diff --git a/bot-wsp/.dockerignore b/bot-wsp/.dockerignore new file mode 100644 index 0000000..3869f84 --- /dev/null +++ b/bot-wsp/.dockerignore @@ -0,0 +1,49 @@ +# Build artifacts +dist/* +node_modules + +# Environment files (excepto plantillas) +.env +.env.local +.env.*.local + +# Logs +*.log +npm-debug.log* +pnpm-debug.log* + +# Runtime data +*_sessions +*tokens +.wwebjs* +tmp/* + +# Git y control de versiones +.git +.gitignore + +# Docker +Dockerfile* +docker-compose* + +# IDE y editores +.vscode +.idea +*.swp +*.swo +*~ + +# Testing +coverage +.cache + +# OS +.DS_Store +Thumbs.db + +# Archivos temporales +*.tmp +*.bak + +# README y docs (opcional, comentar si los necesitas) +README.md \ No newline at end of file diff --git a/bot-wsp/.env.example b/bot-wsp/.env.example new file mode 100644 index 0000000..6232c0f --- /dev/null +++ b/bot-wsp/.env.example @@ -0,0 +1,13 @@ +DATABASE_URL= +SECRET_JWT=mi_clave_secreta +EXPIRATION_TOKEN_MINUTES=30 +URL_FRONT= +URL_ODOO= +<<<<<<< Updated upstream +PHONE_NUMBER=5 +NODE_ENV=d +======= +PHONE_NUMBER= +NODE_ENV=development +>>>>>>> Stashed changes +PROVIDER=baileys \ No newline at end of file diff --git a/bot-wsp/.eslintrc.json b/bot-wsp/.eslintrc.json new file mode 100644 index 0000000..fb33cd2 --- /dev/null +++ b/bot-wsp/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "env": { + "browser": true, + "node": true, + "es2021": true + }, + "ignorePatterns": ["dist/**/*.js"], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "plugin:builderbot/recommended" + ], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@typescript-eslint", "builderbot"], + "rules": { + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": "off", + "no-unsafe-optional-chaining": "off" + } +} diff --git a/bot-wsp/.gitignore b/bot-wsp/.gitignore new file mode 100644 index 0000000..d77b8c3 --- /dev/null +++ b/bot-wsp/.gitignore @@ -0,0 +1,16 @@ +dist/* +node_modules +.vscode/* +.env +tmp/* +!tmp/.gitkeep + +*_sessions +*tokens +.wwebjs* + +*.log +*qr.png +/src/generated/prisma +*.Zone.Identifier + diff --git a/bot-wsp/.npmrc b/bot-wsp/.npmrc new file mode 100644 index 0000000..5159dbd --- /dev/null +++ b/bot-wsp/.npmrc @@ -0,0 +1,4 @@ +enable-pre-post-scripts=true +auto-install-peers=true +shamefully-hoist=false +strict-peer-dependencies=false diff --git a/bot-wsp/Dockerfile b/bot-wsp/Dockerfile new file mode 100644 index 0000000..a11431b --- /dev/null +++ b/bot-wsp/Dockerfile @@ -0,0 +1,139 @@ +# ---------- BUILDER ---------- +<<<<<<< Updated upstream +FROM node:22-alpine AS builder + +WORKDIR /app + +# Instalar dependencias del sistema necesarias para compilación +RUN apk add --no-cache \ + python3 \ + make \ + g++ \ + git \ + openssl \ + curl \ + ffmpeg + +# Instalar pnpm globalmente +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Copiar archivos de configuración de pnpm y dependencias +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc* ./ +COPY patches ./patches + +# Instalar dependencias con pnpm (permite build scripts automáticamente) +RUN pnpm config set enable-pre-post-scripts true \ + && pnpm install --frozen-lockfile + +# Copiar código fuente +COPY . . + +# Generar Prisma client y compilar +RUN pnpm prisma generate && pnpm run build + +# ---------- RUNTIME ---------- +FROM node:22-alpine AS deploy + +WORKDIR /app + +ARG PORT=3001 +ENV PORT=$PORT +ENV NODE_ENV=production + +EXPOSE $PORT + +# Instalar dependencias runtime (ffmpeg incluido para evitar problemas) +RUN apk add --no-cache \ + curl \ + openssl \ + libc6-compat \ + ffmpeg \ + postgresql-client + +# Instalar pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Crear usuario no-root ANTES de copiar archivos +RUN addgroup -g 1001 -S nodejs \ + && adduser -S -u 1001 nodejs \ + && mkdir -p /app/bot_sessions /app/tokens /app/assets /app/tmp \ + && chown nodejs:nodejs /app /app/bot_sessions /app/tokens /app/assets /app/tmp + +# Copiar archivos necesarios del builder con ownership correcto +COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist +COPY --from=builder --chown=nodejs:nodejs /app/prisma ./prisma +COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules +COPY --from=builder --chown=nodejs:nodejs /app/package.json ./package.json +COPY --from=builder --chown=nodejs:nodejs /app/pnpm-lock.yaml ./pnpm-lock.yaml +COPY --from=builder --chown=nodejs:nodejs /app/assets ./assets + +# Copiar entrypoint script +# COPY docker-entrypoint.sh /usr/local/bin/ +# RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +USER nodejs + +# Healthcheck +HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \ + CMD curl -f http://localhost:${PORT}/health || exit 1 + +CMD ["sh", "-c", "pnpm prisma migrate deploy && node dist/main.js"] +======= + FROM node:22-alpine3.20 AS builder + + WORKDIR /app + + RUN apk add --no-cache --virtual .gyp \ + python3 \ + make \ + g++ \ + && apk add --no-cache git openssl + + # Instalar pnpm + RUN npm install -g pnpm + + # Copiar archivos de dependencias (incluyendo lockfile y patches) + COPY package*.json pnpm-lock.yaml ./ + COPY patches/ ./patches/ + + RUN pnpm install --frozen-lockfile + + COPY . . + + RUN pnpm exec prisma generate && pnpm run build + + RUN apk del .gyp + + # ---------- RUNTIME ---------- + FROM node:22-alpine3.20 AS deploy + + WORKDIR /app + + ARG PORT=3001 + ARG PORT_WSP=3008 + ENV PORT=$PORT + ENV PORT_WSP=$PORT_WSP + ENV NODE_ENV=production + + EXPOSE $PORT + EXPOSE $PORT_WSP + + # Herramientas mínimas necesarias + RUN apk add --no-cache curl openssl libc6-compat + + COPY --from=builder /app/dist ./dist + COPY --from=builder /app/prisma ./prisma + COPY --from=builder /app/node_modules ./node_modules + COPY --from=builder /app/package*.json ./ + COPY --from=builder /app/assets ./assets + + RUN addgroup -g 1001 -S nodejs \ + && adduser -S -u 1001 nodejs \ + && mkdir -p /app/bot_sessions \ + && chown -R nodejs:nodejs /app + + USER nodejs + + CMD ["sh", "-c", "npx prisma migrate deploy && node dist/main.js"] +>>>>>>> Stashed changes + \ No newline at end of file diff --git a/bot-wsp/assets/sample.png b/bot-wsp/assets/sample.png new file mode 100755 index 0000000..de27372 Binary files /dev/null and b/bot-wsp/assets/sample.png differ diff --git a/bot-wsp/docker-compose.yml b/bot-wsp/docker-compose.yml new file mode 100644 index 0000000..92fabba --- /dev/null +++ b/bot-wsp/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + postgres: + image: postgres:15 + container_name: postgres_urban + environment: + POSTGRES_DB: urban + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - "5431:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + postgres_data: \ No newline at end of file diff --git a/bot-wsp/dockerignore b/bot-wsp/dockerignore new file mode 100644 index 0000000..2003c19 --- /dev/null +++ b/bot-wsp/dockerignore @@ -0,0 +1,17 @@ +node_modules +dist +tmp +.git +.gitignore +Dockerfile* +docker-compose* +**/*.log +.env* +coverage +pnpm-lock.yamldist/* +node_modules +.env + +*_sessions +*tokens +.wwebjs* \ No newline at end of file diff --git a/bot-wsp/nest-cli.json b/bot-wsp/nest-cli.json new file mode 100644 index 0000000..56167b3 --- /dev/null +++ b/bot-wsp/nest-cli.json @@ -0,0 +1,4 @@ +{ + "collection": "@nestjs/schematics", + "sourceRoot": "src" +} diff --git a/bot-wsp/nodemon.json b/bot-wsp/nodemon.json new file mode 100644 index 0000000..dc42dc3 --- /dev/null +++ b/bot-wsp/nodemon.json @@ -0,0 +1,14 @@ +{ + "watch": ["src"], + "ext": "ts", + "ignore": [ + "**/*.test.ts", + "**/*.spec.ts" + ], + "delay": "1000", + "signal": "SIGTERM", + "restartable": "rs", + "execMap": { + "ts": "tsx" + } + } \ No newline at end of file diff --git a/bot-wsp/package-lock.json b/bot-wsp/package-lock.json new file mode 100644 index 0000000..9d2637c --- /dev/null +++ b/bot-wsp/package-lock.json @@ -0,0 +1,11293 @@ +{ + "name": "bot-wsp", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "bot-wsp", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@builderbot/bot": "1.3.15", + "@builderbot/provider-baileys": "1.3.15", + "@builderbot/provider-sherpa": "1.3.15", + "@nestjs/axios": "^4.0.0", + "@nestjs/common": "^10.3.0", + "@nestjs/core": "^10.3.0", + "@nestjs/jwt": "^11.0.0", + "@nestjs/mapped-types": "*", + "@nestjs/passport": "^11.0.5", + "@nestjs/platform-express": "^10.3.0", + "@nestjs/schedule": "^6.0.0", + "@nestjs/swagger": "7.4.2", + "@nestjs/throttler": "^6.4.0", + "@prisma/client": "^6.10.1", + "aurik3-builderbot-baileys-custom": "^0.0.9", + "baileys": "^7.0.0-rc.9", + "chrono-node": "^2.8.3", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.2", + "dayjs": "^1.11.13", + "dotenv": "^16.4.5", + "multer": "^2.0.2", + "nanoid": "^3.3.6", + "passport": "^0.7.0", + "reflect-metadata": "^0.2.0", + "rxjs": "^7.8.1", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@nestjs/cli": "^10.3.0", + "@types/multer": "^1.4.11", + "@types/node": "^20.19.6", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.4.0", + "eslint": "^8.52.0", + "eslint-plugin-builderbot": "latest", + "nodemon": "^3.1.0", + "prisma": "^6.10.1", + "rollup": "^4.10.0", + "rollup-plugin-typescript2": "^0.36.0", + "tsx": "^4.7.1", + "typescript": "^5.4.3" + }, + "engines": { + "node": ">=22" + } + }, + "node_modules/@adiwajshing/keyed-db": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@adiwajshing/keyed-db/-/keyed-db-0.2.4.tgz", + "integrity": "sha512-yprSnAtj80/VKuDqRcFFLDYltoNV8tChNwFfIgcf6PGD4sjzWIBgs08pRuTqGH5mk5wgL6PBRSsMCZqtZwzFEw==", + "license": "MIT" + }, + "node_modules/@angular-devkit/core": { + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-17.3.11.tgz", + "integrity": "sha512-vTNDYNsLIWpYk2I969LMQFH29GTsLzxNk/0cLw5q56ARF0v5sIWfHYwGTS88jdDqIpuuettcSczbxeA7EuAmqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.1", + "picomatch": "4.0.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "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 + } + } + }, + "node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-17.3.11.tgz", + "integrity": "sha512-I5wviiIqiFwar9Pdk30Lujk8FczEEc18i22A5c6Z9lbmhPQdTroDnEQdsfXjy404wPe8H62s0I15o4pmMGfTYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "17.3.11", + "jsonc-parser": "3.2.1", + "magic-string": "0.30.8", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics-cli": { + "version": "17.3.11", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-17.3.11.tgz", + "integrity": "sha512-kcOMqp+PHAKkqRad7Zd7PbpqJ0LqLaNZdY1+k66lLWmkEBozgq8v4ASn/puPWf9Bo0HpCiK+EzLf0VHE8Z/y6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "17.3.11", + "@angular-devkit/schematics": "17.3.11", + "ansi-colors": "4.1.3", + "inquirer": "9.2.15", + "symbol-observable": "4.0.0", + "yargs-parser": "21.1.1" + }, + "bin": { + "schematics": "bin/schematics.js" + }, + "engines": { + "node": "^18.13.0 || >=20.9.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/chalk": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { + "version": "9.2.15", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.15.tgz", + "integrity": "sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ljharb/through": "^2.3.12", + "ansi-escapes": "^4.3.2", + "chalk": "^5.3.0", + "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.1", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/run-async": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz", + "integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@arr/every": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz", + "integrity": "sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@borewit/text-codec": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.1.tgz", + "integrity": "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@builderbot/bot": { + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/@builderbot/bot/-/bot-1.3.15.tgz", + "integrity": "sha512-g5ofmOTp0ixcQfOBi0wb90ePhGu0lpwZUtryY5/6D/5bYOcHyX6078IYwTm1T2Vn2gTj3c8sIF9r2gGasUSG3g==", + "license": "ISC", + "dependencies": { + "@ffmpeg-installer/ffmpeg": "^1.1.0", + "body-parser": "^1.20.4", + "cors": "^2.8.5", + "fluent-ffmpeg": "^2.1.3", + "follow-redirects": "^1.15.11", + "mime-types": "^2.1.35", + "picocolors": "^1.1.1", + "polka": "^0.5.2" + }, + "optionalDependencies": { + "sharp": "0.33.3" + } + }, + "node_modules/@builderbot/bot/node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "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.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/@builderbot/bot/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/@builderbot/bot/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@builderbot/bot/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/@builderbot/bot/node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@builderbot/bot/node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@builderbot/bot/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@builderbot/provider-baileys": { + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/@builderbot/provider-baileys/-/provider-baileys-1.3.15.tgz", + "integrity": "sha512-CfqqZ69RTmOlJnG1aJ8PYVynUluWzdzLKkS10cnENQaTGSlopDI9huDHBskrrfU7+jqdYfGnxy3I3Ru/4nop7Q==", + "license": "ISC", + "dependencies": { + "@adiwajshing/keyed-db": "^0.2.4", + "@ffmpeg-installer/ffmpeg": "^1.1.0", + "@types/polka": "^0.5.7", + "baileys": "7.0.0-rc.9", + "cheerio": "^1.1.2", + "fluent-ffmpeg": "^2.1.2", + "fs-extra": "^11.3.2", + "jimp": "^1.6.0", + "node-cache": "^5.1.2", + "sharp": "0.33.3" + } + }, + "node_modules/@builderbot/provider-sherpa": { + "version": "1.3.15", + "resolved": "https://registry.npmjs.org/@builderbot/provider-sherpa/-/provider-sherpa-1.3.15.tgz", + "integrity": "sha512-l6RoIFbol9dDIrvt8gIktMEVCc9t2vXW7NPPMlJo164mKX/1Dt3eiV0oqgemRGc3fJX5HyAma/sDtbjvdhXjng==", + "license": "ISC", + "dependencies": { + "@adiwajshing/keyed-db": "^0.2.4", + "@ffmpeg-installer/ffmpeg": "^1.1.0", + "@types/polka": "^0.5.7", + "fluent-ffmpeg": "^2.1.2", + "fs-extra": "^11.3.2", + "jimp": "^1.6.0", + "node-cache": "^5.1.2", + "qrcode-terminal": "^0.12.0", + "rollup": "^4.53.3", + "sharp": "0.33.3", + "tslib": "^2.8.1", + "typescript": "^5.9.3", + "whaileys": "6.3.8" + } + }, + "node_modules/@cacheable/memory": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.7.tgz", + "integrity": "sha512-RbxnxAMf89Tp1dLhXMS7ceft/PGsDl1Ip7T20z5nZ+pwIAsQ1p2izPjVG69oCLv/jfQ7HDPHTWK0c9rcAWXN3A==", + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.3.3", + "@keyv/bigmap": "^1.3.0", + "hookified": "^1.14.0", + "keyv": "^5.5.5" + } + }, + "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", + "license": "MIT", + "dependencies": { + "hashery": "^1.4.0", + "hookified": "^1.15.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/memory/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@cacheable/node-cache": { + "version": "1.7.6", + "resolved": "https://registry.npmjs.org/@cacheable/node-cache/-/node-cache-1.7.6.tgz", + "integrity": "sha512-6Omk2SgNnjtxB5f/E6bTIWIt5xhdpx39fGNRQgU9lojvRxU68v+qY+SXXLsp3ZGukqoPjsK21wZ6XABFr/Ge3A==", + "license": "MIT", + "dependencies": { + "cacheable": "^2.3.1", + "hookified": "^1.14.0", + "keyv": "^5.5.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@cacheable/node-cache/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.4.tgz", + "integrity": "sha512-knwKUJEYgIfwShABS1BX6JyJJTglAFcEU7EXqzTdiGCXur4voqkiJkdgZIQtWNFhynzDWERcTYv/sETMu3uJWA==", + "license": "MIT", + "dependencies": { + "hashery": "^1.3.0", + "keyv": "^5.6.0" + } + }, + "node_modules/@cacheable/utils/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz", + "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz", + "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz", + "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz", + "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz", + "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz", + "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz", + "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz", + "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz", + "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz", + "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz", + "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz", + "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz", + "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz", + "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz", + "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz", + "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz", + "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz", + "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz", + "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz", + "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz", + "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz", + "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz", + "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz", + "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz", + "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@ffmpeg-installer/darwin-arm64": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-arm64/-/darwin-arm64-4.1.5.tgz", + "integrity": "sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "license": "https://git.ffmpeg.org/gitweb/ffmpeg.git/blob_plain/HEAD:/LICENSE.md", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ffmpeg-installer/darwin-x64": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.1.0.tgz", + "integrity": "sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "license": "LGPL-2.1", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@ffmpeg-installer/ffmpeg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/ffmpeg/-/ffmpeg-1.1.0.tgz", + "integrity": "sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==", + "license": "LGPL-2.1", + "optionalDependencies": { + "@ffmpeg-installer/darwin-arm64": "4.1.5", + "@ffmpeg-installer/darwin-x64": "4.1.0", + "@ffmpeg-installer/linux-arm": "4.1.3", + "@ffmpeg-installer/linux-arm64": "4.1.4", + "@ffmpeg-installer/linux-ia32": "4.1.0", + "@ffmpeg-installer/linux-x64": "4.1.0", + "@ffmpeg-installer/win32-ia32": "4.1.0", + "@ffmpeg-installer/win32-x64": "4.1.0" + } + }, + "node_modules/@ffmpeg-installer/linux-arm": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm/-/linux-arm-4.1.3.tgz", + "integrity": "sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==", + "cpu": [ + "arm" + ], + "hasInstallScript": true, + "license": "GPLv3", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/linux-arm64": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-arm64/-/linux-arm64-4.1.4.tgz", + "integrity": "sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==", + "cpu": [ + "arm64" + ], + "hasInstallScript": true, + "license": "GPLv3", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/linux-ia32": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-ia32/-/linux-ia32-4.1.0.tgz", + "integrity": "sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==", + "cpu": [ + "ia32" + ], + "hasInstallScript": true, + "license": "GPLv3", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/linux-x64": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/linux-x64/-/linux-x64-4.1.0.tgz", + "integrity": "sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==", + "cpu": [ + "x64" + ], + "hasInstallScript": true, + "license": "GPLv3", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@ffmpeg-installer/win32-ia32": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-ia32/-/win32-ia32-4.1.0.tgz", + "integrity": "sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==", + "cpu": [ + "ia32" + ], + "license": "GPLv3", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@ffmpeg-installer/win32-x64": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@ffmpeg-installer/win32-x64/-/win32-x64-4.1.0.tgz", + "integrity": "sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==", + "cpu": [ + "x64" + ], + "license": "GPLv3", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@hapi/boom": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.4.tgz", + "integrity": "sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw==", + "license": "BSD-3-Clause", + "dependencies": { + "@hapi/hoek": "9.x.x" + } + }, + "node_modules/@hapi/hoek": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", + "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.3.tgz", + "integrity": "sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.3.tgz", + "integrity": "sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.2.tgz", + "integrity": "sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=11", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.2.tgz", + "integrity": "sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "macos": ">=10.13", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.2.tgz", + "integrity": "sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.2.tgz", + "integrity": "sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.2.tgz", + "integrity": "sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.2.tgz", + "integrity": "sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.2.tgz", + "integrity": "sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.2.tgz", + "integrity": "sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.3.tgz", + "integrity": "sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.3.tgz", + "integrity": "sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.3.tgz", + "integrity": "sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.28", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.2" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.3.tgz", + "integrity": "sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "glibc": ">=2.26", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.3.tgz", + "integrity": "sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.3.tgz", + "integrity": "sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "musl": ">=1.2.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.2" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.3.tgz", + "integrity": "sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.1.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.3.tgz", + "integrity": "sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.3.tgz", + "integrity": "sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0", + "yarn": ">=3.2.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@jimp/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-1.6.0.tgz", + "integrity": "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w==", + "license": "MIT", + "dependencies": { + "@jimp/file-ops": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "await-to-js": "^3.0.0", + "exif-parser": "^0.1.12", + "file-type": "^16.0.0", + "mime": "3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/core/node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "license": "MIT", + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/@jimp/core/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@jimp/core/node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/core/node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@jimp/diff": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/diff/-/diff-1.6.0.tgz", + "integrity": "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw==", + "license": "MIT", + "dependencies": { + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "pixelmatch": "^5.3.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/diff/node_modules/pixelmatch": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.3.0.tgz", + "integrity": "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==", + "license": "ISC", + "dependencies": { + "pngjs": "^6.0.0" + }, + "bin": { + "pixelmatch": "bin/pixelmatch" + } + }, + "node_modules/@jimp/diff/node_modules/pngjs": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", + "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", + "license": "MIT", + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@jimp/file-ops": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/file-ops/-/file-ops-1.6.0.tgz", + "integrity": "sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/js-bmp": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-bmp/-/js-bmp-1.6.0.tgz", + "integrity": "sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "bmp-ts": "^1.0.9" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/js-gif": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-gif/-/js-gif-1.6.0.tgz", + "integrity": "sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "gifwrap": "^0.10.1", + "omggif": "^1.0.10" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/js-gif/node_modules/gifwrap": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/gifwrap/-/gifwrap-0.10.1.tgz", + "integrity": "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==", + "license": "MIT", + "dependencies": { + "image-q": "^4.0.0", + "omggif": "^1.0.10" + } + }, + "node_modules/@jimp/js-jpeg": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-jpeg/-/js-jpeg-1.6.0.tgz", + "integrity": "sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "jpeg-js": "^0.4.4" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/js-png": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-png/-/js-png-1.6.0.tgz", + "integrity": "sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "pngjs": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/js-png/node_modules/pngjs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", + "integrity": "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==", + "license": "MIT", + "engines": { + "node": ">=14.19.0" + } + }, + "node_modules/@jimp/js-tiff": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/js-tiff/-/js-tiff-1.6.0.tgz", + "integrity": "sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "utif2": "^4.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-blit": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-1.6.0.tgz", + "integrity": "sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-blur": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-1.6.0.tgz", + "integrity": "sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/utils": "1.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-circle": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-circle/-/plugin-circle-1.6.0.tgz", + "integrity": "sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-color": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-1.6.0.tgz", + "integrity": "sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "tinycolor2": "^1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-contain": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-1.6.0.tgz", + "integrity": "sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-blit": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-cover": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-1.6.0.tgz", + "integrity": "sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-crop": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-crop": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-1.6.0.tgz", + "integrity": "sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-displace": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-1.6.0.tgz", + "integrity": "sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-dither": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-1.6.0.tgz", + "integrity": "sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-fisheye": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-fisheye/-/plugin-fisheye-1.6.0.tgz", + "integrity": "sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-flip": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-1.6.0.tgz", + "integrity": "sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-hash": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-hash/-/plugin-hash-1.6.0.tgz", + "integrity": "sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/js-bmp": "1.6.0", + "@jimp/js-jpeg": "1.6.0", + "@jimp/js-png": "1.6.0", + "@jimp/js-tiff": "1.6.0", + "@jimp/plugin-color": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "any-base": "^1.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-mask": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-1.6.0.tgz", + "integrity": "sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-print": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-1.6.0.tgz", + "integrity": "sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/js-jpeg": "1.6.0", + "@jimp/js-png": "1.6.0", + "@jimp/plugin-blit": "1.6.0", + "@jimp/types": "1.6.0", + "parse-bmfont-ascii": "^1.0.6", + "parse-bmfont-binary": "^1.0.6", + "parse-bmfont-xml": "^1.1.6", + "simple-xml-to-json": "^1.2.2", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-quantize": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-quantize/-/plugin-quantize-1.6.0.tgz", + "integrity": "sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg==", + "license": "MIT", + "dependencies": { + "image-q": "^4.0.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-resize": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-1.6.0.tgz", + "integrity": "sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/types": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-rotate": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-1.6.0.tgz", + "integrity": "sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-crop": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/plugin-threshold": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-threshold/-/plugin-threshold-1.6.0.tgz", + "integrity": "sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/plugin-color": "1.6.0", + "@jimp/plugin-hash": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0", + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/types": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-1.6.0.tgz", + "integrity": "sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg==", + "license": "MIT", + "dependencies": { + "zod": "^3.23.8" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jimp/utils": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA==", + "license": "MIT", + "dependencies": { + "@jimp/types": "1.6.0", + "tinycolor2": "^1.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsdoc/salty": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.10.tgz", + "integrity": "sha512-VFHSsQAQp8y1NJvAJBpLs9I2shHE6hz9TwukocDObuUgGVAq62yZGbTgJg04Z3Fj0XSMWe0sJqGg5dhKGTV92A==", + "license": "Apache-2.0", + "dependencies": { + "lodash": "^4.17.23" + }, + "engines": { + "node": ">=v12.0.0" + } + }, + "node_modules/@jsdoc/salty/node_modules/lodash": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", + "license": "MIT" + }, + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "license": "MIT" + }, + "node_modules/@ljharb/through": { + "version": "2.3.14", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.14.tgz", + "integrity": "sha512-ajBvlKpWucBB17FuQYUShqpqy8GRgYEpJW0vWJbUu1CV9lWyrDCapy0lScU8T8Z6qn49sSwJB3+M+evYIdGg+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", + "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", + "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "license": "MIT" + }, + "node_modules/@nestjs/axios": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/axios/-/axios-4.0.0.tgz", + "integrity": "sha512-1cB+Jyltu/uUPNQrpUimRHEQHrnQrpLzVj6dU3dgn6iDDDdahr10TgHFGTmw5VuJ9GzKZsCLDL78VSwJAs/9JQ==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "axios": "^1.3.1", + "rxjs": "^7.0.0" + } + }, + "node_modules/@nestjs/cli": { + "version": "10.4.9", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.9.tgz", + "integrity": "sha512-s8qYd97bggqeK7Op3iD49X2MpFtW4LVNLAwXFkfbRxKME6IYT7X0muNTJ2+QfI8hpbNx9isWkrLWIp+g5FOhiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "17.3.11", + "@angular-devkit/schematics": "17.3.11", + "@angular-devkit/schematics-cli": "17.3.11", + "@nestjs/schematics": "^10.0.1", + "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", + "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" + }, + "bin": { + "nest": "bin/nest.js" + }, + "engines": { + "node": ">= 16.14" + }, + "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 + } + } + }, + "node_modules/@nestjs/cli/node_modules/typescript": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@nestjs/common": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.4.19.tgz", + "integrity": "sha512-0TZJ8H+7qtaqZt6YfZJkDRp0e+v6jjo5/pevPAjUy0WYxaTy16bNNQxFPRKLMe/v1hUr2oGV9imvL2477zNt5g==", + "license": "MIT", + "dependencies": { + "file-type": "20.4.1", + "iterare": "1.2.1", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "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 + } + } + }, + "node_modules/@nestjs/core": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.4.19.tgz", + "integrity": "sha512-gahghu0y4Rn4gn/xPjTgNHFMpUM8TxfhdeMowVWTGVnYMZtGeEGbIXMFhJS0Dce3E4VKyqAglzgO9ecAZd4Ong==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@nuxtjs/opencollective": "0.3.2", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "path-to-regexp": "3.3.0", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "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 + } + } + }, + "node_modules/@nestjs/jwt": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.0.tgz", + "integrity": "sha512-v7YRsW3Xi8HNTsO+jeHSEEqelX37TVWgwt+BcxtkG/OfXJEOs6GZdbdza200d6KqId1pJQZ6UPj1F0M6E+mxaA==", + "license": "MIT", + "dependencies": { + "@types/jsonwebtoken": "9.0.7", + "jsonwebtoken": "9.0.2" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" + } + }, + "node_modules/@nestjs/mapped-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", + "integrity": "sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==", + "license": "MIT", + "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 + } + } + }, + "node_modules/@nestjs/passport": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz", + "integrity": "sha512-ulQX6mbjlws92PIM15Naes4F4p2JoxGnIJuUsdXQPT+Oo2sqQmENEZXM7eYuimocfHnKlcfZOuyzbA33LwUlOQ==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "passport": "^0.5.0 || ^0.6.0 || ^0.7.0" + } + }, + "node_modules/@nestjs/platform-express": { + "version": "10.4.19", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.19.tgz", + "integrity": "sha512-IeQkBZUtPeJoO4E0QqSLwkB+60KcThw8/s4gGvAwIRJ5ViuXoxnwU59eBDy84PUuVbNe4VdKjfAF9fuQOEh11Q==", + "license": "MIT", + "dependencies": { + "body-parser": "1.20.3", + "cors": "2.8.5", + "express": "4.21.2", + "multer": "2.0.1", + "tslib": "2.8.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^10.0.0", + "@nestjs/core": "^10.0.0" + } + }, + "node_modules/@nestjs/platform-express/node_modules/multer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.1.tgz", + "integrity": "sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "mkdirp": "^0.5.6", + "object-assign": "^4.1.1", + "type-is": "^1.6.18", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/@nestjs/schedule": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/schedule/-/schedule-6.0.0.tgz", + "integrity": "sha512-aQySMw6tw2nhitELXd3EiRacQRgzUKD9mFcUZVOJ7jPLqIBvXOyvRWLsK9SdurGA+jjziAlMef7iB5ZEFFoQpw==", + "license": "MIT", + "dependencies": { + "cron": "4.3.0" + }, + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "@nestjs/core": "^10.0.0 || ^11.0.0" + } + }, + "node_modules/@nestjs/schematics": { + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.2.3.tgz", + "integrity": "sha512-4e8gxaCk7DhBxVUly2PjYL4xC2ifDFexCqq1/u4TtivLGXotVk0wHdYuPYe1tHTHuR1lsOkRbfOCpkdTnigLVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "17.3.11", + "@angular-devkit/schematics": "17.3.11", + "comment-json": "4.2.5", + "jsonc-parser": "3.3.1", + "pluralize": "8.0.0" + }, + "peerDependencies": { + "typescript": ">=4.8.2" + } + }, + "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nestjs/swagger": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@nestjs/swagger/-/swagger-7.4.2.tgz", + "integrity": "sha512-Mu6TEn1M/owIvAx2B4DUQObQXqo2028R2s9rSZ/hJEgBK95+doTwS0DjmVA2wTeZTyVtXOoN7CsoM5pONBzvKQ==", + "license": "MIT", + "dependencies": { + "@microsoft/tsdoc": "^0.15.0", + "@nestjs/mapped-types": "2.0.5", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "path-to-regexp": "3.3.0", + "swagger-ui-dist": "5.17.14" + }, + "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 + } + } + }, + "node_modules/@nestjs/swagger/node_modules/@nestjs/mapped-types": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz", + "integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==", + "license": "MIT", + "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 + } + } + }, + "node_modules/@nestjs/throttler": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/@nestjs/throttler/-/throttler-6.4.0.tgz", + "integrity": "sha512-osL67i0PUuwU5nqSuJjtUJZMkxAnYB4VldgYUMGzvYRJDCqGRFMWbsbzm/CkUtPLRL30I8T74Xgt/OQxnYokiA==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", + "@nestjs/core": "^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0", + "reflect-metadata": "^0.1.13 || ^0.2.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nuxtjs/opencollective": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", + "integrity": "sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "consola": "^2.15.0", + "node-fetch": "^2.6.1" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@polka/url": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-0.5.0.tgz", + "integrity": "sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==", + "license": "MIT" + }, + "node_modules/@prisma/client": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-6.10.1.tgz", + "integrity": "sha512-Re4pMlcUsQsUTAYMK7EJ4Bw2kg3WfZAAlr8GjORJaK4VOP6LxRQUQ1TuLnxcF42XqGkWQ36q5CQF1yVadANQ6w==", + "hasInstallScript": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "peerDependencies": { + "prisma": "*", + "typescript": ">=5.1.0" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/@prisma/config": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@prisma/config/-/config-6.10.1.tgz", + "integrity": "sha512-kz4/bnqrOrzWo8KzYguN0cden4CzLJJ+2VSpKtF8utHS3l1JS0Lhv6BLwpOX6X9yNreTbZQZwewb+/BMPDCIYQ==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "jiti": "2.4.2" + } + }, + "node_modules/@prisma/debug": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.10.1.tgz", + "integrity": "sha512-k2YT53cWxv9OLjW4zSYTZ6Z7j0gPfCzcr2Mj99qsuvlxr8WAKSZ2NcSR0zLf/mP4oxnYG842IMj3utTgcd7CaA==", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.10.1.tgz", + "integrity": "sha512-Q07P5rS2iPwk2IQr/rUQJ42tHjpPyFcbiH7PXZlV81Ryr9NYIgdxcUrwgVOWVm5T7ap02C0dNd1dpnNcSWig8A==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.10.1", + "@prisma/engines-version": "6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c", + "@prisma/fetch-engine": "6.10.1", + "@prisma/get-platform": "6.10.1" + } + }, + "node_modules/@prisma/engines-version": { + "version": "6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c.tgz", + "integrity": "sha512-ZJFTsEqapiTYVzXya6TUKYDFnSWCNegfUiG5ik9fleQva5Sk3DNyyUi7X1+0ZxWFHwHDr6BZV5Vm+iwP+LlciA==", + "devOptional": true, + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.10.1.tgz", + "integrity": "sha512-clmbG/Jgmrc/n6Y77QcBmAUlq9LrwI9Dbgy4pq5jeEARBpRCWJDJ7PWW1P8p0LfFU0i5fsyO7FqRzRB8mkdS4g==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.10.1", + "@prisma/engines-version": "6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c", + "@prisma/get-platform": "6.10.1" + } + }, + "node_modules/@prisma/get-platform": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.10.1.tgz", + "integrity": "sha512-4CY5ndKylcsce9Mv+VWp5obbR2/86SHOLVV053pwIkhVtT9C9A83yqiqI/5kJM9T1v1u1qco/bYjDKycmei9HA==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "6.10.1" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz", + "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==", + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", + "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", + "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT" + }, + "node_modules/@types/long": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", + "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", + "license": "MIT" + }, + "node_modules/@types/luxon": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.6.2.tgz", + "integrity": "sha512-R/BdP7OxEMc44l2Ex5lSXHoIXTB2JLNa3y2QISIbr58U/YcsffyQrYW//hZSdrfxrjRZj3GcUoxMPGdO8gSYuw==", + "license": "MIT" + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "license": "MIT" + }, + "node_modules/@types/multer": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/@types/multer/-/multer-1.4.13.tgz", + "integrity": "sha512-bhhdtPw7JqCiEfC9Jimx5LqX9BDIPJEh2q/fQ4bqbBPtyEZYr3cvF22NwG0DmPZNYA0CAf2CnqDB4KIGGpJcaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/node": { + "version": "20.19.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.6.tgz", + "integrity": "sha512-uYssdp9z5zH5GQ0L4zEJ2ZuavYsJwkozjiUzCRfGtaaQcyjAMJ34aP8idv61QlqTozu6kudyr6JMq9Chf09dfA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/polka": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@types/polka/-/polka-0.5.7.tgz", + "integrity": "sha512-TH8CDXM8zoskPCNmWabtK7ziGv9Q21s4hMZLVYK5HFEfqmGXBqq/Wgi7jNELWXftZK/1J/9CezYa06x1RKeQ+g==", + "license": "MIT", + "dependencies": { + "@types/express": "*", + "@types/express-serve-static-core": "*", + "@types/node": "*", + "@types/trouter": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/trouter": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/trouter/-/trouter-3.1.4.tgz", + "integrity": "sha512-4YIL/2AvvZqKBWenjvEpxpblT2KGO6793ipr5QS7/6DpQ3O3SwZGgNGWezxf3pzeYZc24a2pJIrR/+Jxh/wYNQ==", + "license": "MIT" + }, + "node_modules/@types/validator": { + "version": "13.15.2", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.2.tgz", + "integrity": "sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", + "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", + "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", + "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", + "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", + "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", + "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", + "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", + "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==" + }, + "node_modules/async-mutex": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", + "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT", + "peer": true + }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/aurik3-builderbot-baileys-custom": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/aurik3-builderbot-baileys-custom/-/aurik3-builderbot-baileys-custom-0.0.9.tgz", + "integrity": "sha512-oR9rUFRqCopW/DtjK0ZXfbyQQOTfqwe8X7Xn18Q2oiohspAMLMVrxpvpNTUW7yQilRdCPBpriBeIJXzwZl8cdg==", + "license": "ISC", + "dependencies": { + "@adiwajshing/keyed-db": "^0.2.4", + "@ffmpeg-installer/ffmpeg": "^1.1.0", + "@types/polka": "^0.5.7", + "aurik3-whaileys": "6.3.8", + "baileys": "7.0.0-rc.6", + "cheerio": "^1.1.2", + "fluent-ffmpeg": "^2.1.2", + "fs-extra": "^11.2.0", + "jimp": "^1.6.0", + "node-cache": "^5.1.2", + "sharp": "0.33.3" + } + }, + "node_modules/aurik3-builderbot-baileys-custom/node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/aurik3-builderbot-baileys-custom/node_modules/baileys": { + "version": "7.0.0-rc.6", + "resolved": "https://registry.npmjs.org/baileys/-/baileys-7.0.0-rc.6.tgz", + "integrity": "sha512-Unt58dy39rFQ3dRgTUxT38/AXWInNLYx9zijU7PpHDeoNdJfvgyROnHLtmh9hAglLKA1t374v1JLnfI5Tk/TSQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@cacheable/node-cache": "^1.4.0", + "@hapi/boom": "^9.1.3", + "async-mutex": "^0.5.0", + "libsignal": "git+https://github.com/whiskeysockets/libsignal-node.git", + "lru-cache": "^11.1.0", + "music-metadata": "^11.7.0", + "p-queue": "^9.0.0", + "pino": "^9.6", + "protobufjs": "^7.2.4", + "ws": "^8.13.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "audio-decode": "^2.1.3", + "jimp": "^1.6.0", + "link-preview-js": "^3.0.0", + "sharp": "*" + }, + "peerDependenciesMeta": { + "audio-decode": { + "optional": true + }, + "jimp": { + "optional": true + }, + "link-preview-js": { + "optional": true + } + } + }, + "node_modules/aurik3-builderbot-baileys-custom/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/aurik3-builderbot-baileys-custom/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/aurik3-builderbot-baileys-custom/node_modules/music-metadata": { + "version": "11.12.1", + "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-11.12.1.tgz", + "integrity": "sha512-j++ltLxHDb5VCXET9FzQ8bnueiLHwQKgCO7vcbkRH/3F7fRjPkv6qncGEJ47yFhmemcYtgvsOAlcQ1dRBTkDjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "file-type": "^21.3.0", + "media-typer": "^1.1.0", + "strtok3": "^10.3.4", + "token-types": "^6.1.2", + "uint8array-extras": "^1.5.0", + "win-guid": "^0.2.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/aurik3-builderbot-baileys-custom/node_modules/music-metadata/node_modules/file-type": { + "version": "21.3.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.0.tgz", + "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/aurik3-whaileys": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/aurik3-whaileys/-/aurik3-whaileys-6.3.8.tgz", + "integrity": "sha512-HO8zEJ9AwAcN5qcnp0i3CNtmCDUEonh+w9oLGgZE0EdlYhpENP3r+o74yWi0JWwEXAxmQW2mZIDOvhM/D63Qxw==", + "license": "MIT", + "dependencies": { + "@hapi/boom": "^9.1.3", + "axios": "^0.24.0", + "futoin-hkdf": "^1.5.0", + "libsignal": "github:canove/libsignal-node#105ad38dc8d7668b5d5e3688e710915bef5cdc7f", + "lodash": "^4.17.21", + "music-metadata": "^7.12.3", + "node-cache": "^5.1.2", + "pino": "^7.0.0", + "protobufjs": "^7.2.4", + "protobufjs-cli": "^1.1.3", + "ws": "^8.0.0" + }, + "peerDependencies": { + "@adiwajshing/keyed-db": "^0.2.4", + "jimp": "^0.16.1", + "link-preview-js": "^2.1.13", + "qrcode-terminal": "^0.12.0", + "sharp": "^0.30.5" + }, + "peerDependenciesMeta": { + "@adiwajshing/keyed-db": { + "optional": true + }, + "jimp": { + "optional": true + }, + "link-preview-js": { + "optional": true + }, + "qrcode-terminal": { + "optional": true + }, + "sharp": { + "optional": true + } + } + }, + "node_modules/aurik3-whaileys/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "license": "MIT" + }, + "node_modules/aurik3-whaileys/node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, + "node_modules/aurik3-whaileys/node_modules/libsignal": { + "version": "2.0.1", + "resolved": "git+ssh://git@github.com/canove/libsignal-node.git#105ad38dc8d7668b5d5e3688e710915bef5cdc7f", + "integrity": "sha512-9DDCxMERQlIblJURTM3hq7+RS/yJ5R0BS45f/S3g+dkod0xtDlYCGwADumqDk9cRC5n+j7nk/g4q6Vm9VILqDQ==", + "license": "GPL-3.0", + "dependencies": { + "curve25519-js": "^0.0.4", + "protobufjs": "6.8.8" + } + }, + "node_modules/aurik3-whaileys/node_modules/libsignal/node_modules/protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "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/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/aurik3-whaileys/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/aurik3-whaileys/node_modules/pino": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-7.11.0.tgz", + "integrity": "sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.0.0", + "on-exit-leak-free": "^0.2.0", + "pino-abstract-transport": "v0.5.0", + "pino-std-serializers": "^4.0.0", + "process-warning": "^1.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.1.0", + "safe-stable-stringify": "^2.1.0", + "sonic-boom": "^2.2.1", + "thread-stream": "^0.15.1" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/aurik3-whaileys/node_modules/pino-abstract-transport": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz", + "integrity": "sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==", + "license": "MIT", + "dependencies": { + "duplexify": "^4.1.2", + "split2": "^4.0.0" + } + }, + "node_modules/aurik3-whaileys/node_modules/pino-std-serializers": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz", + "integrity": "sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==", + "license": "MIT" + }, + "node_modules/aurik3-whaileys/node_modules/process-warning": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz", + "integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==", + "license": "MIT" + }, + "node_modules/aurik3-whaileys/node_modules/thread-stream": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-0.15.2.tgz", + "integrity": "sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==", + "license": "MIT", + "dependencies": { + "real-require": "^0.1.0" + } + }, + "node_modules/await-to-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/await-to-js/-/await-to-js-3.0.0.tgz", + "integrity": "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "license": "MIT", + "peer": true, + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/baileys": { + "version": "7.0.0-rc.9", + "resolved": "https://registry.npmjs.org/baileys/-/baileys-7.0.0-rc.9.tgz", + "integrity": "sha512-Txd2dZ9MHbojvsHckeuCnAKPO/bQjKxua/0tQSJwOKXffK5vpS82k4eA/Nb46K0cK0Bx+fyY0zhnQHYMBriQcw==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@cacheable/node-cache": "^1.4.0", + "@hapi/boom": "^9.1.3", + "async-mutex": "^0.5.0", + "libsignal": "git+https://github.com/whiskeysockets/libsignal-node.git", + "lru-cache": "^11.1.0", + "music-metadata": "^11.7.0", + "p-queue": "^9.0.0", + "pino": "^9.6", + "protobufjs": "^7.2.4", + "ws": "^8.13.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "audio-decode": "^2.1.3", + "jimp": "^1.6.0", + "link-preview-js": "^3.0.0", + "sharp": "*" + }, + "peerDependenciesMeta": { + "audio-decode": { + "optional": true + }, + "jimp": { + "optional": true + }, + "link-preview-js": { + "optional": true + } + } + }, + "node_modules/baileys/node_modules/@tokenizer/inflate": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz", + "integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "token-types": "^6.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/baileys/node_modules/file-type": { + "version": "21.3.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.0.tgz", + "integrity": "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.4", + "token-types": "^6.1.1", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/baileys/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/baileys/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/baileys/node_modules/music-metadata": { + "version": "11.12.1", + "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-11.12.1.tgz", + "integrity": "sha512-j++ltLxHDb5VCXET9FzQ8bnueiLHwQKgCO7vcbkRH/3F7fRjPkv6qncGEJ47yFhmemcYtgvsOAlcQ1dRBTkDjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "file-type": "^21.3.0", + "media-typer": "^1.1.0", + "strtok3": "^10.3.4", + "token-types": "^6.1.2", + "uint8array-extras": "^1.5.0", + "win-guid": "^0.2.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, + "node_modules/bmp-ts": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bmp-ts/-/bmp-ts-1.0.9.tgz", + "integrity": "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.2.tgz", + "integrity": "sha512-w+ZuRNmex9c1TR9RcsxbfTKCjSL0rh1WA5SABbrWprIHeNBdmyQLSYonlDy9gpD+63XT8DgZ/wNh1Smvc9WnJA==", + "license": "MIT", + "dependencies": { + "@cacheable/memory": "^2.0.7", + "@cacheable/utils": "^2.3.3", + "hookified": "^1.15.0", + "keyv": "^5.5.5", + "qified": "^0.6.0" + } + }, + "node_modules/cacheable/node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001726", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001726.tgz", + "integrity": "sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chrono-node": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-2.8.3.tgz", + "integrity": "sha512-YukiXak31pshonVWaeJ9cZ4xxWIlbsyn5qYUkG5pQ+usZ6l22ASXDIk0kHUQkIBNOCLRevFkHJjnGKXwZNtyZw==", + "license": "MIT", + "dependencies": { + "dayjs": "^1.10.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/class-transformer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==", + "license": "MIT" + }, + "node_modules/class-validator": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.2.tgz", + "integrity": "sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==", + "license": "MIT", + "dependencies": { + "@types/validator": "^13.11.8", + "libphonenumber-js": "^1.11.1", + "validator": "^13.9.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "peer": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/comment-json": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.5.tgz", + "integrity": "sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/consola": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", + "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cron": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-4.3.0.tgz", + "integrity": "sha512-ciiYNLfSlF9MrDqnbMdRWFiA6oizSF7kA1osPP9lRzNu0Uu+AWog1UKy7SkckiDY2irrNjeO6qLyKnXC8oxmrw==", + "license": "MIT", + "dependencies": { + "@types/luxon": "~3.6.0", + "luxon": "~3.6.0" + }, + "engines": { + "node": ">=18.x" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/curve25519-js": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/curve25519-js/-/curve25519-js-0.0.4.tgz", + "integrity": "sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w==", + "license": "MIT" + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexify": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", + "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.2" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.177", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.177.tgz", + "integrity": "sha512-7EH2G59nLsEMj97fpDuvVcYi6lwTcM1xuWw3PssD8xzboAW7zj7iB3COEEEATUfjLHrs5uKBLQT03V/8URx06g==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz", + "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.5", + "@esbuild/android-arm": "0.25.5", + "@esbuild/android-arm64": "0.25.5", + "@esbuild/android-x64": "0.25.5", + "@esbuild/darwin-arm64": "0.25.5", + "@esbuild/darwin-x64": "0.25.5", + "@esbuild/freebsd-arm64": "0.25.5", + "@esbuild/freebsd-x64": "0.25.5", + "@esbuild/linux-arm": "0.25.5", + "@esbuild/linux-arm64": "0.25.5", + "@esbuild/linux-ia32": "0.25.5", + "@esbuild/linux-loong64": "0.25.5", + "@esbuild/linux-mips64el": "0.25.5", + "@esbuild/linux-ppc64": "0.25.5", + "@esbuild/linux-riscv64": "0.25.5", + "@esbuild/linux-s390x": "0.25.5", + "@esbuild/linux-x64": "0.25.5", + "@esbuild/netbsd-arm64": "0.25.5", + "@esbuild/netbsd-x64": "0.25.5", + "@esbuild/openbsd-arm64": "0.25.5", + "@esbuild/openbsd-x64": "0.25.5", + "@esbuild/sunos-x64": "0.25.5", + "@esbuild/win32-arm64": "0.25.5", + "@esbuild/win32-ia32": "0.25.5", + "@esbuild/win32-x64": "0.25.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.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.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-builderbot": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/eslint-plugin-builderbot/-/eslint-plugin-builderbot-1.2.9.tgz", + "integrity": "sha512-c6j2zFUxd6mg1Tz6vrUPCcrxZZU+1IZYPc64bTjY5XUYzgLZNVruJmUyKiLCEeUnhDiTnc6vyHY+CVgAe4mh0A==", + "dev": true, + "license": "ISC" + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==" + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "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" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/express/node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" + }, + "node_modules/fast-redact": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", + "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-type": { + "version": "20.4.1", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.4.1.tgz", + "integrity": "sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.2.6", + "strtok3": "^10.2.0", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/fluent-ffmpeg": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fluent-ffmpeg/-/fluent-ffmpeg-2.1.3.tgz", + "integrity": "sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "dependencies": { + "async": "^0.2.9", + "which": "^1.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/fluent-ffmpeg/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", + "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=12.13.0", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.3.tgz", + "integrity": "sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==", + "license": "MIT", + "peer": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", + "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.6.tgz", + "integrity": "sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/futoin-hkdf": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.5.3.tgz", + "integrity": "sha512-SewY5KdMpaoCeh7jachEWFsh1nNlaDjNHZXWqL5IGwtpEYHTgkr2+AMCgNwKWkcc0wpSYrZfR7he4WdmHFtDxQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", + "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-own-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "peer": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hashery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.0.tgz", + "integrity": "sha512-nhQ6ExaOIqti2FDWoEMWARUqIKyjr2VcZzXShrI+A3zpeiuPWzx6iPftt44LhP74E5sW36B75N6VHbvRtpvO6Q==", + "license": "MIT", + "dependencies": { + "hookified": "^1.14.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", + "dev": true, + "license": "ISC" + }, + "node_modules/image-q": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/image-q/-/image-q-4.0.0.tgz", + "integrity": "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==", + "license": "MIT", + "dependencies": { + "@types/node": "16.9.1" + } + }, + "node_modules/image-q/node_modules/@types/node": { + "version": "16.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.1.tgz", + "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==", + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/iterare": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", + "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "license": "ISC", + "engines": { + "node": ">=6" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jimp": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-1.6.0.tgz", + "integrity": "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg==", + "license": "MIT", + "dependencies": { + "@jimp/core": "1.6.0", + "@jimp/diff": "1.6.0", + "@jimp/js-bmp": "1.6.0", + "@jimp/js-gif": "1.6.0", + "@jimp/js-jpeg": "1.6.0", + "@jimp/js-png": "1.6.0", + "@jimp/js-tiff": "1.6.0", + "@jimp/plugin-blit": "1.6.0", + "@jimp/plugin-blur": "1.6.0", + "@jimp/plugin-circle": "1.6.0", + "@jimp/plugin-color": "1.6.0", + "@jimp/plugin-contain": "1.6.0", + "@jimp/plugin-cover": "1.6.0", + "@jimp/plugin-crop": "1.6.0", + "@jimp/plugin-displace": "1.6.0", + "@jimp/plugin-dither": "1.6.0", + "@jimp/plugin-fisheye": "1.6.0", + "@jimp/plugin-flip": "1.6.0", + "@jimp/plugin-hash": "1.6.0", + "@jimp/plugin-mask": "1.6.0", + "@jimp/plugin-print": "1.6.0", + "@jimp/plugin-quantize": "1.6.0", + "@jimp/plugin-resize": "1.6.0", + "@jimp/plugin-rotate": "1.6.0", + "@jimp/plugin-threshold": "1.6.0", + "@jimp/types": "1.6.0", + "@jimp/utils": "1.6.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "devOptional": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jpeg-js": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz", + "integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==", + "license": "BSD-3-Clause" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "license": "Apache-2.0", + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsdoc": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.5.tgz", + "integrity": "sha512-P4C6MWP9yIlMiK8nwoZvxN84vb6MsnXcHuy7XzVOvQoCizWX5JFCBsWIIWKXBltpoRZXddUOVQmCTOZt9yDj9g==", + "license": "Apache-2.0", + "dependencies": { + "@babel/parser": "^7.20.15", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^14.1.1", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^14.1.0", + "markdown-it-anchor": "^8.6.7", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdoc/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jsdoc/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", + "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz", + "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jwa": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz", + "integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libphonenumber-js": { + "version": "1.12.9", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.9.tgz", + "integrity": "sha512-VWwAdNeJgN7jFOD+wN4qx83DTPMVPPAUyx9/TUkBXKLiNkuWWk6anV0439tgdtwaJDrEdqkvdN22iA6J4bUCZg==", + "license": "MIT" + }, + "node_modules/libsignal": { + "name": "@whiskeysockets/libsignal-node", + "version": "2.0.1", + "resolved": "git+ssh://git@github.com/whiskeysockets/libsignal-node.git#1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67", + "license": "GPL-3.0", + "dependencies": { + "curve25519-js": "^0.0.4", + "protobufjs": "6.8.8" + } + }, + "node_modules/libsignal/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "license": "MIT" + }, + "node_modules/libsignal/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/libsignal/node_modules/protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "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/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/luxon": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.6.1.tgz", + "integrity": "sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/magic-string": { + "version": "0.30.8", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", + "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", + "integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "license": "Unlicense", + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/matchit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/matchit/-/matchit-1.1.0.tgz", + "integrity": "sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==", + "license": "MIT", + "dependencies": { + "@arr/every": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", + "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "mkdirp": "^0.5.6", + "object-assign": "^4.1.1", + "type-is": "^1.6.18", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/music-metadata": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-7.14.0.tgz", + "integrity": "sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "content-type": "^1.0.5", + "debug": "^4.3.4", + "file-type": "^16.5.4", + "media-typer": "^1.1.0", + "strtok3": "^6.3.0", + "token-types": "^4.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/music-metadata/node_modules/file-type": { + "version": "16.5.4", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz", + "integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==", + "license": "MIT", + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/music-metadata/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/music-metadata/node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/music-metadata/node_modules/token-types": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz", + "integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true, + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-cache": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-5.1.2.tgz", + "integrity": "sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==", + "license": "MIT", + "dependencies": { + "clone": "2.x" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemon": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz", + "integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "debug": "^4", + "ignore-by-default": "^1.0.1", + "minimatch": "^3.1.2", + "pstree.remy": "^1.1.8", + "semver": "^7.5.3", + "simple-update-notifier": "^2.0.0", + "supports-color": "^5.5.0", + "touch": "^3.1.0", + "undefsafe": "^2.0.5" + }, + "bin": { + "nodemon": "bin/nodemon.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nodemon" + } + }, + "node_modules/nodemon/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/nodemon/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", + "license": "MIT" + }, + "node_modules/on-exit-leak-free": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz", + "integrity": "sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==", + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.1.0.tgz", + "integrity": "sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^7.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz", + "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==", + "license": "MIT" + }, + "node_modules/parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==", + "license": "MIT" + }, + "node_modules/parse-bmfont-xml": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.6.tgz", + "integrity": "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==", + "license": "MIT", + "dependencies": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.5.0" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/passport": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.7.0.tgz", + "integrity": "sha512-cPLl+qZpSc+ireUvt+IzqbED1cHHkDoVYMo30jbJIdOOjQ1MQYZBPiNvmi8UM6lJuOpTPXJGZQk0DtC4y61MYQ==", + "license": "MIT", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1", + "utils-merge": "^1.0.1" + }, + "engines": { + "node": ">= 0.4.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jaredhanson" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" + }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.1.tgz", + "integrity": "sha512-xUXwsxNjwTQ8K3GnT4pCJm+xq3RUPQbmkYJTP5aFIfNIvbcc/4MUxgBaaRSZJ6yGJZiGSyYlM6MzwTsRk8SYCg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pino": { + "version": "9.14.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", + "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", + "license": "MIT", + "dependencies": { + "@pinojs/redact": "^0.4.0", + "atomic-sleep": "^1.0.0", + "on-exit-leak-free": "^2.1.0", + "pino-abstract-transport": "^2.0.0", + "pino-std-serializers": "^7.0.0", + "process-warning": "^5.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.2.0", + "safe-stable-stringify": "^2.3.1", + "sonic-boom": "^4.0.1", + "thread-stream": "^3.0.0" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", + "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", + "license": "MIT", + "dependencies": { + "split2": "^4.0.0" + } + }, + "node_modules/pino-std-serializers": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", + "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", + "license": "MIT" + }, + "node_modules/pino/node_modules/on-exit-leak-free": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/pino/node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/pino/node_modules/sonic-boom": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", + "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/polka": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/polka/-/polka-0.5.2.tgz", + "integrity": "sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==", + "license": "MIT", + "dependencies": { + "@polka/url": "^0.5.0", + "trouter": "^2.0.1" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prisma": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-6.10.1.tgz", + "integrity": "sha512-khhlC/G49E4+uyA3T3H5PRBut486HD2bDqE2+rvkU0pwk9IAqGFacLFUyIx9Uw+W2eCtf6XGwsp+/strUwMNPw==", + "devOptional": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/config": "6.10.1", + "@prisma/engines": "6.10.1" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=18.18" + }, + "peerDependencies": { + "typescript": ">=5.1.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-warning": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", + "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "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": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/protobufjs-cli": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/protobufjs-cli/-/protobufjs-cli-1.2.0.tgz", + "integrity": "sha512-+YvqJEmsmZHGzE5j0tvEzFeHm0sX7pzRFpyj7+GazhkS4Y0r+jgbioVvFxxSWIlPzUel/lxeOnLChBmV8NmyHA==", + "license": "BSD-3-Clause", + "dependencies": { + "chalk": "^4.0.0", + "escodegen": "^1.13.0", + "espree": "^9.0.0", + "estraverse": "^5.1.0", + "glob": "^8.0.0", + "jsdoc": "^4.0.0", + "minimist": "^1.2.0", + "semver": "^7.1.2", + "tmp": "^0.2.1", + "uglify-js": "^3.7.7" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "protobufjs": "^7.0.0" + } + }, + "node_modules/protobufjs-cli/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/protobufjs-cli/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/protobufjs-cli/node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT", + "peer": true + }, + "node_modules/pstree.remy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", + "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qified": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.6.0.tgz", + "integrity": "sha512-tsSGN1x3h569ZSU1u6diwhltLyfUWDp3YbFHedapTmpBl0B3P6U3+Qptg7xu+v+1io1EwhdPyyRHYbEw0KN2FA==", + "license": "MIT", + "dependencies": { + "hookified": "^1.14.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/qrcode-terminal": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz", + "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==", + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/real-require": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.1.0.tgz", + "integrity": "sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/rollup": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-typescript2": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.36.0.tgz", + "integrity": "sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^4.1.2", + "find-cache-dir": "^3.3.2", + "fs-extra": "^10.0.0", + "semver": "^7.5.4", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "rollup": ">=1.26.3", + "typescript": ">=2.4.0" + } + }, + "node_modules/rollup-plugin-typescript2/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/schema-utils/node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/schema-utils/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.3.tgz", + "integrity": "sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.0" + }, + "engines": { + "libvips": ">=8.15.2", + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.3", + "@img/sharp-darwin-x64": "0.33.3", + "@img/sharp-libvips-darwin-arm64": "1.0.2", + "@img/sharp-libvips-darwin-x64": "1.0.2", + "@img/sharp-libvips-linux-arm": "1.0.2", + "@img/sharp-libvips-linux-arm64": "1.0.2", + "@img/sharp-libvips-linux-s390x": "1.0.2", + "@img/sharp-libvips-linux-x64": "1.0.2", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.2", + "@img/sharp-libvips-linuxmusl-x64": "1.0.2", + "@img/sharp-linux-arm": "0.33.3", + "@img/sharp-linux-arm64": "0.33.3", + "@img/sharp-linux-s390x": "0.33.3", + "@img/sharp-linux-x64": "0.33.3", + "@img/sharp-linuxmusl-arm64": "0.33.3", + "@img/sharp-linuxmusl-x64": "0.33.3", + "@img/sharp-wasm32": "0.33.3", + "@img/sharp-win32-ia32": "0.33.3", + "@img/sharp-win32-x64": "0.33.3" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-xml-to-json": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/simple-xml-to-json/-/simple-xml-to-json-1.2.3.tgz", + "integrity": "sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA==", + "license": "MIT", + "engines": { + "node": ">=20.12.2" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sonic-boom": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz", + "integrity": "sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT" + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strtok3": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/swagger-ui-dist": { + "version": "5.17.14", + "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz", + "integrity": "sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==", + "license": "Apache-2.0" + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/thread-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", + "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", + "license": "MIT", + "dependencies": { + "real-require": "^0.2.0" + } + }, + "node_modules/thread-stream/node_modules/real-require": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", + "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==", + "license": "MIT" + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-types": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", + "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.2.1", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/touch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", + "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", + "dev": true, + "license": "ISC", + "bin": { + "nodetouch": "bin/nodetouch.js" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trouter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/trouter/-/trouter-2.0.1.tgz", + "integrity": "sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==", + "license": "MIT", + "dependencies": { + "matchit": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz", + "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths-webpack-plugin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tapable": "^2.2.1", + "tsconfig-paths": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tsx": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz", + "integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.25.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "license": "BSD-2-Clause", + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uid": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", + "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", + "license": "MIT", + "dependencies": { + "@lukeed/csprng": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undefsafe": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", + "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/underscore": { + "version": "1.13.8", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.8.tgz", + "integrity": "sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", + "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utif2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz", + "integrity": "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==", + "license": "MIT", + "dependencies": { + "pako": "^1.0.11" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/validator": { + "version": "13.15.15", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", + "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/webpack": { + "version": "5.97.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", + "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.2.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-node-externals": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", + "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/whaileys": { + "version": "6.3.8", + "resolved": "https://registry.npmjs.org/whaileys/-/whaileys-6.3.8.tgz", + "integrity": "sha512-3pZYp0dP0zp11klZIAX/mpqDGyoFY0o3PPw2fsI+vRhm/DChiioGkYNrCJcmtshDm/Xfl6M/+f5Q0IKVhqfW6g==", + "license": "MIT", + "dependencies": { + "@hapi/boom": "^9.1.3", + "axios": "^0.24.0", + "futoin-hkdf": "^1.5.0", + "libsignal": "github:canove/libsignal-node#105ad38dc8d7668b5d5e3688e710915bef5cdc7f", + "lodash": "^4.17.21", + "music-metadata": "^7.12.3", + "node-cache": "^5.1.2", + "pino": "^7.0.0", + "protobufjs": "^7.2.4", + "protobufjs-cli": "^1.1.3", + "ws": "^8.0.0" + }, + "peerDependencies": { + "@adiwajshing/keyed-db": "^0.2.4", + "jimp": "^0.16.1", + "link-preview-js": "^2.1.13", + "qrcode-terminal": "^0.12.0", + "sharp": "^0.30.5" + }, + "peerDependenciesMeta": { + "@adiwajshing/keyed-db": { + "optional": true + }, + "jimp": { + "optional": true + }, + "link-preview-js": { + "optional": true + }, + "qrcode-terminal": { + "optional": true + }, + "sharp": { + "optional": true + } + } + }, + "node_modules/whaileys/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "license": "MIT" + }, + "node_modules/whaileys/node_modules/axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.14.4" + } + }, + "node_modules/whaileys/node_modules/libsignal": { + "version": "2.0.1", + "resolved": "git+ssh://git@github.com/canove/libsignal-node.git#105ad38dc8d7668b5d5e3688e710915bef5cdc7f", + "integrity": "sha512-9DDCxMERQlIblJURTM3hq7+RS/yJ5R0BS45f/S3g+dkod0xtDlYCGwADumqDk9cRC5n+j7nk/g4q6Vm9VILqDQ==", + "license": "GPL-3.0", + "dependencies": { + "curve25519-js": "^0.0.4", + "protobufjs": "6.8.8" + } + }, + "node_modules/whaileys/node_modules/libsignal/node_modules/protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "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/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/whaileys/node_modules/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", + "license": "Apache-2.0" + }, + "node_modules/whaileys/node_modules/pino": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-7.11.0.tgz", + "integrity": "sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==", + "license": "MIT", + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.0.0", + "on-exit-leak-free": "^0.2.0", + "pino-abstract-transport": "v0.5.0", + "pino-std-serializers": "^4.0.0", + "process-warning": "^1.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.1.0", + "safe-stable-stringify": "^2.1.0", + "sonic-boom": "^2.2.1", + "thread-stream": "^0.15.1" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/whaileys/node_modules/pino-abstract-transport": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz", + "integrity": "sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==", + "license": "MIT", + "dependencies": { + "duplexify": "^4.1.2", + "split2": "^4.0.0" + } + }, + "node_modules/whaileys/node_modules/pino-std-serializers": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz", + "integrity": "sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==", + "license": "MIT" + }, + "node_modules/whaileys/node_modules/process-warning": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz", + "integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==", + "license": "MIT" + }, + "node_modules/whaileys/node_modules/thread-stream": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-0.15.2.tgz", + "integrity": "sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==", + "license": "MIT", + "dependencies": { + "real-require": "^0.1.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/win-guid": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/win-guid/-/win-guid-0.2.1.tgz", + "integrity": "sha512-gEIQU4mkgl2OPeoNrWflcJFJ3Ae2BPd4eCsHHA/XikslkIVms/nHhvnvzIZV7VLmBvtFlDOzLt9rrZT+n6D67A==", + "license": "MIT" + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==", + "license": "MIT" + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "license": "Apache-2.0" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/bot-wsp/package.json b/bot-wsp/package.json new file mode 100644 index 0000000..6f7b494 --- /dev/null +++ b/bot-wsp/package.json @@ -0,0 +1,81 @@ +{ + "name": "bot-wsp", + "version": "1.0.0", + "description": "", + "main": "dist/main.js", + "type": "commonjs", + "engines": { + "node": ">=22" + }, + "scripts": { + "start": "nest start --exec \"node --experimental-require-module\"", + "generar": "prisma format && prisma generate && prisma db push", + "prisma:generate": "prisma generate", + "kill:port": "lsof -ti:3001 | xargs kill -9 2>/dev/null || true", + "prestart:dev": "npm run kill:port && npm run prisma:generate", + "start:dev": "nest start --exec \"node --experimental-require-module\" --watch", + "lint": "eslint .", + "dev": "npm run lint && npm run start:dev", + "build": "nest build" + }, + "keywords": [], + "dependencies": { + "@builderbot/bot": "1.3.15", + "@builderbot/provider-baileys": "1.3.15", + "@builderbot/provider-sherpa": "1.3.15", + "@nestjs/axios": "^4.0.0", + "@nestjs/common": "^10.3.0", + "@nestjs/core": "^10.3.0", + "@nestjs/jwt": "^11.0.0", + "@nestjs/mapped-types": "*", + "@nestjs/passport": "^11.0.5", + "@nestjs/platform-express": "^10.3.0", + "@nestjs/schedule": "^6.0.0", + "@nestjs/swagger": "7.4.2", + "@nestjs/throttler": "^6.4.0", + "@prisma/client": "^6.10.1", + "aurik3-builderbot-baileys-custom": "^0.0.9", + "axios": "^1.7.2", + "baileys": "^7.0.0-rc.9", + "chrono-node": "^2.8.3", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.2", + "dayjs": "^1.11.13", + "dotenv": "^16.4.5", + "express": "^4.18.2", + "multer": "^2.0.2", + "nanoid": "^3.3.6", + "passport": "^0.7.0", + "pnpm": "^10.32.1", + "reflect-metadata": "^0.2.0", + "rxjs": "^7.8.1", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@nestjs/cli": "^10.3.0", + "@types/express": "^4.17.21", + "@types/multer": "^1.4.11", + "@types/node": "^20.19.6", + "@types/passport": "^1.0.16", + "@typescript-eslint/eslint-plugin": "^7.2.0", + "@typescript-eslint/parser": "^7.4.0", + "eslint": "^8.52.0", + "eslint-plugin-builderbot": "latest", + "nodemon": "^3.1.0", + "prisma": "^6.10.1", + "rollup": "^4.10.0", + "rollup-plugin-typescript2": "^0.36.0", + "tsx": "^4.7.1", + "typescript": "^5.4.3" + }, + "author": "", + "license": "ISC", + "overrides": { + "supports-color": "8.1.1" + }, + "pnpm": { + "patchedDependencies": { + "@builderbot/provider-baileys@1.3.15": "patches/@builderbot__provider-baileys@1.3.15.patch" + } + } +} diff --git a/bot-wsp/patches/@builderbot__provider-baileys@1.3.15.patch b/bot-wsp/patches/@builderbot__provider-baileys@1.3.15.patch new file mode 100644 index 0000000..d63d1ac --- /dev/null +++ b/bot-wsp/patches/@builderbot__provider-baileys@1.3.15.patch @@ -0,0 +1,16 @@ +diff --git a/dist/index.cjs b/dist/index.cjs +index 96df9de111b53cd97228e4fa05d46e7d24428459..c2d1fc0f7e9a5de1bc1afd1839b01f9561e8b882 100644 +--- a/dist/index.cjs ++++ b/dist/index.cjs +@@ -31032,9 +31032,9 @@ class BaileysProvider extends bot.ProviderClass { + this.initVendor().then((v) => this.listenOnEvents(v)); + } + try { +- const sock = makeWASocketOther({ ++ const sock = makeWASocketOther.makeWASocket({ + logger: loggerBaileys, +- version: [2, 3000, 1025190524], ++ version: this.globalVendorArgs.version ?? [2, 3000, 1025190524], + printQRInTerminal: false, + auth: { + creds: state.creds, diff --git a/bot-wsp/pnpm-lock.yaml b/bot-wsp/pnpm-lock.yaml new file mode 100644 index 0000000..f7f3a0f --- /dev/null +++ b/bot-wsp/pnpm-lock.yaml @@ -0,0 +1,7813 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +patchedDependencies: + '@builderbot/provider-baileys@1.3.15': + hash: c283889da0b3785de34e1a1604daa63c96680b4d725ec7cb70e3ffef837b0f4c + path: patches/@builderbot__provider-baileys@1.3.15.patch + +importers: + + .: + dependencies: + '@builderbot/bot': + specifier: 1.3.15 + version: 1.3.15 + '@builderbot/provider-baileys': + specifier: 1.3.15 + version: 1.3.15(patch_hash=c283889da0b3785de34e1a1604daa63c96680b4d725ec7cb70e3ffef837b0f4c)(audio-decode@2.2.0) + '@builderbot/provider-sherpa': + specifier: 1.3.15 + version: 1.3.15 + '@nestjs/axios': + specifier: ^4.0.0 + version: 4.0.1(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.13.6)(rxjs@7.8.2) + '@nestjs/common': + specifier: ^10.3.0 + version: 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': + specifier: ^10.3.0 + version: 10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.22)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/jwt': + specifier: ^11.0.0 + version: 11.0.2(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2)) + '@nestjs/mapped-types': + specifier: '*' + version: 2.1.0(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) + '@nestjs/passport': + specifier: ^11.0.5 + version: 11.0.5(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0) + '@nestjs/platform-express': + specifier: ^10.3.0 + version: 10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22) + '@nestjs/schedule': + specifier: ^6.0.0 + version: 6.1.1(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22) + '@nestjs/swagger': + specifier: 7.4.2 + version: 7.4.2(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2) + '@nestjs/throttler': + specifier: ^6.4.0 + version: 6.5.0(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22)(reflect-metadata@0.2.2) + '@prisma/client': + specifier: ^6.10.1 + version: 6.19.2(prisma@6.19.2(typescript@5.4.5))(typescript@5.4.5) + aurik3-builderbot-baileys-custom: + specifier: ^0.0.9 + version: 0.0.9(audio-decode@2.2.0)(qrcode-terminal@0.12.0) + axios: + specifier: ^1.7.2 + version: 1.13.6 + baileys: + specifier: ^7.0.0-rc.9 + version: 7.0.0-rc.9(audio-decode@2.2.0)(jimp@1.6.0)(sharp@0.33.3) + chrono-node: + specifier: ^2.8.3 + version: 2.9.0 + class-transformer: + specifier: ^0.5.1 + version: 0.5.1 + class-validator: + specifier: ^0.14.2 + version: 0.14.4 + dayjs: + specifier: ^1.11.13 + version: 1.11.19 + dotenv: + specifier: ^16.4.5 + version: 16.4.5 + express: + specifier: ^4.18.2 + version: 4.22.1 + multer: + specifier: ^2.0.2 + version: 2.0.2 + nanoid: + specifier: ^3.3.6 + version: 3.3.11 + passport: + specifier: ^0.7.0 + version: 0.7.0 + pnpm: + specifier: ^10.32.1 + version: 10.32.1 + reflect-metadata: + specifier: ^0.2.0 + version: 0.2.2 + rxjs: + specifier: ^7.8.1 + version: 7.8.2 + uuid: + specifier: ^11.1.0 + version: 11.1.0 + devDependencies: + '@nestjs/cli': + specifier: ^10.3.0 + version: 10.4.9 + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + '@types/multer': + specifier: ^1.4.11 + version: 1.4.11 + '@types/node': + specifier: ^20.19.6 + version: 20.19.33 + '@types/passport': + specifier: ^1.0.16 + version: 1.0.17 + '@typescript-eslint/eslint-plugin': + specifier: ^7.2.0 + version: 7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: ^7.4.0 + version: 7.7.1(eslint@8.57.0)(typescript@5.4.5) + eslint: + specifier: ^8.52.0 + version: 8.57.0 + eslint-plugin-builderbot: + specifier: latest + version: 1.1.3 + nodemon: + specifier: ^3.1.0 + version: 3.1.0 + prisma: + specifier: ^6.10.1 + version: 6.19.2(typescript@5.4.5) + rollup: + specifier: ^4.10.0 + version: 4.16.4 + rollup-plugin-typescript2: + specifier: ^0.36.0 + version: 0.36.0(rollup@4.16.4)(typescript@5.4.5) + tsx: + specifier: ^4.7.1 + version: 4.7.2 + typescript: + specifier: ^5.4.3 + version: 5.4.5 + +packages: + + '@aashutoshrathi/word-wrap@1.2.6': + resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} + engines: {node: '>=0.10.0'} + + '@adiwajshing/keyed-db@0.2.4': + resolution: {integrity: sha512-yprSnAtj80/VKuDqRcFFLDYltoNV8tChNwFfIgcf6PGD4sjzWIBgs08pRuTqGH5mk5wgL6PBRSsMCZqtZwzFEw==} + + '@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'} + + '@arr/every@1.0.1': + resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==} + engines: {node: '>=4'} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + 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.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.0': + resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@borewit/text-codec@0.2.1': + resolution: {integrity: sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==} + + '@builderbot/bot@1.3.15': + resolution: {integrity: sha512-g5ofmOTp0ixcQfOBi0wb90ePhGu0lpwZUtryY5/6D/5bYOcHyX6078IYwTm1T2Vn2gTj3c8sIF9r2gGasUSG3g==} + + '@builderbot/provider-baileys@1.3.15': + resolution: {integrity: sha512-CfqqZ69RTmOlJnG1aJ8PYVynUluWzdzLKkS10cnENQaTGSlopDI9huDHBskrrfU7+jqdYfGnxy3I3Ru/4nop7Q==} + + '@builderbot/provider-sherpa@1.3.15': + resolution: {integrity: sha512-l6RoIFbol9dDIrvt8gIktMEVCc9t2vXW7NPPMlJo164mKX/1Dt3eiV0oqgemRGc3fJX5HyAma/sDtbjvdhXjng==} + + '@cacheable/node-cache@1.5.5': + resolution: {integrity: sha512-pCvDtZbYIwWi2Rs3fgakM/EkzfLwNsdDMjvlb1cpPxUx0q5wiULsxTYHHhoXamFHAwVwgOM5gLaQzSAhYkDVoA==} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@emnapi/runtime@1.1.1': + resolution: {integrity: sha512-3bfqkzuR1KLx57nZfjr2NLnFOobvyS0aTszaEGCGqmYMVDRaGvgIZbjGSV/MHSSmLgQ/b9JFHQ5xm5WRZYd+XQ==} + + '@esbuild/aix-ppc64@0.19.12': + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.19.12': + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.19.12': + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.19.12': + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.19.12': + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.19.12': + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.19.12': + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.19.12': + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.19.12': + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.19.12': + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.19.12': + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.19.12': + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.19.12': + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.19.12': + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.19.12': + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.19.12': + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.19.12': + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.19.12': + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.19.12': + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.19.12': + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.19.12': + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.19.12': + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.19.12': + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eshaz/web-worker@1.2.2': + resolution: {integrity: sha512-WxXiHFmD9u/owrzempiDlBB1ZYqiLnm9s6aPc8AlFQalq2tKmqdmMr9GXOupDgzXtqnBipj8Un0gkIm7Sjf8mw==} + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + 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.10.0': + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} + 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.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@ffmpeg-installer/darwin-arm64@4.1.5': + resolution: {integrity: sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==} + cpu: [arm64] + os: [darwin] + + '@ffmpeg-installer/darwin-x64@4.1.0': + resolution: {integrity: sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==} + cpu: [x64] + os: [darwin] + + '@ffmpeg-installer/ffmpeg@1.1.0': + resolution: {integrity: sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==} + + '@ffmpeg-installer/linux-arm64@4.1.4': + resolution: {integrity: sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==} + cpu: [arm64] + os: [linux] + + '@ffmpeg-installer/linux-arm@4.1.3': + resolution: {integrity: sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==} + cpu: [arm] + os: [linux] + + '@ffmpeg-installer/linux-ia32@4.1.0': + resolution: {integrity: sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==} + cpu: [ia32] + os: [linux] + + '@ffmpeg-installer/linux-x64@4.1.0': + resolution: {integrity: sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==} + cpu: [x64] + os: [linux] + + '@ffmpeg-installer/win32-ia32@4.1.0': + resolution: {integrity: sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==} + cpu: [ia32] + os: [win32] + + '@ffmpeg-installer/win32-x64@4.1.0': + resolution: {integrity: sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==} + cpu: [x64] + os: [win32] + + '@hapi/boom@9.1.4': + resolution: {integrity: sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw==} + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + + '@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==} + + '@img/sharp-darwin-arm64@0.33.3': + resolution: {integrity: sha512-FaNiGX1MrOuJ3hxuNzWgsT/mg5OHG/Izh59WW2mk1UwYHUwtfbhk5QNKYZgxf0pLOhx9ctGiGa2OykD71vOnSw==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.3': + resolution: {integrity: sha512-2QeSl7QDK9ru//YBT4sQkoq7L0EAJZA3rtV+v9p8xTKl4U1bUqTIaCnoC7Ctx2kCjQgwFXDasOtPTCT8eCTXvw==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.2': + resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==} + engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.2': + resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==} + engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.2': + resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.0.2': + resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.0.2': + resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==} + engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.0.2': + resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==} + engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.2': + resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.0.2': + resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==} + engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.33.3': + resolution: {integrity: sha512-Zf+sF1jHZJKA6Gor9hoYG2ljr4wo9cY4twaxgFDvlG0Xz9V7sinsPp8pFd1XtlhTzYo0IhDbl3rK7P6MzHpnYA==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.33.3': + resolution: {integrity: sha512-Q7Ee3fFSC9P7vUSqVEF0zccJsZ8GiiCJYGWDdhEjdlOeS9/jdkyJ6sUSPj+bL8VuOYFSbofrW0t/86ceVhx32w==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.33.3': + resolution: {integrity: sha512-vFk441DKRFepjhTEH20oBlFrHcLjPfI8B0pMIxGm3+yilKyYeHEVvrZhYFdqIseSclIqbQ3SnZMwEMWonY5XFA==} + engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.33.3': + resolution: {integrity: sha512-Q4I++herIJxJi+qmbySd072oDPRkCg/SClLEIDh5IL9h1zjhqjv82H0Seupd+q2m0yOfD+/fJnjSoDFtKiHu2g==} + engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.33.3': + resolution: {integrity: sha512-qnDccehRDXadhM9PM5hLvcPRYqyFCBN31kq+ErBSZtZlsAc1U4Z85xf/RXv1qolkdu+ibw64fUDaRdktxTNP9A==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.33.3': + resolution: {integrity: sha512-Jhchim8kHWIU/GZ+9poHMWRcefeaxFIs9EBqf9KtcC14Ojk6qua7ghKiPs0sbeLbLj/2IGBtDcxHyjCdYWkk2w==} + engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.33.3': + resolution: {integrity: sha512-68zivsdJ0koE96stdUfM+gmyaK/NcoSZK5dV5CAjES0FUXS9lchYt8LAB5rTbM7nlWtxaU/2GON0HVN6/ZYJAQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.3': + resolution: {integrity: sha512-CyimAduT2whQD8ER4Ux7exKrtfoaUiVr7HG0zZvO0XTFn2idUWljjxv58GxNTkFb8/J9Ub9AqITGkJD6ZginxQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.3': + resolution: {integrity: sha512-viT4fUIDKnli3IfOephGnolMzhz5VaTvDRkYqtZxOMIoMQ4MrAziO7pT1nVnOt2FAm7qW5aa+CCc13aEY6Le0g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jimp/core@1.6.0': + resolution: {integrity: sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w==} + engines: {node: '>=18'} + + '@jimp/diff@1.6.0': + resolution: {integrity: sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw==} + engines: {node: '>=18'} + + '@jimp/file-ops@1.6.0': + resolution: {integrity: sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ==} + engines: {node: '>=18'} + + '@jimp/js-bmp@1.6.0': + resolution: {integrity: sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw==} + engines: {node: '>=18'} + + '@jimp/js-gif@1.6.0': + resolution: {integrity: sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g==} + engines: {node: '>=18'} + + '@jimp/js-jpeg@1.6.0': + resolution: {integrity: sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA==} + engines: {node: '>=18'} + + '@jimp/js-png@1.6.0': + resolution: {integrity: sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg==} + engines: {node: '>=18'} + + '@jimp/js-tiff@1.6.0': + resolution: {integrity: sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw==} + engines: {node: '>=18'} + + '@jimp/plugin-blit@1.6.0': + resolution: {integrity: sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA==} + engines: {node: '>=18'} + + '@jimp/plugin-blur@1.6.0': + resolution: {integrity: sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw==} + engines: {node: '>=18'} + + '@jimp/plugin-circle@1.6.0': + resolution: {integrity: sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw==} + engines: {node: '>=18'} + + '@jimp/plugin-color@1.6.0': + resolution: {integrity: sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA==} + engines: {node: '>=18'} + + '@jimp/plugin-contain@1.6.0': + resolution: {integrity: sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ==} + engines: {node: '>=18'} + + '@jimp/plugin-cover@1.6.0': + resolution: {integrity: sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA==} + engines: {node: '>=18'} + + '@jimp/plugin-crop@1.6.0': + resolution: {integrity: sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang==} + engines: {node: '>=18'} + + '@jimp/plugin-displace@1.6.0': + resolution: {integrity: sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q==} + engines: {node: '>=18'} + + '@jimp/plugin-dither@1.6.0': + resolution: {integrity: sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ==} + engines: {node: '>=18'} + + '@jimp/plugin-fisheye@1.6.0': + resolution: {integrity: sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA==} + engines: {node: '>=18'} + + '@jimp/plugin-flip@1.6.0': + resolution: {integrity: sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg==} + engines: {node: '>=18'} + + '@jimp/plugin-hash@1.6.0': + resolution: {integrity: sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q==} + engines: {node: '>=18'} + + '@jimp/plugin-mask@1.6.0': + resolution: {integrity: sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA==} + engines: {node: '>=18'} + + '@jimp/plugin-print@1.6.0': + resolution: {integrity: sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A==} + engines: {node: '>=18'} + + '@jimp/plugin-quantize@1.6.0': + resolution: {integrity: sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg==} + engines: {node: '>=18'} + + '@jimp/plugin-resize@1.6.0': + resolution: {integrity: sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA==} + engines: {node: '>=18'} + + '@jimp/plugin-rotate@1.6.0': + resolution: {integrity: sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw==} + engines: {node: '>=18'} + + '@jimp/plugin-threshold@1.6.0': + resolution: {integrity: sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w==} + engines: {node: '>=18'} + + '@jimp/types@1.6.0': + resolution: {integrity: sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg==} + engines: {node: '>=18'} + + '@jimp/utils@1.6.0': + resolution: {integrity: sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA==} + engines: {node: '>=18'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsdoc/salty@0.2.10': + resolution: {integrity: sha512-VFHSsQAQp8y1NJvAJBpLs9I2shHE6hz9TwukocDObuUgGVAq62yZGbTgJg04Z3Fj0XSMWe0sJqGg5dhKGTV92A==} + engines: {node: '>=v12.0.0'} + + '@keyv/serialize@1.0.3': + resolution: {integrity: sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==} + + '@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'} + + '@microsoft/tsdoc@0.15.1': + resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==} + + '@nestjs/axios@4.0.1': + resolution: {integrity: sha512-68pFJgu+/AZbWkGu65Z3r55bTsCPlgyKaV4BSG8yUAD72q1PPuyVRgUwFv6BxdnibTUHlyxm06FmYWNC+bjN7A==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + axios: ^1.3.1 + rxjs: ^7.0.0 + + '@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.22': + resolution: {integrity: sha512-fxJ4v85nDHaqT1PmfNCQ37b/jcv2OojtXTaK1P2uAXhzLf9qq6WNUOFvxBrV4fhQek1EQoT1o9oj5xAZmv3NRw==} + 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/core@10.4.22': + resolution: {integrity: sha512-6IX9+VwjiKtCjx+mXVPncpkQ5ZjKfmssOZPFexmT+6T9H9wZ3svpYACAo7+9e7Nr9DZSoRZw3pffkJP7Z0UjaA==} + 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/jwt@11.0.2': + resolution: {integrity: sha512-rK8aE/3/Ma45gAWfCksAXUNbOoSOUudU0Kn3rT39htPF7wsYXtKfjALKeKKJbFrIWbLjsbqfXX5bIJNvgBugGA==} + peerDependencies: + '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 + + '@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/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@10.4.22': + resolution: {integrity: sha512-ySSq7Py/DFozzZdNDH67m/vHoeVdphDniWBnl6q5QVoXldDdrZIHLXLRMPayTDh5A95nt7jjJzmD4qpTbNQ6tA==} + peerDependencies: + '@nestjs/common': ^10.0.0 + '@nestjs/core': ^10.0.0 + + '@nestjs/schedule@6.1.1': + resolution: {integrity: sha512-kQl1RRgi02GJ0uaUGCrXHCcwISsCsJDciCKe38ykJZgnAeeoeVWs8luWtBo4AqAAXm4nS5K8RlV0smHUJ4+2FA==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + '@nestjs/core': ^10.0.0 || ^11.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/throttler@6.5.0': + resolution: {integrity: sha512-9j0ZRfH0QE1qyrj9JjIRDz5gQLPqq9yVC2nHsrosDVAfI5HHw08/aUAWx9DZLSdQf4HDkmhTTEGLrRFHENvchQ==} + peerDependencies: + '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 + '@nestjs/core': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 + reflect-metadata: ^0.1.13 || ^0.2.0 + + '@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 + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polka/url@0.5.0': + resolution: {integrity: sha512-oZLYFEAzUKyi3SKnXvj32ZCEGH6RDnao7COuCVhDydMS9NrCSVXhM79VaKyP5+Zc33m0QXEd2DN3UkU7OsHcfw==} + + '@prisma/client@6.19.2': + resolution: {integrity: sha512-gR2EMvfK/aTxsuooaDA32D8v+us/8AAet+C3J1cc04SW35FPdZYgLF+iN4NDLUgAaUGTKdAB0CYenu1TAgGdMg==} + engines: {node: '>=18.18'} + peerDependencies: + prisma: '*' + typescript: '>=5.1.0' + peerDependenciesMeta: + prisma: + optional: true + typescript: + optional: true + + '@prisma/config@6.19.2': + resolution: {integrity: sha512-kadBGDl+aUswv/zZMk9Mx0C8UZs1kjao8H9/JpI4Wh4SHZaM7zkTwiKn/iFLfRg+XtOAo/Z/c6pAYhijKl0nzQ==} + + '@prisma/debug@6.19.2': + resolution: {integrity: sha512-lFnEZsLdFLmEVCVNdskLDCL8Uup41GDfU0LUfquw+ercJC8ODTuL0WNKgOKmYxCJVvFwf0OuZBzW99DuWmoH2A==} + + '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': + resolution: {integrity: sha512-03bgb1VD5gvuumNf+7fVGBzfpJPjmqV423l/WxsWk2cNQ42JD0/SsFBPhN6z8iAvdHs07/7ei77SKu7aZfq8bA==} + + '@prisma/engines@6.19.2': + resolution: {integrity: sha512-TTkJ8r+uk/uqczX40wb+ODG0E0icVsMgwCTyTHXehaEfb0uo80M9g1aW1tEJrxmFHeOZFXdI2sTA1j1AgcHi4A==} + + '@prisma/fetch-engine@6.19.2': + resolution: {integrity: sha512-h4Ff4Pho+SR1S8XerMCC12X//oY2bG3Iug/fUnudfcXEUnIeRiBdXHFdGlGOgQ3HqKgosTEhkZMvGM9tWtYC+Q==} + + '@prisma/get-platform@6.19.2': + resolution: {integrity: sha512-PGLr06JUSTqIvztJtAzIxOwtWKtJm5WwOG6xpsgD37Rc84FpfUBGLKz65YpJBGtkRQGXTYEFie7pYALocC3MtA==} + + '@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==} + + '@rollup/pluginutils@4.2.1': + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + + '@rollup/rollup-android-arm-eabi@4.16.4': + resolution: {integrity: sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm-eabi@4.59.0': + resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.16.4': + resolution: {integrity: sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-android-arm64@4.59.0': + resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.16.4': + resolution: {integrity: sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-arm64@4.59.0': + resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.16.4': + resolution: {integrity: sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.59.0': + resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.59.0': + resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.59.0': + resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.16.4': + resolution: {integrity: sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.16.4': + resolution: {integrity: sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.16.4': + resolution: {integrity: sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.16.4': + resolution: {integrity: sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-musl@4.59.0': + resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.59.0': + resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-powerpc64le-gnu@4.16.4': + resolution: {integrity: sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.16.4': + resolution: {integrity: sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.16.4': + resolution: {integrity: sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.16.4': + resolution: {integrity: sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.59.0': + resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.16.4': + resolution: {integrity: sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-x64-musl@4.59.0': + resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.59.0': + resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.59.0': + resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.16.4': + resolution: {integrity: sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.16.4': + resolution: {integrity: sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.59.0': + resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.16.4': + resolution: {integrity: sha512-YunpoOAyGLDseanENHmbFvQSfVL5BxW3k7hhy0eN4rb3gS/ct75dVD0EXOWIqFT/nE8XYW6LP6vz6ctKRi0k9A==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.59.0': + resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==} + cpu: [x64] + os: [win32] + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@thi.ng/bitstream@2.2.59': + resolution: {integrity: sha512-9YEzjujV/rU/510z0Ht2jgPVsWakseXDxPaacW0nKCd/QxGd4TTeuSkehf/SOKoRLfeUpApbJcbk8gIbZJdAOQ==} + engines: {node: '>=18'} + + '@thi.ng/errors@2.5.6': + resolution: {integrity: sha512-i2mNaye+ieK3lIugMRdjac12vgnwyq52wE6dMSF/PRN1hciY+zV+q9VObbL1X19Nqy/G5xMghIrzDOeIRcObLg==} + engines: {node: '>=18'} + + '@tokenizer/inflate@0.2.7': + resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} + engines: {node: '>=18'} + + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@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.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/express-serve-static-core@4.19.0': + resolution: {integrity: sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==} + + '@types/express@4.17.21': + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/jsonwebtoken@9.0.10': + resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/long@4.0.2': + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + + '@types/luxon@3.7.1': + resolution: {integrity: sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/multer@1.4.11': + resolution: {integrity: sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w==} + + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + + '@types/node@16.9.1': + resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==} + + '@types/node@20.19.33': + resolution: {integrity: sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==} + + '@types/passport@1.0.17': + resolution: {integrity: sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==} + + '@types/polka@0.5.7': + resolution: {integrity: sha512-TH8CDXM8zoskPCNmWabtK7ziGv9Q21s4hMZLVYK5HFEfqmGXBqq/Wgi7jNELWXftZK/1J/9CezYa06x1RKeQ+g==} + + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/trouter@3.1.4': + resolution: {integrity: sha512-4YIL/2AvvZqKBWenjvEpxpblT2KGO6793ipr5QS7/6DpQ3O3SwZGgNGWezxf3pzeYZc24a2pJIrR/+Jxh/wYNQ==} + + '@types/validator@13.15.10': + resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} + + '@typescript-eslint/eslint-plugin@7.7.1': + resolution: {integrity: sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.7.1': + resolution: {integrity: sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.7.1': + resolution: {integrity: sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.7.1': + resolution: {integrity: sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.7.1': + resolution: {integrity: sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.7.1': + resolution: {integrity: sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.7.1': + resolution: {integrity: sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.7.1': + resolution: {integrity: sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@wasm-audio-decoders/common@9.0.4': + resolution: {integrity: sha512-+XdSt6mMfvir5D+vcW8gLqledJIgzkBAGXOG7ySJtbKdOTHduG2YAHvUNH9/Mb2hkiM8U9EJrGA6HhbsqG/bbg==} + + '@wasm-audio-decoders/common@9.0.5': + resolution: {integrity: sha512-b9JNh9sPAvn8PVIizNh9D60WkfQong/u9ea873H47u7zvVDLctxYIp2aZw9CQqXaQdk7JB3MoU5UHiseO40swg==} + + '@wasm-audio-decoders/flac@0.2.4': + resolution: {integrity: sha512-bsUlwIjd5y+IAEyILCQdi8y0LocKEkZ0enA8ljDL+NVVwN+5Rv5Xkm/HcdUxnB7MtekxN2cNcTsv1zkb2aZyWg==} + + '@wasm-audio-decoders/ogg-vorbis@0.1.15': + resolution: {integrity: sha512-skAN3NIrRzMkVouyfyq3gYT/op/K9iutMZr7kr5/9fnIaCnpYdrdbv69X8PZ6y3K2J5zy5KuGno5kzH8yGLOOg==} + + '@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==} + + '@whiskeysockets/libsignal-node@https://codeload.github.com/whiskeysockets/libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67': + resolution: {tarball: https://codeload.github.com/whiskeysockets/libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67} + version: 2.0.1 + + '@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@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + 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-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.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + 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.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + any-base@1.1.0: + resolution: {integrity: sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==} + + 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==} + + 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'} + + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + + async@0.2.10: + resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} + + async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + audio-buffer@5.0.0: + resolution: {integrity: sha512-gsDyj1wwUp8u7NBB+eW6yhLb9ICf+0eBmDX8NGaAS00w8/fLqFdxUlL5Ge/U8kB64DlQhdonxYC59dXy1J7H/w==} + + audio-decode@2.2.0: + resolution: {integrity: sha512-3SLGQ4VL57+fuFHV5JBeTNx3frjdztOIm4LJBFqiFhMQGeerrcS3WQbfuPPOqcNmqFGmPeaAAFPCxF75cSK/pQ==} + + audio-type@2.2.1: + resolution: {integrity: sha512-En9AY6EG1qYqEy5L/quryzbA4akBpJrnBZNxeKTqGHC2xT9Qc4aZ8b7CcbOMFTTc/MGdoNyp+SN4zInZNKxMYA==} + engines: {node: '>=14'} + + aurik3-builderbot-baileys-custom@0.0.9: + resolution: {integrity: sha512-oR9rUFRqCopW/DtjK0ZXfbyQQOTfqwe8X7Xn18Q2oiohspAMLMVrxpvpNTUW7yQilRdCPBpriBeIJXzwZl8cdg==} + + aurik3-whaileys@6.3.8: + resolution: {integrity: sha512-HO8zEJ9AwAcN5qcnp0i3CNtmCDUEonh+w9oLGgZE0EdlYhpENP3r+o74yWi0JWwEXAxmQW2mZIDOvhM/D63Qxw==} + peerDependencies: + '@adiwajshing/keyed-db': ^0.2.4 + jimp: ^0.16.1 + link-preview-js: ^2.1.13 + qrcode-terminal: ^0.12.0 + sharp: ^0.30.5 + peerDependenciesMeta: + '@adiwajshing/keyed-db': + optional: true + jimp: + optional: true + link-preview-js: + optional: true + qrcode-terminal: + optional: true + sharp: + optional: true + + await-to-js@3.0.0: + resolution: {integrity: sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g==} + engines: {node: '>=6.0.0'} + + axios@0.24.0: + resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} + + axios@1.13.6: + resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==} + + baileys@7.0.0-rc.6: + resolution: {integrity: sha512-Unt58dy39rFQ3dRgTUxT38/AXWInNLYx9zijU7PpHDeoNdJfvgyROnHLtmh9hAglLKA1t374v1JLnfI5Tk/TSQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + audio-decode: ^2.1.3 + jimp: ^1.6.0 + link-preview-js: ^3.0.0 + sharp: '*' + peerDependenciesMeta: + audio-decode: + optional: true + jimp: + optional: true + link-preview-js: + optional: true + + baileys@7.0.0-rc.9: + resolution: {integrity: sha512-Txd2dZ9MHbojvsHckeuCnAKPO/bQjKxua/0tQSJwOKXffK5vpS82k4eA/Nb46K0cK0Bx+fyY0zhnQHYMBriQcw==} + engines: {node: '>=20.0.0'} + peerDependencies: + audio-decode: ^2.1.3 + jimp: ^1.6.0 + link-preview-js: ^3.0.0 + sharp: '*' + peerDependenciesMeta: + audio-decode: + optional: true + jimp: + optional: true + link-preview-js: + optional: true + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.10.0: + resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} + engines: {node: '>=6.0.0'} + hasBin: true + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + bmp-ts@1.0.9: + resolution: {integrity: sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw==} + + body-parser@1.20.4: + resolution: {integrity: sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + 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'} + + c12@3.1.0: + resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + + cacheable@1.9.0: + resolution: {integrity: sha512-8D5htMCxPDUULux9gFzv30f04Xo3wCnik0oOxKoRTPIBoqA7HtOcJ87uBhQTs3jCfZZTrUBGsYIZOgE0ZRgMAg==} + + 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'} + + caniuse-lite@1.0.30001774: + resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} + + catharsis@0.9.0: + resolution: {integrity: sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==} + engines: {node: '>= 10'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.2.0: + resolution: {integrity: sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==} + engines: {node: '>=20.18.1'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + 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'} + + chrono-node@2.9.0: + resolution: {integrity: sha512-glI4YY2Jy6JII5l3d5FN6rcrIbKSQqKPhWsIRYPK2IK8Mm4Q1ZZFdYIaDqglUNf7gNwG+kWIzTn0omzzE0VkvQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + citty@0.2.1: + resolution: {integrity: sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==} + + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + + class-validator@0.14.4: + resolution: {integrity: sha512-AwNusCCam51q703dW82x95tOqQp6oC9HNUl724KxJJOfnKscI8dOloXFgyez7LbTTKWuRBA37FScqVbJEoq8Yw==} + + 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'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + codec-parser@2.4.3: + resolution: {integrity: sha512-3dAvFtdpxn4YLstqsB2ZiJXXNg7n1j7R5ONeDuk+2kBkb39PwrCRytOFHlSWA8q5jCjW3PumeMv9q37bFHsijg==} + + 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-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + 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'} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + + confbox@0.2.4: + resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} + + consola@2.15.3: + resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==} + + 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-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + 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 + + cron@4.4.0: + resolution: {integrity: sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==} + engines: {node: '>=18.x'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + curve25519-js@0.0.4: + resolution: {integrity: sha512-axn2UMEnkhyDUPWOwVKBMVIzSQy2ejH2xRGy1wq81dqRwApXfIzfbE3hIX0ZRFBIihf/KDqK158DLwESu4AK1w==} + + dayjs@1.11.19: + resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge-ts@7.1.5: + resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + engines: {node: '>=16.0.0'} + + 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'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + 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'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + 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'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + effect@3.18.4: + resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + + electron-to-chromium@1.5.302: + resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + empathic@2.0.0: + resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} + engines: {node: '>=14'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + 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'} + + esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + + 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'} + + escodegen@1.14.3: + resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} + engines: {node: '>=4.0'} + hasBin: true + + eslint-plugin-builderbot@1.1.3: + resolution: {integrity: sha512-DD9dc/YpsVNj9z8f3lsEJg8u4EU1CJerdtTrpaltEPu/39qZ4x2lQWFdV3SCMQk4h/VmOdB2sXH5MB0W1QZN1g==} + + 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.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + 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.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + 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'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + 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'} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + exif-parser@0.1.12: + resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} + + express@4.22.1: + resolution: {integrity: sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==} + engines: {node: '>= 0.10.0'} + + exsolve@1.0.8: + resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-check@3.23.2: + resolution: {integrity: sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A==} + engines: {node: '>=8.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + 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-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + 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@16.5.4: + resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} + engines: {node: '>=10'} + + file-type@20.4.1: + resolution: {integrity: sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==} + engines: {node: '>=18'} + + file-type@21.3.0: + resolution: {integrity: sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==} + engines: {node: '>=20'} + + fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=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.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + fluent-ffmpeg@2.1.2: + resolution: {integrity: sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==} + engines: {node: '>=0.8.0'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + fluent-ffmpeg@2.1.3: + resolution: {integrity: sha512-Be3narBNt2s6bsaqP6Jzq91heDgOEaDCJAXcE3qcma/EJBSy5FB4cvO31XBInuAuKBx8Kptf8dkhjK0IOru39Q==} + engines: {node: '>=18'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + 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.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + 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-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-extra@11.3.3: + resolution: {integrity: sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==} + engines: {node: '>=14.14'} + + fs-monkey@1.1.0: + resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} + + 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==} + + futoin-hkdf@1.5.3: + resolution: {integrity: sha512-SewY5KdMpaoCeh7jachEWFsh1nNlaDjNHZXWqL5IGwtpEYHTgkr2+AMCgNwKWkcc0wpSYrZfR7he4WdmHFtDxQ==} + engines: {node: '>=8'} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-intrinsic@1.3.0: + 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'} + + get-tsconfig@4.7.3: + resolution: {integrity: sha512-ZvkrzoUA0PQZM6fy6+/Hce561s+faD1rsNwhnO5FelNjyy7EMGJ3Rz1AQ8GYDWjhRs/7dBLOEJvhK8MiEJOAFg==} + + gifwrap@0.10.1: + resolution: {integrity: sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw==} + + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} + hasBin: true + + 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==} + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + 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'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + 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==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + 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-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + 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'} + + hookified@1.9.0: + resolution: {integrity: sha512-2yEEGqphImtKIe1NXWEhu6yD3hlFR4Mxk4Mtp3XEyScpSt4pQ4ymmXA1zzxZpj99QkFK+nN0nzjeb2+RUi/6CQ==} + + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + 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-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + image-q@4.0.0: + resolution: {integrity: sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + 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==} + + 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'} + + 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-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + 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-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-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + 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==} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jimp@1.6.0: + resolution: {integrity: sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg==} + engines: {node: '>=18'} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + jpeg-js@0.4.4: + resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + js2xmlparser@4.0.2: + resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} + + jsdoc@4.0.5: + resolution: {integrity: sha512-P4C6MWP9yIlMiK8nwoZvxN84vb6MsnXcHuy7XzVOvQoCizWX5JFCBsWIIWKXBltpoRZXddUOVQmCTOZt9yDj9g==} + engines: {node: '>=12.0.0'} + 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==} + + jsonwebtoken@9.0.3: + resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} + engines: {node: '>=12', npm: '>=6'} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + keyv@5.3.3: + resolution: {integrity: sha512-Rwu4+nXI9fqcxiEHtbkvoes2X+QfkTRo1TMkPfwzipGsJlJO/z69vqB4FNl9xJ3xCpAcbkvmEabZfPzrwN3+gQ==} + + klaw@3.0.0: + resolution: {integrity: sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + libphonenumber-js@1.12.37: + resolution: {integrity: sha512-rDU6bkpuMs8YRt/UpkuYEAsYSoNuDEbrE41I3KNvmXREGH6DGBJ8Wbak4by29wNOQ27zk4g4HL82zf0OGhwRuw==} + + libsignal@https://codeload.github.com/canove/libsignal-node/tar.gz/105ad38dc8d7668b5d5e3688e710915bef5cdc7f: + resolution: {tarball: https://codeload.github.com/canove/libsignal-node/tar.gz/105ad38dc8d7668b5d5e3688e710915bef5cdc7f} + version: 2.0.1 + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + 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.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lodash@4.17.23: + resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + + long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.2.6: + resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} + engines: {node: 20 || >=22} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + luxon@3.7.2: + resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} + engines: {node: '>=12'} + + 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'} + + markdown-it-anchor@8.6.7: + resolution: {integrity: sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==} + peerDependencies: + '@types/markdown-it': '*' + markdown-it: '*' + + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + + marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + + matchit@1.1.0: + resolution: {integrity: sha512-+nGYoOlfHmxe5BW5tE0EMJppXEwdSf8uBA1GTZC7Q77kbT35+VKLYJMzVNWCHSsga1ps1tPYFtFyvxvKzWVmMA==} + engines: {node: '>=6'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + 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@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.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + 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@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.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.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + 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 + + mpg123-decoder@0.4.12: + resolution: {integrity: sha512-BjeE7+D7FttqNRFtF3IgSSnG2Hn96ID4JDsCCmxhaPy2R1yuJu2gaabhlS9r12JibaRTT2SYDMXTyjD6xqe0fg==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multer@2.0.2: + resolution: {integrity: sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==} + engines: {node: '>= 10.16.0'} + + music-metadata@11.12.1: + resolution: {integrity: sha512-j++ltLxHDb5VCXET9FzQ8bnueiLHwQKgCO7vcbkRH/3F7fRjPkv6qncGEJ47yFhmemcYtgvsOAlcQ1dRBTkDjg==} + engines: {node: '>=18'} + + music-metadata@7.14.0: + resolution: {integrity: sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA==} + engines: {node: '>=10'} + + 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} + + nanoid@3.3.11: + 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==} + + 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-cache@5.1.2: + resolution: {integrity: sha512-t1QzWwnk4sjLWaQAS8CHgOJ+RAfmHpxFWmc36IWTiWHQfs0w5JDMBS1b1ZxQteo0vVVuWJvIUKHDkkeK7vIGCg==} + engines: {node: '>= 8.0.0'} + + node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + 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-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + node-wav@0.0.2: + resolution: {integrity: sha512-M6Rm/bbG6De/gKGxOpeOobx/dnGuP0dz40adqx38boqHhlWssBJZgLCPBNtb9NkrmnKYiV04xELq+R6PFOnoLA==} + engines: {node: '>=4.4.0'} + + nodemon@3.1.0: + resolution: {integrity: sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==} + engines: {node: '>=10'} + hasBin: true + + nopt@1.0.10: + resolution: {integrity: sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nypm@0.6.5: + resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} + engines: {node: '>=18'} + hasBin: true + + 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'} + + ogg-opus-decoder@1.6.12: + resolution: {integrity: sha512-6MY/rgFegJABKVE7LS10lmVoy8dFhvLDbIlcymgMnn0qZG0YHqcUU+bW+MkVyhhWN3H0vqtkRlPHGOXU6yR5YQ==} + + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + + omggif@1.0.10: + resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + 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.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + optionator@0.9.3: + resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} + engines: {node: '>= 0.8.0'} + + opus-decoder@0.7.6: + resolution: {integrity: sha512-5QYSl1YQYbSzWL7vM4dJoyrLC804xIvBFjfKTZZ6/z/EgmdFouOTT+8PDM2V18vzgnhRNPDuyB2aTfl/2hvMRA==} + + 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-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-queue@9.1.0: + resolution: {integrity: sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==} + engines: {node: '>=20'} + + p-timeout@7.0.1: + resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} + engines: {node: '>=20'} + + 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==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-bmfont-ascii@1.0.6: + resolution: {integrity: sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==} + + parse-bmfont-binary@1.0.6: + resolution: {integrity: sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==} + + parse-bmfont-xml@1.1.6: + resolution: {integrity: sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + + 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-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'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pause@0.0.1: + resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} + + peek-readable@4.1.0: + resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} + engines: {node: '>=8'} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + 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'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + + pino@9.7.0: + resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==} + hasBin: true + + pixelmatch@5.3.0: + resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==} + hasBin: true + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + pngjs@6.0.0: + resolution: {integrity: sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==} + engines: {node: '>=12.13.0'} + + pngjs@7.0.0: + resolution: {integrity: sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow==} + engines: {node: '>=14.19.0'} + + pnpm@10.32.1: + resolution: {integrity: sha512-pwaTjw6JrBRWtlY+q07fHR+vM2jRGR/FxZeQ6W3JGORFarLmfWE94QQ9LoyB+HMD5rQNT/7KnfFe8a1Wc0jyvg==} + engines: {node: '>=18.12'} + hasBin: true + + polka@0.5.2: + resolution: {integrity: sha512-FVg3vDmCqP80tOrs+OeNlgXYmFppTXdjD5E7I4ET1NjvtNmQrb1/mJibybKkb/d4NA7YWAr1ojxuhpL3FHqdlw==} + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prisma@6.19.2: + resolution: {integrity: sha512-XTKeKxtQElcq3U9/jHyxSPgiRgeYDKxWTPOf6NkXA0dNj5j40MfEsZkMbyNpwDWCUv7YBFUl7I2VK/6ALbmhEg==} + engines: {node: '>=18.18'} + hasBin: true + peerDependencies: + typescript: '>=5.1.0' + peerDependenciesMeta: + typescript: + optional: true + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + + protobufjs-cli@1.2.0: + resolution: {integrity: sha512-+YvqJEmsmZHGzE5j0tvEzFeHm0sX7pzRFpyj7+GazhkS4Y0r+jgbioVvFxxSWIlPzUel/lxeOnLChBmV8NmyHA==} + engines: {node: '>=12.0.0'} + hasBin: true + peerDependencies: + protobufjs: ^7.0.0 + + protobufjs@6.8.8: + resolution: {integrity: sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==} + hasBin: true + + protobufjs@7.2.6: + resolution: {integrity: sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==} + engines: {node: '>=12.0.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + qoa-format@1.0.1: + resolution: {integrity: sha512-dMB0Z6XQjdpz/Cw4Rf6RiBpQvUSPCfYlQMWvmuWlWkAT7nDQD29cVZ1SwDUB6DYJSitHENwbt90lqfI+7bvMcw==} + + qrcode-terminal@0.12.0: + resolution: {integrity: sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==} + hasBin: true + + qs@6.14.2: + resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + 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.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-web-to-node-stream@3.0.2: + resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} + engines: {node: '>=8'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.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-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requizzle@0.2.4: + resolution: {integrity: sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + + rollup-plugin-typescript2@0.36.0: + resolution: {integrity: sha512-NB2CSQDxSe9+Oe2ahZbf+B4bh7pHwjV5L+RSYpCu7Q5ROuN94F9b6ioWwKfz3ueL3KTtmX4o2MUH2cgHDIEUsw==} + peerDependencies: + rollup: '>=1.26.3' + typescript: '>=2.4.0' + + rollup@4.16.4: + resolution: {integrity: sha512-kuaTJSUbz+Wsb2ATGvEknkI12XV40vIiHmLuFlejoo7HtDok/O5eDDD0UpCVY5bBX5U5RYo8wWP83H7ZsqVEnA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rollup@4.59.0: + resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + 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.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sax@1.4.4: + resolution: {integrity: sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==} + engines: {node: '>=11.0.0'} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + 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==} + + sharp@0.33.3: + resolution: {integrity: sha512-vHUeXJU1UvlO/BNwTpT0x/r53WkLUVxrmb5JTgW92fdFCFk0ispLMAeu/jPO2vjkXM1fYUi3K7/qcLF47pwM1A==} + engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + 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'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + + simple-xml-to-json@1.2.3: + resolution: {integrity: sha512-kWJDCr9EWtZ+/EYYM5MareWj2cRnZGF93YDNpH4jQiHB+hBIZnfPFSQiVMzZOdk+zXWqTZ/9fTeQNu2DqeiudA==} + engines: {node: '>=20.12.2'} + + simple-yenc@1.0.4: + resolution: {integrity: sha512-5gvxpSd79e9a3V4QDYUqnqxeD4HGlhCakVpb6gMnDD7lexJggSBJRBO5h52y/iJrdXRilX9UCuDaIJhSWm5OWw==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + 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'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.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.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.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strtok3@10.3.4: + resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} + engines: {node: '>=18'} + + strtok3@6.3.0: + resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} + engines: {node: '>=10'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + 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'} + + 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'} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.3.16: + resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + 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.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} + engines: {node: '>=10'} + hasBin: true + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + + tinyexec@1.0.2: + resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} + engines: {node: '>=18'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + 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@4.2.1: + resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==} + engines: {node: '>=10'} + + token-types@6.1.2: + resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} + engines: {node: '>=14.16'} + + touch@3.1.0: + resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==} + hasBin: true + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + trouter@2.0.1: + resolution: {integrity: sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==} + engines: {node: '>=6'} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + 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.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.7.2: + resolution: {integrity: sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + 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-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.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + uid@2.0.2: + resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} + engines: {node: '>=8'} + + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + + underscore@1.13.8: + resolution: {integrity: sha512-DXtD3ZtEQzc7M8m4cXotyHR+FAS18C64asBYY5vqZexfYryNNnDc02W4hKg3rdQuqOYas1jkseX0+nZXjTXnvQ==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici@7.22.0: + resolution: {integrity: sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==} + engines: {node: '>=20.18.1'} + + 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.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + utif2@4.1.0: + resolution: {integrity: sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w==} + + 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@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + validator@13.15.26: + resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==} + engines: {node: '>= 0.10'} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + 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.3.4: + resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} + 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 + + whaileys@6.3.8: + resolution: {integrity: sha512-3pZYp0dP0zp11klZIAX/mpqDGyoFY0o3PPw2fsI+vRhm/DChiioGkYNrCJcmtshDm/Xfl6M/+f5Q0IKVhqfW6g==} + peerDependencies: + '@adiwajshing/keyed-db': ^0.2.4 + jimp: ^0.16.1 + link-preview-js: ^2.1.13 + qrcode-terminal: ^0.12.0 + sharp: ^0.30.5 + peerDependenciesMeta: + '@adiwajshing/keyed-db': + optional: true + jimp: + optional: true + link-preview-js: + optional: true + qrcode-terminal: + optional: true + sharp: + optional: true + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + 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@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + win-guid@0.2.1: + resolution: {integrity: sha512-gEIQU4mkgl2OPeoNrWflcJFJ3Ae2BPd4eCsHHA/XikslkIVms/nHhvnvzIZV7VLmBvtFlDOzLt9rrZT+n6D67A==} + + 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==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + 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 + + xml-parse-from-string@1.0.1: + resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} + + xml2js@0.5.0: + resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xmlcreate@2.0.4: + resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + 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'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + +snapshots: + + '@aashutoshrathi/word-wrap@1.2.6': {} + + '@adiwajshing/keyed-db@0.2.4': {} + + '@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 + + '@arr/every@1.0.1': {} + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/parser@7.29.0': + dependencies: + '@babel/types': 7.29.0 + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@borewit/text-codec@0.2.1': {} + + '@builderbot/bot@1.3.15': + dependencies: + '@ffmpeg-installer/ffmpeg': 1.1.0 + body-parser: 1.20.4 + cors: 2.8.5 + fluent-ffmpeg: 2.1.3 + follow-redirects: 1.15.11 + mime-types: 2.1.35 + picocolors: 1.1.1 + polka: 0.5.2 + optionalDependencies: + sharp: 0.33.3 + transitivePeerDependencies: + - debug + - supports-color + + '@builderbot/provider-baileys@1.3.15(patch_hash=c283889da0b3785de34e1a1604daa63c96680b4d725ec7cb70e3ffef837b0f4c)(audio-decode@2.2.0)': + dependencies: + '@adiwajshing/keyed-db': 0.2.4 + '@ffmpeg-installer/ffmpeg': 1.1.0 + '@types/polka': 0.5.7 + baileys: 7.0.0-rc.9(audio-decode@2.2.0)(jimp@1.6.0)(sharp@0.33.3) + cheerio: 1.2.0 + fluent-ffmpeg: 2.1.2 + fs-extra: 11.3.3 + jimp: 1.6.0 + node-cache: 5.1.2 + sharp: 0.33.3 + transitivePeerDependencies: + - audio-decode + - bufferutil + - link-preview-js + - supports-color + - utf-8-validate + + '@builderbot/provider-sherpa@1.3.15': + dependencies: + '@adiwajshing/keyed-db': 0.2.4 + '@ffmpeg-installer/ffmpeg': 1.1.0 + '@types/polka': 0.5.7 + fluent-ffmpeg: 2.1.2 + fs-extra: 11.3.3 + jimp: 1.6.0 + node-cache: 5.1.2 + qrcode-terminal: 0.12.0 + rollup: 4.59.0 + sharp: 0.33.3 + tslib: 2.8.1 + typescript: 5.9.3 + whaileys: 6.3.8(@adiwajshing/keyed-db@0.2.4)(jimp@1.6.0)(qrcode-terminal@0.12.0)(sharp@0.33.3) + transitivePeerDependencies: + - bufferutil + - debug + - link-preview-js + - supports-color + - utf-8-validate + + '@cacheable/node-cache@1.5.5': + dependencies: + cacheable: 1.9.0 + hookified: 1.9.0 + keyv: 5.3.3 + + '@colors/colors@1.5.0': + optional: true + + '@emnapi/runtime@1.1.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.19.12': + optional: true + + '@esbuild/android-arm64@0.19.12': + optional: true + + '@esbuild/android-arm@0.19.12': + optional: true + + '@esbuild/android-x64@0.19.12': + optional: true + + '@esbuild/darwin-arm64@0.19.12': + optional: true + + '@esbuild/darwin-x64@0.19.12': + optional: true + + '@esbuild/freebsd-arm64@0.19.12': + optional: true + + '@esbuild/freebsd-x64@0.19.12': + optional: true + + '@esbuild/linux-arm64@0.19.12': + optional: true + + '@esbuild/linux-arm@0.19.12': + optional: true + + '@esbuild/linux-ia32@0.19.12': + optional: true + + '@esbuild/linux-loong64@0.19.12': + optional: true + + '@esbuild/linux-mips64el@0.19.12': + optional: true + + '@esbuild/linux-ppc64@0.19.12': + optional: true + + '@esbuild/linux-riscv64@0.19.12': + optional: true + + '@esbuild/linux-s390x@0.19.12': + optional: true + + '@esbuild/linux-x64@0.19.12': + optional: true + + '@esbuild/netbsd-x64@0.19.12': + optional: true + + '@esbuild/openbsd-x64@0.19.12': + optional: true + + '@esbuild/sunos-x64@0.19.12': + optional: true + + '@esbuild/win32-arm64@0.19.12': + optional: true + + '@esbuild/win32-ia32@0.19.12': + optional: true + + '@esbuild/win32-x64@0.19.12': + optional: true + + '@eshaz/web-worker@1.2.2': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.10.0': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.4(supports-color@5.5.0) + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@ffmpeg-installer/darwin-arm64@4.1.5': + optional: true + + '@ffmpeg-installer/darwin-x64@4.1.0': + optional: true + + '@ffmpeg-installer/ffmpeg@1.1.0': + optionalDependencies: + '@ffmpeg-installer/darwin-arm64': 4.1.5 + '@ffmpeg-installer/darwin-x64': 4.1.0 + '@ffmpeg-installer/linux-arm': 4.1.3 + '@ffmpeg-installer/linux-arm64': 4.1.4 + '@ffmpeg-installer/linux-ia32': 4.1.0 + '@ffmpeg-installer/linux-x64': 4.1.0 + '@ffmpeg-installer/win32-ia32': 4.1.0 + '@ffmpeg-installer/win32-x64': 4.1.0 + + '@ffmpeg-installer/linux-arm64@4.1.4': + optional: true + + '@ffmpeg-installer/linux-arm@4.1.3': + optional: true + + '@ffmpeg-installer/linux-ia32@4.1.0': + optional: true + + '@ffmpeg-installer/linux-x64@4.1.0': + optional: true + + '@ffmpeg-installer/win32-ia32@4.1.0': + optional: true + + '@ffmpeg-installer/win32-x64@4.1.0': + optional: true + + '@hapi/boom@9.1.4': + dependencies: + '@hapi/hoek': 9.3.0 + + '@hapi/hoek@9.3.0': {} + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.4(supports-color@5.5.0) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@img/sharp-darwin-arm64@0.33.3': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.2 + optional: true + + '@img/sharp-darwin-x64@0.33.3': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.2 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.2': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.2': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.2': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.2': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.2': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.2': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.2': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.2': + optional: true + + '@img/sharp-linux-arm64@0.33.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.2 + optional: true + + '@img/sharp-linux-arm@0.33.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.2 + optional: true + + '@img/sharp-linux-s390x@0.33.3': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.2 + optional: true + + '@img/sharp-linux-x64@0.33.3': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.2 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.2 + optional: true + + '@img/sharp-wasm32@0.33.3': + dependencies: + '@emnapi/runtime': 1.1.1 + optional: true + + '@img/sharp-win32-ia32@0.33.3': + optional: true + + '@img/sharp-win32-x64@0.33.3': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.2 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jimp/core@1.6.0': + dependencies: + '@jimp/file-ops': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + await-to-js: 3.0.0 + exif-parser: 0.1.12 + file-type: 16.5.4 + mime: 3.0.0 + + '@jimp/diff@1.6.0': + dependencies: + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + pixelmatch: 5.3.0 + + '@jimp/file-ops@1.6.0': {} + + '@jimp/js-bmp@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + bmp-ts: 1.0.9 + + '@jimp/js-gif@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + gifwrap: 0.10.1 + omggif: 1.0.10 + + '@jimp/js-jpeg@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + jpeg-js: 0.4.4 + + '@jimp/js-png@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + pngjs: 7.0.0 + + '@jimp/js-tiff@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + utif2: 4.1.0 + + '@jimp/plugin-blit@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-blur@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/utils': 1.6.0 + + '@jimp/plugin-circle@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-color@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + tinycolor2: 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-contain@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-blit': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-cover@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-crop': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-crop@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-displace@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-dither@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + + '@jimp/plugin-fisheye@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-flip@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-hash@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/js-bmp': 1.6.0 + '@jimp/js-jpeg': 1.6.0 + '@jimp/js-png': 1.6.0 + '@jimp/js-tiff': 1.6.0 + '@jimp/plugin-color': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + any-base: 1.1.0 + + '@jimp/plugin-mask@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-print@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/js-jpeg': 1.6.0 + '@jimp/js-png': 1.6.0 + '@jimp/plugin-blit': 1.6.0 + '@jimp/types': 1.6.0 + parse-bmfont-ascii: 1.0.6 + parse-bmfont-binary: 1.0.6 + parse-bmfont-xml: 1.1.6 + simple-xml-to-json: 1.2.3 + zod: 3.25.76 + + '@jimp/plugin-quantize@1.6.0': + dependencies: + image-q: 4.0.0 + zod: 3.25.76 + + '@jimp/plugin-resize@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/types': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-rotate@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-crop': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/plugin-threshold@1.6.0': + dependencies: + '@jimp/core': 1.6.0 + '@jimp/plugin-color': 1.6.0 + '@jimp/plugin-hash': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + zod: 3.25.76 + + '@jimp/types@1.6.0': + dependencies: + zod: 3.25.76 + + '@jimp/utils@1.6.0': + dependencies: + '@jimp/types': 1.6.0 + tinycolor2: 1.6.0 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsdoc/salty@0.2.10': + dependencies: + lodash: 4.17.23 + + '@keyv/serialize@1.0.3': + dependencies: + buffer: 6.0.3 + + '@ljharb/through@2.3.14': + dependencies: + call-bind: 1.0.8 + + '@lukeed/csprng@1.1.0': {} + + '@microsoft/tsdoc@0.15.1': {} + + '@nestjs/axios@4.0.1(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(axios@1.13.6)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + axios: 1.13.6 + rxjs: 7.8.2 + + '@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.22(class-transformer@0.5.1)(class-validator@0.14.4)(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.4 + transitivePeerDependencies: + - supports-color + + '@nestjs/core@10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.22)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nuxtjs/opencollective': 0.3.2(encoding@0.1.13) + 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/platform-express': 10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22) + transitivePeerDependencies: + - encoding + + '@nestjs/jwt@11.0.2(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@types/jsonwebtoken': 9.0.10 + jsonwebtoken: 9.0.3 + + '@nestjs/mapped-types@2.0.5(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + reflect-metadata: 0.2.2 + optionalDependencies: + class-transformer: 0.5.1 + class-validator: 0.14.4 + + '@nestjs/mapped-types@2.1.0(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + reflect-metadata: 0.2.2 + optionalDependencies: + class-transformer: 0.5.1 + class-validator: 0.14.4 + + '@nestjs/passport@11.0.5(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(passport@0.7.0)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + passport: 0.7.0 + + '@nestjs/platform-express@10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.22)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + body-parser: 1.20.4 + cors: 2.8.5 + express: 4.22.1 + multer: 2.0.2 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@nestjs/schedule@6.1.1(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.22)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + cron: 4.4.0 + + '@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/swagger@7.4.2(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22)(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)': + dependencies: + '@microsoft/tsdoc': 0.15.1 + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.22)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.0.5(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.4)(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.4 + + '@nestjs/throttler@6.5.0(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@10.4.22)(reflect-metadata@0.2.2)': + dependencies: + '@nestjs/common': 10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 10.4.22(@nestjs/common@10.4.22(class-transformer@0.5.1)(class-validator@0.14.4)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.22)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + reflect-metadata: 0.2.2 + + '@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.17.1 + + '@nuxtjs/opencollective@0.3.2(encoding@0.1.13)': + dependencies: + chalk: 4.1.2 + consola: 2.15.3 + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polka/url@0.5.0': {} + + '@prisma/client@6.19.2(prisma@6.19.2(typescript@5.4.5))(typescript@5.4.5)': + optionalDependencies: + prisma: 6.19.2(typescript@5.4.5) + typescript: 5.4.5 + + '@prisma/config@6.19.2': + dependencies: + c12: 3.1.0 + deepmerge-ts: 7.1.5 + effect: 3.18.4 + empathic: 2.0.0 + transitivePeerDependencies: + - magicast + + '@prisma/debug@6.19.2': {} + + '@prisma/engines-version@7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7': {} + + '@prisma/engines@6.19.2': + dependencies: + '@prisma/debug': 6.19.2 + '@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7 + '@prisma/fetch-engine': 6.19.2 + '@prisma/get-platform': 6.19.2 + + '@prisma/fetch-engine@6.19.2': + dependencies: + '@prisma/debug': 6.19.2 + '@prisma/engines-version': 7.1.1-3.c2990dca591cba766e3b7ef5d9e8a84796e47ab7 + '@prisma/get-platform': 6.19.2 + + '@prisma/get-platform@6.19.2': + dependencies: + '@prisma/debug': 6.19.2 + + '@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': {} + + '@rollup/pluginutils@4.2.1': + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + + '@rollup/rollup-android-arm-eabi@4.16.4': + optional: true + + '@rollup/rollup-android-arm-eabi@4.59.0': + optional: true + + '@rollup/rollup-android-arm64@4.16.4': + optional: true + + '@rollup/rollup-android-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.16.4': + optional: true + + '@rollup/rollup-darwin-arm64@4.59.0': + optional: true + + '@rollup/rollup-darwin-x64@4.16.4': + optional: true + + '@rollup/rollup-darwin-x64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.59.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.16.4': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.16.4': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.16.4': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.16.4': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.16.4': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.16.4': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.59.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.16.4': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.16.4': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.16.4': + optional: true + + '@rollup/rollup-linux-x64-musl@4.59.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.59.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.59.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.16.4': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.16.4': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.59.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.16.4': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.59.0': + optional: true + + '@standard-schema/spec@1.1.0': {} + + '@thi.ng/bitstream@2.2.59': + dependencies: + '@thi.ng/errors': 2.5.6 + optional: true + + '@thi.ng/errors@2.5.6': + optional: true + + '@tokenizer/inflate@0.2.7': + dependencies: + debug: 4.4.3 + fflate: 0.8.2 + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color + + '@tokenizer/inflate@0.4.1': + dependencies: + debug: 4.4.3 + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.19.33 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 20.19.33 + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.5': {} + + '@types/estree@1.0.8': {} + + '@types/express-serve-static-core@4.19.0': + dependencies: + '@types/node': 20.19.33 + '@types/qs': 6.9.15 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.21': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.0 + '@types/qs': 6.9.15 + '@types/serve-static': 1.15.7 + + '@types/http-errors@2.0.4': {} + + '@types/json-schema@7.0.15': {} + + '@types/jsonwebtoken@9.0.10': + dependencies: + '@types/ms': 2.1.0 + '@types/node': 20.19.33 + + '@types/linkify-it@5.0.0': {} + + '@types/long@4.0.2': {} + + '@types/luxon@3.7.1': {} + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdurl@2.0.0': {} + + '@types/mime@1.3.5': {} + + '@types/ms@2.1.0': {} + + '@types/multer@1.4.11': + dependencies: + '@types/express': 4.17.21 + + '@types/node@10.17.60': {} + + '@types/node@16.9.1': {} + + '@types/node@20.19.33': + dependencies: + undici-types: 6.21.0 + + '@types/passport@1.0.17': + dependencies: + '@types/express': 4.17.21 + + '@types/polka@0.5.7': + dependencies: + '@types/express': 4.17.21 + '@types/express-serve-static-core': 4.19.0 + '@types/node': 20.19.33 + '@types/trouter': 3.1.4 + + '@types/qs@6.9.15': {} + + '@types/range-parser@1.2.7': {} + + '@types/semver@7.5.8': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.19.33 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 20.19.33 + '@types/send': 0.17.4 + + '@types/trouter@3.1.4': {} + + '@types/validator@13.15.10': {} + + '@typescript-eslint/eslint-plugin@7.7.1(@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.7.1 + '@typescript-eslint/type-utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.7.1 + debug: 4.3.4(supports-color@5.5.0) + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.7.1(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.7.1 + '@typescript-eslint/types': 7.7.1 + '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.7.1 + debug: 4.3.4(supports-color@5.5.0) + eslint: 8.57.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.7.1': + dependencies: + '@typescript-eslint/types': 7.7.1 + '@typescript-eslint/visitor-keys': 7.7.1 + + '@typescript-eslint/type-utils@7.7.1(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5) + '@typescript-eslint/utils': 7.7.1(eslint@8.57.0)(typescript@5.4.5) + debug: 4.3.4(supports-color@5.5.0) + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.7.1': {} + + '@typescript-eslint/typescript-estree@7.7.1(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.7.1 + '@typescript-eslint/visitor-keys': 7.7.1 + debug: 4.3.4(supports-color@5.5.0) + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.7.1(eslint@8.57.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 7.7.1 + '@typescript-eslint/types': 7.7.1 + '@typescript-eslint/typescript-estree': 7.7.1(typescript@5.4.5) + eslint: 8.57.0 + semver: 7.6.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.7.1': + dependencies: + '@typescript-eslint/types': 7.7.1 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@wasm-audio-decoders/common@9.0.4': + dependencies: + '@eshaz/web-worker': 1.2.2 + optional: true + + '@wasm-audio-decoders/common@9.0.5': + dependencies: + '@eshaz/web-worker': 1.2.2 + simple-yenc: 1.0.4 + optional: true + + '@wasm-audio-decoders/flac@0.2.4': + dependencies: + '@wasm-audio-decoders/common': 9.0.5 + codec-parser: 2.4.3 + optional: true + + '@wasm-audio-decoders/ogg-vorbis@0.1.15': + dependencies: + '@wasm-audio-decoders/common': 9.0.5 + codec-parser: 2.4.3 + optional: true + + '@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 + + '@whiskeysockets/libsignal-node@https://codeload.github.com/whiskeysockets/libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67': + dependencies: + curve25519-js: 0.0.4 + protobufjs: 6.8.8 + + '@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.11.3): + dependencies: + acorn: 8.11.3 + + acorn@8.11.3: {} + + acorn@8.16.0: {} + + ajv-formats@2.1.1(ajv@8.12.0): + optionalDependencies: + ajv: 8.12.0 + + ajv-formats@2.1.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv-keywords@3.5.2(ajv@6.12.6): + dependencies: + ajv: 6.12.6 + + ajv-keywords@5.1.0(ajv@8.18.0): + dependencies: + ajv: 8.18.0 + 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.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + 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.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + any-base@1.1.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + append-field@1.0.0: {} + + argparse@2.0.1: {} + + array-flatten@1.1.1: {} + + array-timsort@1.0.3: {} + + array-union@2.1.0: {} + + async-mutex@0.5.0: + dependencies: + tslib: 2.6.2 + + async@0.2.10: {} + + async@3.2.5: {} + + asynckit@0.4.0: {} + + atomic-sleep@1.0.0: {} + + audio-buffer@5.0.0: + optional: true + + audio-decode@2.2.0: + dependencies: + '@wasm-audio-decoders/flac': 0.2.4 + '@wasm-audio-decoders/ogg-vorbis': 0.1.15 + audio-buffer: 5.0.0 + audio-type: 2.2.1 + mpg123-decoder: 0.4.12 + node-wav: 0.0.2 + ogg-opus-decoder: 1.6.12 + qoa-format: 1.0.1 + optional: true + + audio-type@2.2.1: + optional: true + + aurik3-builderbot-baileys-custom@0.0.9(audio-decode@2.2.0)(qrcode-terminal@0.12.0): + dependencies: + '@adiwajshing/keyed-db': 0.2.4 + '@ffmpeg-installer/ffmpeg': 1.1.0 + '@types/polka': 0.5.7 + aurik3-whaileys: 6.3.8(@adiwajshing/keyed-db@0.2.4)(jimp@1.6.0)(qrcode-terminal@0.12.0)(sharp@0.33.3) + baileys: 7.0.0-rc.6(audio-decode@2.2.0)(jimp@1.6.0)(sharp@0.33.3) + cheerio: 1.2.0 + fluent-ffmpeg: 2.1.2 + fs-extra: 11.2.0 + jimp: 1.6.0 + node-cache: 5.1.2 + sharp: 0.33.3 + transitivePeerDependencies: + - audio-decode + - bufferutil + - debug + - link-preview-js + - qrcode-terminal + - supports-color + - utf-8-validate + + aurik3-whaileys@6.3.8(@adiwajshing/keyed-db@0.2.4)(jimp@1.6.0)(qrcode-terminal@0.12.0)(sharp@0.33.3): + dependencies: + '@hapi/boom': 9.1.4 + axios: 0.24.0 + futoin-hkdf: 1.5.3 + libsignal: https://codeload.github.com/canove/libsignal-node/tar.gz/105ad38dc8d7668b5d5e3688e710915bef5cdc7f + lodash: 4.17.21 + music-metadata: 7.14.0 + node-cache: 5.1.2 + pino: 7.11.0 + protobufjs: 7.2.6 + protobufjs-cli: 1.2.0(protobufjs@7.2.6) + ws: 8.18.0 + optionalDependencies: + '@adiwajshing/keyed-db': 0.2.4 + jimp: 1.6.0 + qrcode-terminal: 0.12.0 + sharp: 0.33.3 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + await-to-js@3.0.0: {} + + axios@0.24.0: + dependencies: + follow-redirects: 1.15.11 + transitivePeerDependencies: + - debug + + axios@1.13.6: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + baileys@7.0.0-rc.6(audio-decode@2.2.0)(jimp@1.6.0)(sharp@0.33.3): + dependencies: + '@cacheable/node-cache': 1.5.5 + '@hapi/boom': 9.1.4 + async-mutex: 0.5.0 + libsignal: '@whiskeysockets/libsignal-node@https://codeload.github.com/whiskeysockets/libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67' + lru-cache: 11.2.6 + music-metadata: 11.12.1 + p-queue: 9.1.0 + pino: 9.7.0 + protobufjs: 7.2.6 + sharp: 0.33.3 + ws: 8.18.0 + optionalDependencies: + audio-decode: 2.2.0 + jimp: 1.6.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + baileys@7.0.0-rc.9(audio-decode@2.2.0)(jimp@1.6.0)(sharp@0.33.3): + dependencies: + '@cacheable/node-cache': 1.5.5 + '@hapi/boom': 9.1.4 + async-mutex: 0.5.0 + libsignal: '@whiskeysockets/libsignal-node@https://codeload.github.com/whiskeysockets/libsignal-node/tar.gz/1c30d7d7e76a3b0aa120b04dc6a26f5a12dccf67' + lru-cache: 11.2.6 + music-metadata: 11.12.1 + p-queue: 9.1.0 + pino: 9.7.0 + protobufjs: 7.2.6 + sharp: 0.33.3 + ws: 8.18.0 + optionalDependencies: + audio-decode: 2.2.0 + jimp: 1.6.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.10.0: {} + + binary-extensions@2.3.0: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + bluebird@3.7.2: {} + + bmp-ts@1.0.9: {} + + body-parser@1.20.4: + 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.1 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.14.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + 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.2: + dependencies: + fill-range: 7.0.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.10.0 + caniuse-lite: 1.0.30001774 + electron-to-chromium: 1.5.302 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + buffer-equal-constant-time@1.0.1: {} + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + bytes@3.1.2: {} + + c12@3.1.0: + dependencies: + chokidar: 4.0.3 + confbox: 0.2.4 + defu: 6.1.4 + dotenv: 16.6.1 + exsolve: 1.0.8 + giget: 2.0.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + + cacheable@1.9.0: + dependencies: + hookified: 1.9.0 + keyv: 5.3.3 + + 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.0 + get-intrinsic: 1.2.4 + 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: {} + + caniuse-lite@1.0.30001774: {} + + catharsis@0.9.0: + dependencies: + lodash: 4.17.21 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + chardet@0.7.0: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.2.2 + css-what: 6.2.2 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + + cheerio@1.2.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 + htmlparser2: 10.1.0 + parse5: 7.3.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 7.22.0 + whatwg-mimetype: 4.0.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + 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 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chrome-trace-event@1.0.4: {} + + chrono-node@2.9.0: {} + + citty@0.1.6: + dependencies: + consola: 3.4.2 + + citty@0.2.1: {} + + class-transformer@0.5.1: {} + + class-validator@0.14.4: + dependencies: + '@types/validator': 13.15.10 + libphonenumber-js: 1.12.37 + validator: 13.15.26 + + 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: {} + + clone@1.0.4: {} + + clone@2.1.2: {} + + codec-parser@2.4.3: + optional: true + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.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 + + commondir@1.0.1: {} + + concat-map@0.0.1: {} + + concat-stream@2.0.0: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + + confbox@0.2.4: {} + + consola@2.15.3: {} + + consola@3.4.2: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + 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.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.7.2 + + cron@4.4.0: + dependencies: + '@types/luxon': 3.7.1 + luxon: 3.7.2 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-what@6.2.2: {} + + curve25519-js@0.0.4: {} + + dayjs@1.11.19: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.4(supports-color@5.5.0): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 5.5.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + deepmerge-ts@7.1.5: {} + + 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.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + destr@2.0.5: {} + + destroy@1.2.0: {} + + detect-libc@2.0.3: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv@16.4.5: {} + + dotenv@16.6.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + eastasianwidth@0.2.0: {} + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + effect@3.18.4: + dependencies: + '@standard-schema/spec': 1.1.0 + fast-check: 3.23.2 + + electron-to-chromium@1.5.302: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + empathic@2.0.0: {} + + encodeurl@2.0.0: {} + + encoding-sniffer@0.2.1: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + enhanced-resolve@5.19.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + entities@4.5.0: {} + + entities@6.0.1: {} + + entities@7.0.1: {} + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + 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 + + esbuild@0.19.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + + 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: {} + + escodegen@1.14.3: + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-plugin-builderbot@1.1.3: {} + + 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.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4(supports-color@5.5.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.5.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.1 + 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.3 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.5.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eventemitter3@5.0.4: {} + + events@3.3.0: {} + + exif-parser@0.1.12: {} + + express@4.22.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.4 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + 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.14.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + exsolve@1.0.8: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-check@3.23.2: + dependencies: + pure-rand: 6.1.0 + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + 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.5 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + + fast-uri@3.1.0: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + 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@16.5.4: + dependencies: + readable-web-to-node-stream: 3.0.2 + strtok3: 6.3.0 + token-types: 4.2.1 + + file-type@20.4.1: + dependencies: + '@tokenizer/inflate': 0.2.7 + strtok3: 10.3.4 + token-types: 6.1.2 + uint8array-extras: 1.5.0 + transitivePeerDependencies: + - supports-color + + file-type@21.3.0: + dependencies: + '@tokenizer/inflate': 0.4.1 + strtok3: 10.3.4 + token-types: 6.1.2 + uint8array-extras: 1.5.0 + transitivePeerDependencies: + - supports-color + + fill-range@7.0.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.2: + 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.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + 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.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.3.1: {} + + fluent-ffmpeg@2.1.2: + dependencies: + async: 3.2.5 + which: 1.3.1 + + fluent-ffmpeg@2.1.3: + dependencies: + async: 0.2.10 + which: 1.3.1 + + follow-redirects@1.15.11: {} + + 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.29.0 + 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.6.3 + tapable: 2.3.0 + typescript: 5.7.2 + webpack: 5.97.1 + + form-data@4.0.5: + 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@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-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@11.3.3: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-monkey@1.1.0: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + futoin-hkdf@1.5.3: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + 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-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-tsconfig@4.7.3: + dependencies: + resolve-pkg-maps: 1.0.0 + + gifwrap@0.10.1: + dependencies: + image-q: 4.0.0 + omggif: 1.0.10 + + giget@2.0.0: + dependencies: + citty: 0.1.6 + consola: 3.4.2 + defu: 6.1.4 + node-fetch-native: 1.6.7 + nypm: 0.6.5 + pathe: 2.0.3 + + 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.4 + minipass: 7.1.3 + 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 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.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.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-own-prop@2.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + 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 + + hookified@1.9.0: {} + + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + 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-by-default@1.0.1: {} + + ignore@5.3.1: {} + + image-q@4.0.0: + dependencies: + '@types/node': 16.9.1 + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.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.6.2 + 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 + + ipaddr.js@1.9.1: {} + + is-arrayish@0.2.1: {} + + is-arrayish@0.3.2: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.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-unicode-supported@0.1.0: {} + + isexe@2.0.0: {} + + iterare@1.2.1: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jest-worker@27.5.1: + dependencies: + '@types/node': 20.19.33 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jimp@1.6.0: + dependencies: + '@jimp/core': 1.6.0 + '@jimp/diff': 1.6.0 + '@jimp/js-bmp': 1.6.0 + '@jimp/js-gif': 1.6.0 + '@jimp/js-jpeg': 1.6.0 + '@jimp/js-png': 1.6.0 + '@jimp/js-tiff': 1.6.0 + '@jimp/plugin-blit': 1.6.0 + '@jimp/plugin-blur': 1.6.0 + '@jimp/plugin-circle': 1.6.0 + '@jimp/plugin-color': 1.6.0 + '@jimp/plugin-contain': 1.6.0 + '@jimp/plugin-cover': 1.6.0 + '@jimp/plugin-crop': 1.6.0 + '@jimp/plugin-displace': 1.6.0 + '@jimp/plugin-dither': 1.6.0 + '@jimp/plugin-fisheye': 1.6.0 + '@jimp/plugin-flip': 1.6.0 + '@jimp/plugin-hash': 1.6.0 + '@jimp/plugin-mask': 1.6.0 + '@jimp/plugin-print': 1.6.0 + '@jimp/plugin-quantize': 1.6.0 + '@jimp/plugin-resize': 1.6.0 + '@jimp/plugin-rotate': 1.6.0 + '@jimp/plugin-threshold': 1.6.0 + '@jimp/types': 1.6.0 + '@jimp/utils': 1.6.0 + + jiti@2.6.1: {} + + jpeg-js@0.4.4: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + js2xmlparser@4.0.2: + dependencies: + xmlcreate: 2.0.4 + + jsdoc@4.0.5: + dependencies: + '@babel/parser': 7.29.0 + '@jsdoc/salty': 0.2.10 + '@types/markdown-it': 14.1.2 + bluebird: 3.7.2 + catharsis: 0.9.0 + escape-string-regexp: 2.0.0 + js2xmlparser: 4.0.2 + klaw: 3.0.0 + markdown-it: 14.1.1 + markdown-it-anchor: 8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.1) + marked: 4.3.0 + mkdirp: 1.0.4 + requizzle: 0.2.4 + strip-json-comments: 3.1.1 + underscore: 1.13.8 + + 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 + + jsonwebtoken@9.0.3: + dependencies: + jws: 4.0.1 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.2 + semver: 7.6.3 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + keyv@5.3.3: + dependencies: + '@keyv/serialize': 1.0.3 + + klaw@3.0.0: + dependencies: + graceful-fs: 4.2.11 + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + libphonenumber-js@1.12.37: {} + + libsignal@https://codeload.github.com/canove/libsignal-node/tar.gz/105ad38dc8d7668b5d5e3688e710915bef5cdc7f: + dependencies: + curve25519-js: 0.0.4 + protobufjs: 6.8.8 + + lines-and-columns@1.2.4: {} + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + loader-runner@4.3.1: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + + lodash.merge@4.6.2: {} + + lodash.once@4.1.1: {} + + lodash@4.17.21: {} + + lodash@4.17.23: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + long@4.0.0: {} + + long@5.2.3: {} + + lru-cache@10.4.3: {} + + lru-cache@11.2.6: {} + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + luxon@3.7.2: {} + + magic-string@0.30.8: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + markdown-it-anchor@8.6.7(@types/markdown-it@14.1.2)(markdown-it@14.1.1): + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.1 + + markdown-it@14.1.1: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + marked@4.3.0: {} + + matchit@1.1.0: + dependencies: + '@arr/every': 1.0.1 + + math-intrinsics@1.1.0: {} + + mdurl@2.0.0: {} + + media-typer@0.3.0: {} + + media-typer@1.1.0: {} + + memfs@3.5.3: + dependencies: + fs-monkey: 1.1.0 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromatch@4.0.5: + dependencies: + braces: 3.0.2 + 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@3.0.0: {} + + mimic-fn@2.1.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.3: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mpg123-decoder@0.4.12: + dependencies: + '@wasm-audio-decoders/common': 9.0.4 + optional: true + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + multer@2.0.2: + dependencies: + append-field: 1.0.0 + busboy: 1.6.0 + concat-stream: 2.0.0 + mkdirp: 0.5.6 + object-assign: 4.1.1 + type-is: 1.6.18 + xtend: 4.0.2 + + music-metadata@11.12.1: + dependencies: + '@borewit/text-codec': 0.2.1 + '@tokenizer/token': 0.3.0 + content-type: 1.0.5 + debug: 4.4.3 + file-type: 21.3.0 + media-typer: 1.1.0 + strtok3: 10.3.4 + token-types: 6.1.2 + uint8array-extras: 1.5.0 + win-guid: 0.2.1 + transitivePeerDependencies: + - supports-color + + music-metadata@7.14.0: + dependencies: + '@tokenizer/token': 0.3.0 + content-type: 1.0.5 + debug: 4.4.3 + file-type: 16.5.4 + media-typer: 1.1.0 + strtok3: 6.3.0 + token-types: 4.2.1 + transitivePeerDependencies: + - supports-color + + mute-stream@0.0.8: {} + + mute-stream@1.0.0: {} + + nanoid@3.3.11: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + neo-async@2.6.2: {} + + node-abort-controller@3.1.1: {} + + node-cache@5.1.2: + dependencies: + clone: 2.1.2 + + node-emoji@1.11.0: + dependencies: + lodash: 4.17.21 + + node-fetch-native@1.6.7: {} + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-releases@2.0.27: {} + + node-wav@0.0.2: + optional: true + + nodemon@3.1.0: + dependencies: + chokidar: 3.6.0 + debug: 4.3.4(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.6.0 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.0 + undefsafe: 2.0.5 + + nopt@1.0.10: + dependencies: + abbrev: 1.1.1 + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nypm@0.6.5: + dependencies: + citty: 0.2.1 + pathe: 2.0.3 + tinyexec: 1.0.2 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + ogg-opus-decoder@1.6.12: + dependencies: + '@wasm-audio-decoders/common': 9.0.5 + codec-parser: 2.4.3 + opus-decoder: 0.7.6 + optional: true + + ohash@2.0.11: {} + + omggif@1.0.10: {} + + on-exit-leak-free@0.2.0: {} + + on-exit-leak-free@2.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + + optionator@0.9.3: + dependencies: + '@aashutoshrathi/word-wrap': 1.2.6 + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + + opus-decoder@0.7.6: + dependencies: + '@wasm-audio-decoders/common': 9.0.5 + optional: true + + 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-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-queue@9.1.0: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 7.0.1 + + p-timeout@7.0.1: {} + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + pako@1.0.11: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-bmfont-ascii@1.0.6: {} + + parse-bmfont-binary@1.0.6: {} + + parse-bmfont-xml@1.1.6: + dependencies: + xml-parse-from-string: 1.0.1 + xml2js: 0.5.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.3.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.3.0 + + parse5@7.3.0: + dependencies: + entities: 6.0.1 + + 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-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + path-to-regexp@0.1.12: {} + + path-to-regexp@3.3.0: {} + + path-type@4.0.0: {} + + pathe@2.0.3: {} + + pause@0.0.1: {} + + peek-readable@4.1.0: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.1: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@4.0.0: {} + + pino-std-serializers@7.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + + pino@9.7.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.0.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + + pixelmatch@5.3.0: + dependencies: + pngjs: 6.0.0 + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pkg-types@2.3.0: + dependencies: + confbox: 0.2.4 + exsolve: 1.0.8 + pathe: 2.0.3 + + pluralize@8.0.0: {} + + pngjs@6.0.0: {} + + pngjs@7.0.0: {} + + pnpm@10.32.1: {} + + polka@0.5.2: + dependencies: + '@polka/url': 0.5.0 + trouter: 2.0.1 + + prelude-ls@1.1.2: {} + + prelude-ls@1.2.1: {} + + prisma@6.19.2(typescript@5.4.5): + dependencies: + '@prisma/config': 6.19.2 + '@prisma/engines': 6.19.2 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - magicast + + process-warning@1.0.0: {} + + process-warning@5.0.0: {} + + protobufjs-cli@1.2.0(protobufjs@7.2.6): + dependencies: + chalk: 4.1.2 + escodegen: 1.14.3 + espree: 9.6.1 + estraverse: 5.3.0 + glob: 8.1.0 + jsdoc: 4.0.5 + minimist: 1.2.8 + protobufjs: 7.2.6 + semver: 7.6.3 + tmp: 0.2.5 + uglify-js: 3.19.3 + + protobufjs@6.8.8: + 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/long': 4.0.2 + '@types/node': 10.17.60 + long: 4.0.0 + + protobufjs@7.2.6: + 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': 20.19.33 + long: 5.2.3 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@1.1.0: {} + + pstree.remy@1.1.8: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + pure-rand@6.1.0: {} + + qoa-format@1.0.1: + dependencies: + '@thi.ng/bitstream': 2.2.59 + optional: true + + qrcode-terminal@0.12.0: {} + + qs@6.14.2: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.5 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readable-web-to-node-stream@3.0.2: + dependencies: + readable-stream: 3.6.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + real-require@0.1.0: {} + + real-require@0.2.0: {} + + reflect-metadata@0.2.2: {} + + repeat-string@1.6.1: {} + + require-from-string@2.0.2: {} + + requizzle@0.2.4: + dependencies: + lodash: 4.17.21 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.0.4: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup-plugin-typescript2@0.36.0(rollup@4.16.4)(typescript@5.4.5): + dependencies: + '@rollup/pluginutils': 4.2.1 + find-cache-dir: 3.3.2 + fs-extra: 10.1.0 + rollup: 4.16.4 + semver: 7.6.0 + tslib: 2.6.2 + typescript: 5.4.5 + + rollup@4.16.4: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.16.4 + '@rollup/rollup-android-arm64': 4.16.4 + '@rollup/rollup-darwin-arm64': 4.16.4 + '@rollup/rollup-darwin-x64': 4.16.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.16.4 + '@rollup/rollup-linux-arm-musleabihf': 4.16.4 + '@rollup/rollup-linux-arm64-gnu': 4.16.4 + '@rollup/rollup-linux-arm64-musl': 4.16.4 + '@rollup/rollup-linux-powerpc64le-gnu': 4.16.4 + '@rollup/rollup-linux-riscv64-gnu': 4.16.4 + '@rollup/rollup-linux-s390x-gnu': 4.16.4 + '@rollup/rollup-linux-x64-gnu': 4.16.4 + '@rollup/rollup-linux-x64-musl': 4.16.4 + '@rollup/rollup-win32-arm64-msvc': 4.16.4 + '@rollup/rollup-win32-ia32-msvc': 4.16.4 + '@rollup/rollup-win32-x64-msvc': 4.16.4 + fsevents: 2.3.3 + + rollup@4.59.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.59.0 + '@rollup/rollup-android-arm64': 4.59.0 + '@rollup/rollup-darwin-arm64': 4.59.0 + '@rollup/rollup-darwin-x64': 4.59.0 + '@rollup/rollup-freebsd-arm64': 4.59.0 + '@rollup/rollup-freebsd-x64': 4.59.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.59.0 + '@rollup/rollup-linux-arm-musleabihf': 4.59.0 + '@rollup/rollup-linux-arm64-gnu': 4.59.0 + '@rollup/rollup-linux-arm64-musl': 4.59.0 + '@rollup/rollup-linux-loong64-gnu': 4.59.0 + '@rollup/rollup-linux-loong64-musl': 4.59.0 + '@rollup/rollup-linux-ppc64-gnu': 4.59.0 + '@rollup/rollup-linux-ppc64-musl': 4.59.0 + '@rollup/rollup-linux-riscv64-gnu': 4.59.0 + '@rollup/rollup-linux-riscv64-musl': 4.59.0 + '@rollup/rollup-linux-s390x-gnu': 4.59.0 + '@rollup/rollup-linux-x64-gnu': 4.59.0 + '@rollup/rollup-linux-x64-musl': 4.59.0 + '@rollup/rollup-openbsd-x64': 4.59.0 + '@rollup/rollup-openharmony-arm64': 4.59.0 + '@rollup/rollup-win32-arm64-msvc': 4.59.0 + '@rollup/rollup-win32-ia32-msvc': 4.59.0 + '@rollup/rollup-win32-x64-gnu': 4.59.0 + '@rollup/rollup-win32-x64-msvc': 4.59.0 + fsevents: 2.3.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.6.2 + + rxjs@7.8.2: + dependencies: + tslib: 2.6.2 + + safe-buffer@5.2.1: {} + + safe-stable-stringify@2.4.3: {} + + safer-buffer@2.1.2: {} + + sax@1.4.4: {} + + 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.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + ajv-keywords: 5.1.0(ajv@8.18.0) + + semver@6.3.1: {} + + semver@7.6.0: + dependencies: + lru-cache: 6.0.0 + + semver@7.6.3: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + sharp@0.33.3: + dependencies: + color: 4.2.3 + detect-libc: 2.0.3 + semver: 7.6.3 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.3 + '@img/sharp-darwin-x64': 0.33.3 + '@img/sharp-libvips-darwin-arm64': 1.0.2 + '@img/sharp-libvips-darwin-x64': 1.0.2 + '@img/sharp-libvips-linux-arm': 1.0.2 + '@img/sharp-libvips-linux-arm64': 1.0.2 + '@img/sharp-libvips-linux-s390x': 1.0.2 + '@img/sharp-libvips-linux-x64': 1.0.2 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.2 + '@img/sharp-libvips-linuxmusl-x64': 1.0.2 + '@img/sharp-linux-arm': 0.33.3 + '@img/sharp-linux-arm64': 0.33.3 + '@img/sharp-linux-s390x': 0.33.3 + '@img/sharp-linux-x64': 0.33.3 + '@img/sharp-linuxmusl-arm64': 0.33.3 + '@img/sharp-linuxmusl-x64': 0.33.3 + '@img/sharp-wasm32': 0.33.3 + '@img/sharp-win32-ia32': 0.33.3 + '@img/sharp-win32-x64': 0.33.3 + + 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: {} + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + simple-update-notifier@2.0.0: + dependencies: + semver: 7.6.0 + + simple-xml-to-json@1.2.3: {} + + simple-yenc@1.0.4: + optional: true + + slash@3.0.0: {} + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + 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: {} + + split2@4.2.0: {} + + statuses@2.0.2: {} + + stream-shift@1.0.3: {} + + streamsearch@1.1.0: {} + + 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.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.2: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + strtok3@10.3.4: + dependencies: + '@tokenizer/token': 0.3.0 + + strtok3@6.3.0: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 4.1.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + swagger-ui-dist@5.17.14: {} + + symbol-observable@4.0.0: {} + + tapable@2.3.0: {} + + terser-webpack-plugin@5.3.16(webpack@5.97.1): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.46.0 + webpack: 5.97.1 + + terser@5.46.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + text-table@0.2.0: {} + + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + + through@2.3.8: {} + + tinycolor2@1.6.0: {} + + tinyexec@1.0.2: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmp@0.2.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + token-types@4.2.1: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + token-types@6.1.2: + dependencies: + '@borewit/text-codec': 0.2.1 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + touch@3.1.0: + dependencies: + nopt: 1.0.10 + + tr46@0.0.3: {} + + tree-kill@1.2.2: {} + + trouter@2.0.1: + dependencies: + matchit: 1.1.0 + + ts-api-utils@1.3.0(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + + tsconfig-paths-webpack-plugin@4.2.0: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.19.0 + tapable: 2.3.0 + 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.6.2: {} + + tslib@2.8.1: {} + + tsx@4.7.2: + dependencies: + esbuild: 0.19.12 + get-tsconfig: 4.7.3 + optionalDependencies: + fsevents: 2.3.3 + + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typedarray@0.0.6: {} + + typescript@5.4.5: {} + + typescript@5.7.2: {} + + typescript@5.9.3: {} + + uc.micro@2.1.0: {} + + uglify-js@3.19.3: {} + + uid@2.0.2: + dependencies: + '@lukeed/csprng': 1.1.0 + + uint8array-extras@1.5.0: {} + + undefsafe@2.0.5: {} + + underscore@1.13.8: {} + + undici-types@6.21.0: {} + + undici@7.22.0: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + utif2@4.1.0: + dependencies: + pako: 1.0.11 + + util-deprecate@1.0.2: {} + + utils-merge@1.0.1: {} + + uuid@11.1.0: {} + + validator@13.15.26: {} + + vary@1.1.2: {} + + watchpack@2.5.1: + 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.3.4: {} + + webpack@5.97.1: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.16.0 + browserslist: 4.28.1 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.19.0 + 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.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 3.3.0 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.16(webpack@5.97.1) + watchpack: 2.5.1 + webpack-sources: 3.3.4 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + whaileys@6.3.8(@adiwajshing/keyed-db@0.2.4)(jimp@1.6.0)(qrcode-terminal@0.12.0)(sharp@0.33.3): + dependencies: + '@hapi/boom': 9.1.4 + axios: 0.24.0 + futoin-hkdf: 1.5.3 + libsignal: https://codeload.github.com/canove/libsignal-node/tar.gz/105ad38dc8d7668b5d5e3688e710915bef5cdc7f + lodash: 4.17.21 + music-metadata: 7.14.0 + node-cache: 5.1.2 + pino: 7.11.0 + protobufjs: 7.2.6 + protobufjs-cli: 1.2.0(protobufjs@7.2.6) + ws: 8.18.0 + optionalDependencies: + '@adiwajshing/keyed-db': 0.2.4 + jimp: 1.6.0 + qrcode-terminal: 0.12.0 + sharp: 0.33.3 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + win-guid@0.2.1: {} + + 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.3 + string-width: 5.1.2 + strip-ansi: 7.1.2 + + wrappy@1.0.2: {} + + ws@8.18.0: {} + + xml-parse-from-string@1.0.1: {} + + xml2js@0.5.0: + dependencies: + sax: 1.4.4 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + xmlcreate@2.0.4: {} + + xtend@4.0.2: {} + + yallist@4.0.0: {} + + yargs-parser@21.1.1: {} + + yocto-queue@0.1.0: {} + + zod@3.25.76: {} diff --git a/bot-wsp/pnpm-workspace.yaml b/bot-wsp/pnpm-workspace.yaml new file mode 100644 index 0000000..a3cffbf --- /dev/null +++ b/bot-wsp/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +patchedDependencies: + '@builderbot/provider-baileys@1.3.15': patches/@builderbot__provider-baileys@1.3.15.patch diff --git a/bot-wsp/prisma/migrations/20250629003805_init/migration.sql b/bot-wsp/prisma/migrations/20250629003805_init/migration.sql new file mode 100644 index 0000000..2855a24 --- /dev/null +++ b/bot-wsp/prisma/migrations/20250629003805_init/migration.sql @@ -0,0 +1,12 @@ +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); diff --git a/bot-wsp/prisma/migrations/20250629035045_add_phone_and_rfid/migration.sql b/bot-wsp/prisma/migrations/20250629035045_add_phone_and_rfid/migration.sql new file mode 100644 index 0000000..0270acf --- /dev/null +++ b/bot-wsp/prisma/migrations/20250629035045_add_phone_and_rfid/migration.sql @@ -0,0 +1,40 @@ +/* + Warnings: + + - You are about to drop the column `email` on the `User` table. All the data in the column will be lost. + - A unique constraint covering the columns `[phone]` on the table `User` will be added. If there are existing duplicate values, this will fail. + +*/ +-- CreateEnum +CREATE TYPE "UserRole" AS ENUM ('ADMIN', 'USER', 'GUEST'); + +-- CreateEnum +CREATE TYPE "LogDirection" AS ENUM ('INGRESS', 'EGRESS'); + +-- DropIndex +DROP INDEX "User_email_key"; + +-- AlterTable +ALTER TABLE "User" DROP COLUMN "email", +ADD COLUMN "phone" TEXT, +ADD COLUMN "rfid" TEXT, +ADD COLUMN "role" "UserRole" NOT NULL DEFAULT 'USER'; + +-- CreateTable +CREATE TABLE "AccessLog" ( + "id" SERIAL NOT NULL, + "userId" INTEGER NOT NULL, + "direction" "LogDirection" NOT NULL, + "timestamp" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "AccessLog_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE INDEX "AccessLog_userId_timestamp_idx" ON "AccessLog"("userId", "timestamp"); + +-- CreateIndex +CREATE UNIQUE INDEX "User_phone_key" ON "User"("phone"); + +-- AddForeignKey +ALTER TABLE "AccessLog" ADD CONSTRAINT "AccessLog_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/bot-wsp/prisma/migrations/20251107234002_refactor_subscription_to_direct_invoice_relation/migration.sql b/bot-wsp/prisma/migrations/20251107234002_refactor_subscription_to_direct_invoice_relation/migration.sql new file mode 100644 index 0000000..0d6a50c --- /dev/null +++ b/bot-wsp/prisma/migrations/20251107234002_refactor_subscription_to_direct_invoice_relation/migration.sql @@ -0,0 +1,243 @@ +/* + Warnings: + + - The primary key for the `AccessLog` table will be changed. If it partially fails, the table could be left without primary key constraint. + - The primary key for the `User` table will be changed. If it partially fails, the table could be left without primary key constraint. + - Added the required column `customId` to the `User` table without a default value. This is not possible if the table is not empty. + - Made the column `name` on table `User` required. This step will fail if there are existing NULL values in that column. + +*/ +-- CreateEnum +CREATE TYPE "SessionType" AS ENUM ('RECURRING', 'ONE_TIME'); + +-- CreateEnum +CREATE TYPE "InvoiceStatus" AS ENUM ('PENDING', 'PAID', 'CANCELED'); + +-- AlterEnum +ALTER TYPE "UserRole" ADD VALUE 'INSTRUCTOR'; + +-- DropForeignKey +ALTER TABLE "AccessLog" DROP CONSTRAINT "AccessLog_userId_fkey"; + +-- DropIndex +DROP INDEX "User_phone_key"; + +-- AlterTable +ALTER TABLE "AccessLog" DROP CONSTRAINT "AccessLog_pkey", +ALTER COLUMN "id" DROP DEFAULT, +ALTER COLUMN "id" SET DATA TYPE TEXT, +ALTER COLUMN "userId" SET DATA TYPE TEXT, +ADD CONSTRAINT "AccessLog_pkey" PRIMARY KEY ("id"); +DROP SEQUENCE "AccessLog_id_seq"; + +-- AlterTable +ALTER TABLE "User" DROP CONSTRAINT "User_pkey", +ADD COLUMN "birth" TIMESTAMP(3), +ADD COLUMN "customId" TEXT NOT NULL, +ADD COLUMN "deleted" TIMESTAMP(3), +ADD COLUMN "dni" TEXT, +ALTER COLUMN "id" DROP DEFAULT, +ALTER COLUMN "id" SET DATA TYPE TEXT, +ALTER COLUMN "name" SET NOT NULL, +ADD CONSTRAINT "User_pkey" PRIMARY KEY ("id"); +DROP SEQUENCE "User_id_seq"; + +-- CreateTable +CREATE TABLE "Token" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "token" TEXT NOT NULL, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "redirectUrl" TEXT, + "expiresAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Token_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Session" ( + "id" TEXT NOT NULL, + "customId" TEXT NOT NULL, + "description" TEXT NOT NULL, + "type" "SessionType" NOT NULL, + "startDate" TIMESTAMP(3), + "endDate" TIMESTAMP(3), + "isActive" BOOLEAN NOT NULL DEFAULT true, + "amount" DOUBLE PRECISION, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Session_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "SessionPriceHistory" ( + "id" TEXT NOT NULL, + "sessionId" TEXT NOT NULL, + "amount" DOUBLE PRECISION NOT NULL, + "effectiveFrom" TIMESTAMP(3) NOT NULL, + "effectiveTo" TIMESTAMP(3), + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "SessionPriceHistory_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "SessionDateRange" ( + "id" TEXT NOT NULL, + "start" TIMESTAMP(3) NOT NULL, + "end" TIMESTAMP(3) NOT NULL, + "sessionId" TEXT NOT NULL, + + CONSTRAINT "SessionDateRange_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "SessionDateSnapshot" ( + "id" TEXT NOT NULL, + "dateRangeId" TEXT NOT NULL, + "sessionId" TEXT NOT NULL, + "notes" TEXT, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "SessionDateSnapshot_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Invoice" ( + "id" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "sessionId" TEXT NOT NULL, + "base64Invoice" TEXT, + "linkPayment" TEXT, + "status" "InvoiceStatus" NOT NULL DEFAULT 'PENDING', + "amount" DOUBLE PRECISION NOT NULL, + "dateInvoice" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Invoice_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "_InstructorSessions" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_InstructorSessions_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_AssistantSessions" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_AssistantSessions_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_SubstituteInstructorsOnDate" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_SubstituteInstructorsOnDate_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_PresentInstructorsOnDate" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_PresentInstructorsOnDate_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateTable +CREATE TABLE "_PresentAssistantsOnDate" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + + CONSTRAINT "_PresentAssistantsOnDate_AB_pkey" PRIMARY KEY ("A","B") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Token_token_key" ON "Token"("token"); + +-- CreateIndex +CREATE UNIQUE INDEX "Session_customId_key" ON "Session"("customId"); + +-- CreateIndex +CREATE INDEX "Invoice_userId_dateInvoice_idx" ON "Invoice"("userId", "dateInvoice"); + +-- CreateIndex +CREATE INDEX "Invoice_sessionId_dateInvoice_idx" ON "Invoice"("sessionId", "dateInvoice"); + +-- CreateIndex +CREATE INDEX "_InstructorSessions_B_index" ON "_InstructorSessions"("B"); + +-- CreateIndex +CREATE INDEX "_AssistantSessions_B_index" ON "_AssistantSessions"("B"); + +-- CreateIndex +CREATE INDEX "_SubstituteInstructorsOnDate_B_index" ON "_SubstituteInstructorsOnDate"("B"); + +-- CreateIndex +CREATE INDEX "_PresentInstructorsOnDate_B_index" ON "_PresentInstructorsOnDate"("B"); + +-- CreateIndex +CREATE INDEX "_PresentAssistantsOnDate_B_index" ON "_PresentAssistantsOnDate"("B"); + +-- AddForeignKey +ALTER TABLE "AccessLog" ADD CONSTRAINT "AccessLog_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Token" ADD CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "SessionPriceHistory" ADD CONSTRAINT "SessionPriceHistory_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Session"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "SessionDateRange" ADD CONSTRAINT "SessionDateRange_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Session"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "SessionDateSnapshot" ADD CONSTRAINT "SessionDateSnapshot_dateRangeId_fkey" FOREIGN KEY ("dateRangeId") REFERENCES "SessionDateRange"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "SessionDateSnapshot" ADD CONSTRAINT "SessionDateSnapshot_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Session"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Invoice" ADD CONSTRAINT "Invoice_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Invoice" ADD CONSTRAINT "Invoice_sessionId_fkey" FOREIGN KEY ("sessionId") REFERENCES "Session"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_InstructorSessions" ADD CONSTRAINT "_InstructorSessions_A_fkey" FOREIGN KEY ("A") REFERENCES "Session"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_InstructorSessions" ADD CONSTRAINT "_InstructorSessions_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_AssistantSessions" ADD CONSTRAINT "_AssistantSessions_A_fkey" FOREIGN KEY ("A") REFERENCES "Session"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_AssistantSessions" ADD CONSTRAINT "_AssistantSessions_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_SubstituteInstructorsOnDate" ADD CONSTRAINT "_SubstituteInstructorsOnDate_A_fkey" FOREIGN KEY ("A") REFERENCES "SessionDateSnapshot"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_SubstituteInstructorsOnDate" ADD CONSTRAINT "_SubstituteInstructorsOnDate_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PresentInstructorsOnDate" ADD CONSTRAINT "_PresentInstructorsOnDate_A_fkey" FOREIGN KEY ("A") REFERENCES "SessionDateSnapshot"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PresentInstructorsOnDate" ADD CONSTRAINT "_PresentInstructorsOnDate_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PresentAssistantsOnDate" ADD CONSTRAINT "_PresentAssistantsOnDate_A_fkey" FOREIGN KEY ("A") REFERENCES "SessionDateSnapshot"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "_PresentAssistantsOnDate" ADD CONSTRAINT "_PresentAssistantsOnDate_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/bot-wsp/prisma/migrations/20251118231129_add_profile_picture_and_config/migration.sql b/bot-wsp/prisma/migrations/20251118231129_add_profile_picture_and_config/migration.sql new file mode 100644 index 0000000..ccb5ad3 --- /dev/null +++ b/bot-wsp/prisma/migrations/20251118231129_add_profile_picture_and_config/migration.sql @@ -0,0 +1,18 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "profilePicture" TEXT, +ADD COLUMN "profilePictureUpdatedAt" TIMESTAMP(3), +ALTER COLUMN "customId" DROP NOT NULL; + +-- CreateTable +CREATE TABLE "SystemConfig" ( + "id" TEXT NOT NULL, + "sessionCleanupIntervalMinutes" INTEGER NOT NULL DEFAULT 30, + "invoiceGenerationDayOfMonth" INTEGER NOT NULL DEFAULT 1, + "tokenExpirationMinutes" INTEGER NOT NULL DEFAULT 30, + "tokenCleanupIntervalMinutes" INTEGER NOT NULL DEFAULT 60, + "profilePictureUpdateIntervalDays" INTEGER NOT NULL DEFAULT 2, + "updatedAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "SystemConfig_pkey" PRIMARY KEY ("id") +); diff --git a/bot-wsp/prisma/migrations/migration_lock.toml b/bot-wsp/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..044d57c --- /dev/null +++ b/bot-wsp/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/bot-wsp/prisma/schema.prisma b/bot-wsp/prisma/schema.prisma new file mode 100644 index 0000000..344388b --- /dev/null +++ b/bot-wsp/prisma/schema.prisma @@ -0,0 +1,159 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +/// Un ejemplo de modelo "User" +model User { + id String @id @default(cuid()) + customId String? + name String + dni String? + phone String? + birth DateTime? + rfid String? + deleted DateTime? + role UserRole @default(USER) + profilePicture String? + profilePictureUpdatedAt DateTime? + createdAt DateTime @default(now()) + AccessLog AccessLog[] + invoices Invoice[] + tokens Token[] + assistantSessions Session[] @relation("AssistantSessions") + instructorSessions Session[] @relation("InstructorSessions") + presentAssistantsOnDates SessionDateSnapshot[] @relation("PresentAssistantsOnDate") + presentInstructorsOnDates SessionDateSnapshot[] @relation("PresentInstructorsOnDate") + SessionDateSnapshot SessionDateSnapshot[] @relation("SubstituteInstructorsOnDate") +} + +/// Registro de acceso de un usuario +model AccessLog { + id String @id @default(cuid()) + userId String + direction LogDirection + timestamp DateTime @default(now()) + user User @relation(fields: [userId], references: [id]) + + @@index([userId, timestamp]) +} + +model Token { + id String @id @default(cuid()) + userId String? + token String @unique + isActive Boolean @default(true) + redirectUrl String? + expiresAt DateTime + createdAt DateTime @default(now()) + user User? @relation(fields: [userId], references: [id]) +} + +model Session { + id String @id @default(cuid()) + customId String @unique + description String + type SessionType + startDate DateTime? + endDate DateTime? + isActive Boolean @default(true) + amount Float? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + invoices Invoice[] + dates SessionDateRange[] + SessionDateSnapshot SessionDateSnapshot[] + priceHistories SessionPriceHistory[] + assistants User[] @relation("AssistantSessions") + instructors User[] @relation("InstructorSessions") +} + +model SessionPriceHistory { + id String @id @default(cuid()) + sessionId String + amount Float + effectiveFrom DateTime + effectiveTo DateTime? + createdAt DateTime @default(now()) + session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade) +} + +model SessionDateRange { + id String @id @default(cuid()) + start DateTime + end DateTime + sessionId String + session Session @relation(fields: [sessionId], references: [id], onDelete: Cascade) + SessionDateSnapshot SessionDateSnapshot[] +} + +model SessionDateSnapshot { + id String @id @default(cuid()) + dateRangeId String + sessionId String + notes String? + isActive Boolean @default(true) + createdAt DateTime @default(now()) + dateRange SessionDateRange @relation(fields: [dateRangeId], references: [id]) + session Session @relation(fields: [sessionId], references: [id]) + presentAssistants User[] @relation("PresentAssistantsOnDate") + presentInstructors User[] @relation("PresentInstructorsOnDate") + substituteInstructors User[] @relation("SubstituteInstructorsOnDate") +} + +model Invoice { + id String @id @default(cuid()) + userId String + sessionId String + base64Invoice String? + linkPayment String? + status InvoiceStatus @default(PENDING) + amount Float + dateInvoice DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + session Session @relation(fields: [sessionId], references: [id]) + user User @relation(fields: [userId], references: [id]) + + @@index([userId, dateInvoice]) + @@index([sessionId, dateInvoice]) +} + +model SystemConfig { + id String @id @default(cuid()) + sessionCleanupIntervalMinutes Int @default(30) + invoiceGenerationDayOfMonth Int @default(1) + tokenExpirationMinutes Int @default(30) + tokenCleanupIntervalMinutes Int @default(60) + profilePictureUpdateIntervalDays Int @default(2) + updatedAt DateTime @updatedAt + createdAt DateTime @default(now()) +} + +enum UserRole { + ADMIN + INSTRUCTOR + USER + GUEST +} + +/// Dirección de un registro (INGRESO o EGRESO) +enum LogDirection { + INGRESS + EGRESS +} + +enum SessionType { + RECURRING + ONE_TIME +} + +enum InvoiceStatus { + PENDING + PAID + CANCELED +} diff --git a/bot-wsp/rollup.config.js b/bot-wsp/rollup.config.js new file mode 100644 index 0000000..6de1ab0 --- /dev/null +++ b/bot-wsp/rollup.config.js @@ -0,0 +1,13 @@ +import typescript from 'rollup-plugin-typescript2' + +export default { + input: 'src/app.ts', + output: { + file: 'dist/app.js', + format: 'esm', + }, + onwarn: (warning) => { + if (warning.code === 'UNRESOLVED_IMPORT') return + }, + plugins: [typescript()], +} diff --git a/bot-wsp/sketchesp32.txt b/bot-wsp/sketchesp32.txt new file mode 100644 index 0000000..7616468 --- /dev/null +++ b/bot-wsp/sketchesp32.txt @@ -0,0 +1,67 @@ +#include +#include +#include +#include + +#define SS_PIN 21 // GPIO21 para SS (SDA) +#define RST_PIN 22 // GPIO22 para RST +MFRC522 rfid(SS_PIN, RST_PIN); + +const char* ssid = "Personal-915-2.4GHz"; +const char* password = "00439028922"; + +const char* post_url = "http://localhost:3000/rfid/ping"; + +void setup() { + Serial.begin(115200); + SPI.begin(18, 19, 23); // SCK, MISO, MOSI (GPIO18,19,23) + + WiFi.begin(ssid, password); + Serial.print("Conectando a WiFi..."); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + } + Serial.println("\nWiFi conectado."); + + rfid.PCD_Init(); + Serial.println("Lector RFID listo."); +} + +void loop() { + if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) { + delay(100); + return; + } + + // Leer UID + String uid = ""; + for (byte i = 0; i < rfid.uid.size; i++) { + uid += String(rfid.uid.uidByte[i] < 0x10 ? "0" : ""); + uid += String(rfid.uid.uidByte[i], HEX); + } + uid.toUpperCase(); // Ej: B31D7313 + Serial.println("UID detectado: " + uid); + + // Enviar POST + if (WiFi.status() == WL_CONNECTED) { + HTTPClient http; + http.begin(post_url); + http.addHeader("Content-Type", "application/json"); + + String jsonBody = "{\"id\": \"" + uid + "\"}"; + Serial.println("Enviando POST: " + jsonBody); + int httpResponseCode = http.POST(jsonBody); + + Serial.printf("Código de respuesta: %d\n", httpResponseCode); + String payload = http.getString(); + Serial.println("Respuesta: " + payload); + http.end(); + } else { + Serial.println("WiFi no conectado."); + } + + rfid.PICC_HaltA(); // Detener comunicación + rfid.PCD_StopCrypto1(); + delay(2000); // Esperar antes de siguiente lectura +} \ No newline at end of file diff --git a/bot-wsp/src/app.module.ts b/bot-wsp/src/app.module.ts new file mode 100644 index 0000000..d693b24 --- /dev/null +++ b/bot-wsp/src/app.module.ts @@ -0,0 +1,56 @@ +import { Module } from '@nestjs/common'; +import { WhatsappModule } from './whatsapp/whatsapp.module.js'; +import { UserModule } from './user/user.module.js'; +import { PrismaModule } from './prisma/prisma.module.js'; +import { RfidModule } from './rfid/rfid.module'; +import { AttendanceModule } from './attendance/attendance.module'; +import { SessionsModule } from './sessions/sessions.module'; +import { IaModule } from './ia/ia.module'; +import { CustomIdModule } from './custom-id/custom-id.module'; +import { OdooModule } from './odoo/odoo.module'; +import { AuthModule } from './auth/auth.module'; +import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler'; +import { APP_GUARD } from '@nestjs/core'; +import { InvoicesModule } from './invoices/invoices.module'; +import { DashboardModule } from './dashboard/dashboard.module'; +import { SubscriptionsModule } from './subscriptions/subscriptions.module'; +import { BackupModule } from './backup/backup.module'; +import { SchedulingModule } from './scheduling/scheduling.module'; +import { SystemConfigModule } from './common/system-config.module'; + + +@Module({ + imports: [ + ThrottlerModule.forRoot({ + throttlers: [ + { + ttl: 60, // Tiempo en segundos + limit: 5, // Máximo 5 requests por IP + }, + ], + }), + PrismaModule, + WhatsappModule, + UserModule, + RfidModule, + AttendanceModule, + SessionsModule, + IaModule, + CustomIdModule, + OdooModule, + AuthModule, + InvoicesModule, + DashboardModule, + SubscriptionsModule, + BackupModule, + SchedulingModule, + SystemConfigModule, + ], + providers: [ + { + provide: APP_GUARD, + useClass: ThrottlerGuard, + }, + ] +}) +export class AppModule { } diff --git a/bot-wsp/src/attendance/attendance.controller.spec.ts b/bot-wsp/src/attendance/attendance.controller.spec.ts new file mode 100644 index 0000000..d81b279 --- /dev/null +++ b/bot-wsp/src/attendance/attendance.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AttendanceController } from './attendance.controller'; +import { AttendanceService } from './attendance.service'; + +describe('AttendanceController', () => { + let controller: AttendanceController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [AttendanceController], + providers: [AttendanceService], + }).compile(); + + controller = module.get(AttendanceController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/attendance/attendance.controller.ts b/bot-wsp/src/attendance/attendance.controller.ts new file mode 100644 index 0000000..4bd4767 --- /dev/null +++ b/bot-wsp/src/attendance/attendance.controller.ts @@ -0,0 +1,52 @@ +import { Controller, ForbiddenException, Get, Param, Put, Query, UseGuards } from '@nestjs/common'; +import { UserRole } from '@prisma/client'; +import { User } from '~/common/decoratos/user.decorator'; +import { AuthTokenGuard } from '~/common/guards/auth-token.guard'; +import { AuthUser } from '~/common/types'; +import { AttendanceService } from './attendance.service'; + +@Controller('attendance') +@UseGuards(AuthTokenGuard) +export class AttendanceController { + constructor(private readonly attendanceService: AttendanceService) { } + + @Get() + async getAccessLogsByDate( + @Query('userId') userId: string, + @Query('date') date: string, + @User() user: AuthUser, + ) { + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR || user?.id === userId; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para ver esta información'); + } + + if (!userId || !date) { + throw new Error('userId and date are required'); + } + + return await this.attendanceService.getAccessLogsByDate(userId, date); + } + + @Put('/:userId/:snapshotId') + async updateAttendanceSnapshot( + @Param('userId') userId: string, + @Param('snapshotId') snapshotId: string, + @Query('unmark') unmark: string | undefined, + @User() user: AuthUser, + ) { + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para actualizar asistencias'); + } + + const shouldUnmark = unmark === 'true'; + + if (shouldUnmark) { + return await this.attendanceService.unmarkAttendance(userId, snapshotId); + } else { + return await this.attendanceService.markAttendance(userId, snapshotId); + } + } + +} diff --git a/bot-wsp/src/attendance/attendance.module.ts b/bot-wsp/src/attendance/attendance.module.ts new file mode 100644 index 0000000..ba82c8d --- /dev/null +++ b/bot-wsp/src/attendance/attendance.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { AttendanceService } from './attendance.service'; +import { AttendanceController } from './attendance.controller'; +import { PrismaModule } from '../prisma/prisma.module'; +import { InvoicesModule } from '../invoices/invoices.module'; + +@Module({ + controllers: [AttendanceController], + providers: [AttendanceService], + imports: [PrismaModule, InvoicesModule], + exports: [AttendanceService], +}) +export class AttendanceModule {} diff --git a/bot-wsp/src/attendance/attendance.service.spec.ts b/bot-wsp/src/attendance/attendance.service.spec.ts new file mode 100644 index 0000000..c72a59c --- /dev/null +++ b/bot-wsp/src/attendance/attendance.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { AttendanceService } from './attendance.service'; + +describe('AttendanceService', () => { + let service: AttendanceService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AttendanceService], + }).compile(); + + service = module.get(AttendanceService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/attendance/attendance.service.ts b/bot-wsp/src/attendance/attendance.service.ts new file mode 100644 index 0000000..9cac2ad --- /dev/null +++ b/bot-wsp/src/attendance/attendance.service.ts @@ -0,0 +1,414 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { AccessLog, LogDirection } from '@prisma/client'; +import dayjs from 'dayjs'; +import { PrismaService } from '../prisma/prisma.service'; + +@Injectable() +export class AttendanceService { + private logger = new Logger(AttendanceService.name); + constructor(private prisma: PrismaService) { } + + + /** + * Registra un ingreso o egreso alternando según el último registro del día. + */ + async logAccess(userId: string): Promise { + const startOfDay = dayjs().startOf('day').toDate(); + const endOfDay = dayjs().endOf('day').toDate(); + const timestamp = new Date(); + + // 2) Buscamos el último log de hoy + const lastLog = await this.prisma.accessLog.findFirst({ + where: { + userId, + timestamp: { + gte: startOfDay, + lte: endOfDay, + }, + }, + orderBy: { timestamp: 'desc' }, + }); + + // 3) Inferimos la dirección + const direction: LogDirection = + lastLog?.direction === LogDirection.INGRESS + ? LogDirection.EGRESS + : LogDirection.INGRESS; + + // 4) Creamos el registro + const accesLog = await this.prisma.accessLog.create({ + data: { userId, direction, timestamp }, + }); + + // 5) Si es un INGRESS, intentar marcar asistencia automáticamente + if (direction === LogDirection.INGRESS) { + await this.autoMarkAttendance(userId, timestamp); + } + + return accesLog + } + + /** + * Marca automáticamente la asistencia cuando un usuario hace INGRESS. + * Busca sesiones activas (como asistente o instructor) dentro de una ventana de ±1 hora. + * @param userId ID del usuario + * @param timestamp Momento del ingreso + */ + private async autoMarkAttendance(userId: string, timestamp: Date): Promise { + try { + // Ventana de ±1 hora + const oneHourBefore = dayjs(timestamp).subtract(1, 'hour').toDate(); + const oneHourAfter = dayjs(timestamp).add(1, 'hour').toDate(); + + // Buscar snapshots activos donde: + // 1. El dateRange.start <= oneHourAfter + // 2. El dateRange.end >= oneHourBefore + // 3. El usuario es asistente o instructor de la sesión + const candidateSnapshots = await this.prisma.sessionDateSnapshot.findMany({ + where: { + isActive: true, + dateRange: { + start: { lte: oneHourAfter }, + end: { gte: oneHourBefore } + }, + session: { + OR: [ + { assistants: { some: { id: userId } } }, + { instructors: { some: { id: userId } } } + ] + } + }, + include: { + session: { + include: { + assistants: { where: { id: userId }, select: { id: true } }, + instructors: { where: { id: userId }, select: { id: true } } + } + }, + presentAssistants: { where: { id: userId }, select: { id: true } }, + presentInstructors: { where: { id: userId }, select: { id: true } } + } + }); + + if (candidateSnapshots.length === 0) { + this.logger.log(`No active snapshots found for user ${userId} within ±1 hour window`); + return; + } + + // Marcar en cada snapshot encontrado + for (const snapshot of candidateSnapshots) { + const isAlreadyMarked = + snapshot.presentAssistants.length > 0 || + snapshot.presentInstructors.length > 0; + + if (isAlreadyMarked) { + this.logger.log(`User ${userId} already marked in snapshot ${snapshot.id} - skipping`); + continue; + } + + // Determinar si es instructor o asistente en esta sesión + const isInstructor = snapshot.session.instructors.length > 0; + const isAssistant = snapshot.session.assistants.length > 0; + + if (isInstructor) { + await this.prisma.sessionDateSnapshot.update({ + where: { id: snapshot.id }, + data: { + presentInstructors: { + connect: { id: userId } + } + } + }); + this.logger.log(`Auto-marked user ${userId} as instructor in snapshot ${snapshot.id}`); + } else if (isAssistant) { + await this.prisma.sessionDateSnapshot.update({ + where: { id: snapshot.id }, + data: { + presentAssistants: { + connect: { id: userId } + } + } + }); + this.logger.log(`Auto-marked user ${userId} as assistant in snapshot ${snapshot.id}`); + } + } + + } catch (error: any) { + this.logger.error(`Error in autoMarkAttendance for user ${userId}: ${error.message}`, error.stack); + // No lanzamos el error para no interrumpir el flujo del logAccess + } + } + + /** + * Obtiene los últimos N registros de acceso de un usuario. + * @param userId ID del usuario + * @param limit Número máximo de registros a devolver (por defecto 5) + */ + async getLastAccesses( + userId: string, + limit = 5, + ): Promise { + return this.prisma.accessLog.findMany({ + where: { userId }, + orderBy: { timestamp: 'desc' }, + take: limit, + }); + } + + async attendanceSnapshotSession(userId: string) { + const lastAccesses = await this.getLastAccesses(userId); + // Aquí puedes agregar lógica adicional para crear un snapshot de la asistencia + return lastAccesses; + } + + /** + * Obtiene todos los registros de acceso de un usuario en una fecha específica + * @param userId ID del usuario + * @param date Fecha en formato ISO string + * @returns Objeto con información del usuario y sus registros de acceso + */ + async getAccessLogsByDate(userId: string, date: string) { + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + select: { id: true, name: true } + }); + + if (!user) { + throw new Error('User not found'); + } + + const targetDate = dayjs(date); + const startOfDay = targetDate.startOf('day').toDate(); + const endOfDay = targetDate.endOf('day').toDate(); + + const accessLogs = await this.prisma.accessLog.findMany({ + where: { + userId, + timestamp: { + gte: startOfDay, + lte: endOfDay + } + }, + orderBy: { timestamp: 'asc' } + }); + + return { + userId: user.id, + name: user.name, + accessLogs + }; + } + + async updateAttendanceSnapshot(userId: string, snapShotId: string) { + try { + + const user = await this.prisma.user.findUnique({ where: { id: userId } }); + if (!user) { + throw new Error(`User not found`); + } + const snapshot = await this.prisma.sessionDateSnapshot.findUnique({ where: { id: snapShotId } }); + + if (!snapshot) { + throw new Error(`Snapshot not found`); + } + + const updatedSnapshot = await this.prisma.sessionDateSnapshot.update({ + where: { id: snapShotId }, + data: { + presentAssistants: { + connect: { + id: userId + } + } + }, + }); + + return !!updatedSnapshot; + } + catch (error: any) { + this.logger.error(`Error updating attendance snapshot: ${error.message}`); + throw new Error(`Error updating attendance snapshot: ${error.message}`); + + } + } + + /** + * Marca la asistencia de un usuario en un snapshot específico + * @param userId ID del usuario + * @param snapshotId ID del snapshot de sesión + * @returns Objeto con el estado de la operación + */ + async markAttendance(userId: string, snapshotId: string) { + try { + // Verificar que el usuario existe + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + select: { id: true, name: true, role: true } + }); + + if (!user) { + this.logger.warn(`Attempt to mark attendance for non-existent user: ${userId}`); + throw new Error('User not found'); + } + + // Verificar que el snapshot existe y obtener información de asistentes presentes + const snapshot = await this.prisma.sessionDateSnapshot.findUnique({ + where: { id: snapshotId }, + include: { + presentAssistants: { select: { id: true } }, + presentInstructors: { select: { id: true } } + } + }); + + if (!snapshot) { + this.logger.warn(`Attempt to mark attendance for non-existent snapshot: ${snapshotId}`); + throw new Error('Snapshot not found'); + } + + // Verificar si el usuario ya está marcado como presente + const isAssistantPresent = snapshot.presentAssistants.some(a => a.id === userId); + const isInstructorPresent = snapshot.presentInstructors.some(i => i.id === userId); + const isAlreadyMarked = isAssistantPresent || isInstructorPresent; + + if (isAlreadyMarked) { + this.logger.log(`User ${userId} already marked as present in snapshot ${snapshotId} - idempotent behavior`); + return { + status: 'marked', + userId, + snapshotId, + message: 'User already marked as present', + alreadyMarked: true + }; + } + + // Determinar si es instructor o asistente basado en el rol + if (user.role === 'INSTRUCTOR' || user.role === 'ADMIN') { + await this.prisma.sessionDateSnapshot.update({ + where: { id: snapshotId }, + data: { + presentInstructors: { + connect: { id: userId } + } + } + }); + this.logger.log(`Instructor ${userId} marked as present in snapshot ${snapshotId}`); + } else { + await this.prisma.sessionDateSnapshot.update({ + where: { id: snapshotId }, + data: { + presentAssistants: { + connect: { id: userId } + } + } + }); + this.logger.log(`Assistant ${userId} marked as present in snapshot ${snapshotId}`); + } + + return { + status: 'marked', + userId, + snapshotId, + message: 'Attendance marked successfully', + alreadyMarked: false + }; + + } catch (error: any) { + this.logger.error(`Error marking attendance: ${error.message}`, error.stack); + throw error; + } + } + + /** + * Desmarca la asistencia de un usuario en un snapshot específico + * @param userId ID del usuario + * @param snapshotId ID del snapshot de sesión + * @returns Objeto con el estado de la operación + */ + async unmarkAttendance(userId: string, snapshotId: string) { + try { + // Verificar que el usuario existe + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + select: { id: true, name: true, role: true } + }); + + if (!user) { + this.logger.warn(`Attempt to unmark attendance for non-existent user: ${userId}`); + throw new Error('User not found'); + } + + // Verificar que el snapshot existe y obtener información de asistentes presentes + const snapshot = await this.prisma.sessionDateSnapshot.findUnique({ + where: { id: snapshotId }, + include: { + presentAssistants: { select: { id: true } }, + presentInstructors: { select: { id: true } } + } + }); + + if (!snapshot) { + this.logger.warn(`Attempt to unmark attendance for non-existent snapshot: ${snapshotId}`); + throw new Error('Snapshot not found'); + } + + // Verificar si el usuario está marcado como presente + const isAssistantPresent = snapshot.presentAssistants.some(a => a.id === userId); + const isInstructorPresent = snapshot.presentInstructors.some(i => i.id === userId); + const isMarked = isAssistantPresent || isInstructorPresent; + + if (!isMarked) { + this.logger.log(`User ${userId} not marked as present in snapshot ${snapshotId} - idempotent behavior`); + return { + status: 'unmarked', + userId, + snapshotId, + message: 'User was not marked as present', + wasMarked: false + }; + } + + // Desconectar de la relación correspondiente usando set con el array filtrado + if (isInstructorPresent) { + const remainingInstructors = snapshot.presentInstructors + .filter(i => i.id !== userId) + .map(i => ({ id: i.id })); + + await this.prisma.sessionDateSnapshot.update({ + where: { id: snapshotId }, + data: { + presentInstructors: { + set: remainingInstructors + } + } + }); + this.logger.log(`Instructor ${userId} unmarked from snapshot ${snapshotId}`); + } else { + const remainingAssistants = snapshot.presentAssistants + .filter(a => a.id !== userId) + .map(a => ({ id: a.id })); + + await this.prisma.sessionDateSnapshot.update({ + where: { id: snapshotId }, + data: { + presentAssistants: { + set: remainingAssistants + } + } + }); + this.logger.log(`Assistant ${userId} unmarked from snapshot ${snapshotId}`); + } + + return { + status: 'unmarked', + userId, + snapshotId, + message: 'Attendance unmarked successfully', + wasMarked: true + }; + + } catch (error: any) { + this.logger.error(`Error unmarking attendance: ${error.message}`, error.stack); + throw error; + } + } +} diff --git a/bot-wsp/src/attendance/dto/create-attendance.dto.ts b/bot-wsp/src/attendance/dto/create-attendance.dto.ts new file mode 100644 index 0000000..8da6aa9 --- /dev/null +++ b/bot-wsp/src/attendance/dto/create-attendance.dto.ts @@ -0,0 +1 @@ +export class CreateAttendanceDto {} diff --git a/bot-wsp/src/attendance/dto/update-attendance.dto.ts b/bot-wsp/src/attendance/dto/update-attendance.dto.ts new file mode 100644 index 0000000..112dde9 --- /dev/null +++ b/bot-wsp/src/attendance/dto/update-attendance.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateAttendanceDto } from './create-attendance.dto'; + +export class UpdateAttendanceDto extends PartialType(CreateAttendanceDto) {} diff --git a/bot-wsp/src/attendance/entities/attendance.entity.ts b/bot-wsp/src/attendance/entities/attendance.entity.ts new file mode 100644 index 0000000..5a53d68 --- /dev/null +++ b/bot-wsp/src/attendance/entities/attendance.entity.ts @@ -0,0 +1 @@ +export class Attendance {} diff --git a/bot-wsp/src/auth/auth.controller.ts b/bot-wsp/src/auth/auth.controller.ts new file mode 100644 index 0000000..6a546d0 --- /dev/null +++ b/bot-wsp/src/auth/auth.controller.ts @@ -0,0 +1,35 @@ +import { Controller, Get, NotFoundException, Query, Res } from '@nestjs/common'; +import { Response } from 'express'; +import { AuthService } from './auth.service'; +import { Inject, forwardRef } from '@nestjs/common'; +import { WhatsappService } from '../whatsapp/whatsapp.service'; + +@Controller('auth') +export class AuthController { + constructor( + private readonly authService: AuthService, + @Inject(forwardRef(() => WhatsappService)) + private readonly whatsappService: WhatsappService, + ) { } + + @Get('verify') + verificar(@Query('t') token: string) { + return this.authService.verificarToken(token); + } + + @Get('getToken') + async getToken() { + if (process.env.NODE_ENV === 'production') { + throw new NotFoundException(); + } + return await this.authService.getTokenDev(); + } + + @Get('init') + async redirectDynamic(@Res() res: Response) { + const whatsappStatus = await this.whatsappService.status().catch(() => null); + return await this.authService.init(res, whatsappStatus?.status ?? null); + } +} + +//650030 \ No newline at end of file diff --git a/bot-wsp/src/auth/auth.module.ts b/bot-wsp/src/auth/auth.module.ts new file mode 100644 index 0000000..70736fc --- /dev/null +++ b/bot-wsp/src/auth/auth.module.ts @@ -0,0 +1,33 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { JwtModule } from '@nestjs/jwt'; +import { PrismaModule } from '../prisma/prisma.module'; +import { SystemConfigModule } from '../common/system-config.module'; +import { SystemConfigService } from '../common/system-config.service'; +import { AuthController } from './auth.controller'; +import { AuthService } from './auth.service'; +import { WhatsappModule } from '../whatsapp/whatsapp.module'; + +@Module({ + controllers: [AuthController], + providers: [AuthService], + imports: [ + JwtModule.registerAsync({ + imports: [SystemConfigModule], + useFactory: async (systemConfig: SystemConfigService) => { + // Esperar a que se cargue la configuración + await new Promise(resolve => setTimeout(resolve, 100)); + const expirationMinutes = systemConfig.getTokenExpirationMinutes(); + return { + secret: process.env.SECRET_JWT, + signOptions: { expiresIn: `${expirationMinutes}m` }, + }; + }, + inject: [SystemConfigService], + }), + PrismaModule, + SystemConfigModule, + forwardRef(() => WhatsappModule), + ], + exports: [AuthService], +}) +export class AuthModule { } diff --git a/bot-wsp/src/auth/auth.service.ts b/bot-wsp/src/auth/auth.service.ts new file mode 100644 index 0000000..8c3bde9 --- /dev/null +++ b/bot-wsp/src/auth/auth.service.ts @@ -0,0 +1,142 @@ +import { forwardRef, Inject, Injectable, InternalServerErrorException, Logger } from '@nestjs/common'; +import { User } from '@prisma/client'; +import { customAlphabet } from 'nanoid'; +import { PrismaService } from '../prisma/prisma.service'; +import { SystemConfigService } from '../common/system-config.service'; +import { Response } from 'express'; + +export enum TokenRedirectURL { + FRONT = 'FRONT', + SESSION = 'SESSION', + USER = 'USER', + WHATSAPP = 'WHATSAPP', + CONFIG = 'CONFIG', +} + +const RedirectToUrlParams = { + [TokenRedirectURL.FRONT]: '/', + [TokenRedirectURL.SESSION]: 'clases', + [TokenRedirectURL.USER]: 'usuarios', + [TokenRedirectURL.WHATSAPP]: 'whatsapp', + [TokenRedirectURL.CONFIG]: 'configuracion/sistema', +}; + +@Injectable() +export class AuthService { + private readonly nanoid = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 10); + + private readonly logger = new Logger(AuthService.name); + + constructor( + private prisma: PrismaService, + @Inject(forwardRef(() => SystemConfigService)) + private systemConfig: SystemConfigService + ) { } + + async getTokenDev() { + try { + const user = await this.prisma.user.findFirst({ + where: { + role: 'ADMIN', + phone: { not: null } + } + }); + return await this.generarToken(user?.id, TokenRedirectURL.SESSION); + } + catch (error: any) { + + } + } + getLoginLink(user: User): Promise { + return this.generarToken(user.id).then(token => `${process.env.URL_FRONT}?t=${token}`); + } + + //NOTE duration opcional para el primer arranque , MINUTOS + async generarToken(userId?: string, redirectUrl?: TokenRedirectURL, duration?: number): Promise { + try { + + + const now = Date.now(); + + // Buscar token activo existente + const existing = userId ? await this.prisma.token.findFirst({ + where: { + userId, + expiresAt: { gt: new Date(now) }, + isActive: { equals: true } + }, + }) + : false + + if (existing) { + return existing.token; + } + + // Si no hay uno válido, crear uno nuevo + const token = this.nanoid(); + const expirationMinutes = this.systemConfig.getTokenExpirationMinutes(); + const expiresAt = new Date(now + (duration ?? expirationMinutes) * 60 * 1000); + + await this.prisma.token.create({ + data: { + token, + userId, + expiresAt, + ...(redirectUrl + ? { redirectUrl: RedirectToUrlParams[redirectUrl] } + : { redirectUrl: RedirectToUrlParams[TokenRedirectURL.FRONT] }) + }, + }); + + return token; + } + catch (error: any) { + this.logger.error('Error generating token', error); + throw new InternalServerErrorException('Error generating token'); + } + } + + + async verificarToken(token: string): Promise<{ autorizado: boolean; user?: User, redirectUrl?: string }> { + try { + const found = await this.prisma.token.findUnique({ + where: { token, isActive: { equals: true } }, + include: { user: true }, + }); + + if (!found) return { autorizado: false }; + + const expired = new Date() > found.expiresAt; + if (expired) return { autorizado: false }; + + await this.prisma.token.update({ where: { id: found.id }, data: { isActive: false } }); + return { autorizado: true, user: found?.user || undefined, redirectUrl: found.redirectUrl! }; + } catch { + return { autorizado: false }; + } + } + + async init(res: Response, whatsappStatus?: 'Correcto' | 'Sin session' | null) { + try { + // Caso 1: primera vez que arranca el sistema (admin creado, token listo) + const firstUrl = this.systemConfig.getFirstUrl(); + if (firstUrl) { + return res.redirect(302, firstUrl); + } + + // Caso 2: WhatsApp sin sesión → redirigir al front en la sección de WhatsApp + if (whatsappStatus === 'Sin session') { + const admin = await this.prisma.user.findFirst({ where: { role: 'ADMIN' } }); + const token = await this.generarToken(admin?.id, TokenRedirectURL.WHATSAPP); + return res.redirect(302, `${process.env.URL_FRONT}?t=${token}`); + } + + + // Caso 3: sistema normal no dar acceso + return res.sendStatus(403); + } catch (error: any) { + this.logger.error('Error in init', error); + return res.sendStatus(500); + } + } +} diff --git a/bot-wsp/src/backup/backup.controller.ts b/bot-wsp/src/backup/backup.controller.ts new file mode 100644 index 0000000..55e059e --- /dev/null +++ b/bot-wsp/src/backup/backup.controller.ts @@ -0,0 +1,254 @@ +import { + Controller, + Get, + Post, + Res, + UseGuards, + ForbiddenException, + InternalServerErrorException, + Logger, + UseInterceptors, + UploadedFile, + BadRequestException +} from '@nestjs/common'; +import { Response } from 'express'; +import { FileInterceptor } from '@nestjs/platform-express'; +import { diskStorage } from 'multer'; +import * as path from 'path'; +import { BackupService } from './backup.service'; +import { AuthTokenGuard } from '~/common/guards/auth-token.guard'; +import { User } from '~/common/decoratos/user.decorator'; +import { AuthUser } from '~/common/types'; +import { UserRole } from '@prisma/client'; +import * as fs from 'fs'; +import { AuthService, TokenRedirectURL } from '~/auth/auth.service'; + +@Controller('backup') +@UseGuards(AuthTokenGuard) +export class BackupController { + private readonly logger = new Logger(BackupController.name); + + constructor( + private readonly backupService: BackupService, + private readonly authService: AuthService + ) { } + + @Get('download') + async downloadBackup( + @User() user: AuthUser, + @Res() res: Response, + ): Promise { + // Solo administradores pueden descargar backups + if (user?.role !== UserRole.ADMIN) { + throw new ForbiddenException('Solo los administradores pueden descargar backups'); + } + + let backupInfo: { filePath: string; fileName: string } | null = null; + + try { + this.logger.log(`Admin ${user.id} solicitó backup de la base de datos`); + + // Limpiar backups antiguos antes de crear uno nuevo + await this.backupService.cleanupOldBackups(); + + // Crear el backup + backupInfo = await this.backupService.createBackup(); + + // Verificar que el archivo existe + if (!fs.existsSync(backupInfo.filePath)) { + throw new Error('El archivo de backup no se encontró'); + } + + const stats = fs.statSync(backupInfo.filePath); + + // Configurar headers para la descarga + res.setHeader('Content-Type', 'application/sql'); + res.setHeader('Content-Disposition', `attachment; filename="${backupInfo.fileName}"`); + res.setHeader('Content-Length', stats.size); + + // Crear stream para enviar el archivo + const fileStream = fs.createReadStream(backupInfo.filePath); + + // Manejar errores del stream + fileStream.on('error', (error) => { + this.logger.error('Error leyendo archivo de backup:', error); + if (!res.headersSent) { + res.status(500).json({ error: 'Error al leer el archivo de backup' }); + } + }); + + // Enviar el archivo + fileStream.pipe(res); + + // Limpiar el archivo después de enviarlo + fileStream.on('end', () => { + if (backupInfo) { + this.logger.log(`Backup enviado exitosamente: ${backupInfo.fileName}`); + // Eliminar el archivo después de un pequeño delay para asegurar que se envió completamente + setTimeout(() => { + this.backupService.deleteBackupFile(backupInfo!.filePath); + }, 1000); + } + }); + + } catch (error: any) { + this.logger.error('Error generando o enviando backup:', error.message); + + // Limpiar archivo si se creó pero hubo error + if (backupInfo?.filePath) { + this.backupService.deleteBackupFile(backupInfo.filePath); + } + + if (!res.headersSent) { + throw new InternalServerErrorException('Error al generar el backup de la base de datos'); + } + } + } + + @Post('upload') + @UseInterceptors( + FileInterceptor('backup', { + storage: diskStorage({ + destination: (req, file, cb) => { + const uploadPath = path.join(process.cwd(), 'tmp'); + cb(null, uploadPath); + }, + filename: (req, file, cb) => { + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const filename = `restore-${timestamp}-${file.originalname}`; + cb(null, filename); + }, + }), + fileFilter: (req, file, cb) => { + // Solo permitir archivos .sql + if (file.mimetype === 'application/sql' || + file.originalname.endsWith('.sql') || + file.mimetype === 'text/plain') { + cb(null, true); + } else { + cb(new BadRequestException('Solo se permiten archivos .sql'), false); + } + }, + limits: { + fileSize: 100 * 1024 * 1024, // 100MB máximo + }, + }) + ) + async uploadBackup( + @UploadedFile() file: Express.Multer.File, + @User() user: AuthUser, + ) { + // Solo administradores pueden restaurar backups + if (user?.role && user?.role !== UserRole.ADMIN) { + throw new ForbiddenException('Solo los administradores pueden restaurar backups'); + } + + if (!file) { + throw new BadRequestException('No se proporcionó ningún archivo'); + } + + try { + this.logger.log(`Admin ${user?.id} subió backup: ${file.originalname} (${file.size} bytes)`); + + const result = await this.backupService.restoreBackup(file.path, file.originalname); + + // El usuario actual puede no existir en el backup restaurado (si el backup es de un + // estado anterior) + let urlCallback = `${process.env.BACKEND_URL ?? ''}/auth/init`; + try { + const token = await this.authService.generarToken(user?.id, TokenRedirectURL.FRONT); + urlCallback = `${process.env.URL_FRONT}?t=${token}`; + } catch { + this.logger.warn('El usuario actual no existe en el backup restaurado. Redirigiendo a /auth/init.'); + } + + return { + success: true, + message: 'Backup restaurado exitosamente', + urlCallback, + details: result, + timestamp: new Date().toISOString(), + }; + + } catch (error: any) { + this.logger.error('Error restaurando backup:', error.message); + + // Limpiar archivo en caso de error + this.backupService.deleteBackupFile(file.path); + + throw new InternalServerErrorException('Error al restaurar el backup'); + } + } + + @Get('status') + async getBackupStatus(@User() user: AuthUser) { + // Solo administradores pueden ver el estado + if (user?.role !== UserRole.ADMIN) { + throw new ForbiddenException('Solo los administradores pueden ver el estado de backups'); + } + + return { + message: 'Servicio de backup disponible', + timestamp: new Date().toISOString(), + databaseUrl: process.env.DATABASE_URL ? 'Configurado' : 'No configurado', + }; + } + + @Post('validate') + @UseInterceptors( + FileInterceptor('backup', { + storage: diskStorage({ + destination: (req, file, cb) => { + const uploadPath = path.join(process.cwd(), 'tmp'); + cb(null, uploadPath); + }, + filename: (req, file, cb) => { + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const filename = `validate-${timestamp}-${file.originalname}`; + cb(null, filename); + }, + }), + fileFilter: (req, file, cb) => { + if (file.mimetype === 'application/sql' || + file.originalname.endsWith('.sql') || + file.mimetype === 'text/plain') { + cb(null, true); + } else { + cb(new BadRequestException('Solo se permiten archivos .sql'), false); + } + }, + limits: { + fileSize: 100 * 1024 * 1024, // 100MB máximo + }, + }) + ) + async validateBackupFile( + @UploadedFile() file: Express.Multer.File, + @User() user: AuthUser, + ) { + // Solo administradores pueden validar backups + if (user?.role !== UserRole.ADMIN) { + throw new ForbiddenException('Solo los administradores pueden validar backups'); + } + + if (!file) { + throw new BadRequestException('No se proporcionó ningún archivo'); + } + + try { + const isValid = await this.backupService.validateBackupFile(file.path); + + return { + valid: isValid.valid, + message: isValid.message, + details: isValid.details, + }; + + } catch (error: any) { + throw new BadRequestException('Error al validar el archivo'); + } finally { + // Siempre limpiar el archivo de validación + this.backupService.deleteBackupFile(file.path); + } + } +} \ No newline at end of file diff --git a/bot-wsp/src/backup/backup.module.ts b/bot-wsp/src/backup/backup.module.ts new file mode 100644 index 0000000..efd0aa8 --- /dev/null +++ b/bot-wsp/src/backup/backup.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { PrismaModule } from '../prisma/prisma.module'; +import { BackupController } from './backup.controller'; +import { BackupService } from './backup.service'; +import { AuthModule } from '~/auth/auth.module'; + +@Module({ + imports: [PrismaModule, AuthModule], + controllers: [BackupController], + providers: [BackupService], + exports: [BackupService], +}) +export class BackupModule { } \ No newline at end of file diff --git a/bot-wsp/src/backup/backup.service.ts b/bot-wsp/src/backup/backup.service.ts new file mode 100644 index 0000000..6940efd --- /dev/null +++ b/bot-wsp/src/backup/backup.service.ts @@ -0,0 +1,415 @@ +import { Injectable, Logger, InternalServerErrorException } from '@nestjs/common'; +import { exec } from 'child_process'; +import { promisify } from 'util'; +import * as fs from 'fs'; +import * as path from 'path'; +import { PrismaService } from '../prisma/prisma.service'; + +const execAsync = promisify(exec); + +@Injectable() +export class BackupService { + private readonly logger = new Logger(BackupService.name); + + constructor(private readonly prisma: PrismaService) {} + + private cleanDatabaseUrl(databaseUrl: string): string { + try { + const url = new URL(databaseUrl); + // Remover parámetros de query que pg_dump no reconoce + url.search = ''; + return url.toString(); + } catch (error) { + // Si no es una URL válida, intentar limpiar manualmente + return databaseUrl.split('?')[0]; + } + } + + async createBackup(): Promise<{ filePath: string; fileName: string }> { + try { + const databaseUrl = process.env.DATABASE_URL; + if (!databaseUrl) { + throw new Error('DATABASE_URL no está configurada'); + } + + // Limpiar la URL de parámetros que pg_dump no reconoce + const cleanDatabaseUrl = this.cleanDatabaseUrl(databaseUrl); + + // Generar nombre único para el archivo + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const fileName = `backup-${timestamp}.sql`; + const backupDir = path.join(process.cwd(), 'tmp'); + const filePath = path.join(backupDir, fileName); + + // Crear directorio tmp si no existe + if (!fs.existsSync(backupDir)) { + fs.mkdirSync(backupDir, { recursive: true }); + } + + // Ejecutar pg_dump (instalado en el contenedor) + this.logger.log('Iniciando backup de la base de datos...'); + + const command = `pg_dump "${cleanDatabaseUrl}" -f "${filePath}"`; + + await execAsync(command); + + // Verificar que el archivo se creó correctamente + if (!fs.existsSync(filePath)) { + throw new Error('El archivo de backup no se creó correctamente'); + } + + const stats = fs.statSync(filePath); + this.logger.log(`Backup creado exitosamente: ${fileName} (${stats.size} bytes)`); + + return { filePath, fileName }; + } catch (error: any) { + this.logger.error('Error creando backup:', error.message); + throw new InternalServerErrorException('Error al crear el backup de la base de datos'); + } + } + + async restoreBackup(filePath: string, originalName: string): Promise<{ tablesRestored: string; fileSize: number }> { + try { + const databaseUrl = process.env.DATABASE_URL; + if (!databaseUrl) { + throw new Error('DATABASE_URL no está configurada'); + } + + // Limpiar la URL de parámetros que psql no reconoce + const cleanDatabaseUrl = this.cleanDatabaseUrl(databaseUrl); + + // Verificar que el archivo existe + if (!fs.existsSync(filePath)) { + throw new Error('Archivo de backup no encontrado'); + } + + const stats = fs.statSync(filePath); + this.logger.log(`Iniciando restauración desde: ${originalName} (${stats.size} bytes)`); + + // DEBUG: Analizar contenido del backup + await this.debugBackupContent(filePath); + + // **IMPORTANTE: Esto eliminará TODOS los datos actuales y desconectará la aplicación temporalmente** + this.logger.log('Eliminando base de datos completa y recreando desde cero...'); + + // Paso 1: Obtener el nombre de la base de datos de la URL + const dbUrl = new URL(cleanDatabaseUrl); + const dbName = dbUrl.pathname.substring(1); // Remover el "/" + + // Paso 2: Conectar a postgres (base de datos administrativa) para eliminar y recrear + const adminUrl = cleanDatabaseUrl.replace(`/${dbName}`, '/postgres'); + + // Paso 3: Terminar todas las conexiones activas a la base de datos (incluyendo la aplicación) + this.logger.log(`⚠️ Terminando TODAS las conexiones a la base de datos ${dbName}...`); + const terminateConnectionsCommand = `psql "${adminUrl}" -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = '${dbName}' AND pid <> pg_backend_pid();"`; + + try { + const { stdout: terminated } = await execAsync(terminateConnectionsCommand); + this.logger.log('Conexiones terminadas:', terminated.trim()); + } catch (error: any) { + this.logger.warn('Error terminando conexiones (puede ser normal):', error.message); + } + + // Paso 4: Esperar a que las conexiones se cierren + this.logger.log('Esperando que las conexiones se cierren completamente...'); + await new Promise(resolve => setTimeout(resolve, 2000)); + + // Paso 5: Eliminar la base de datos actual + this.logger.log(`🗑️ Eliminando base de datos ${dbName}...`); + const dropCommand = `psql "${adminUrl}" -c "DROP DATABASE IF EXISTS \"${dbName}\";"`; + await execAsync(dropCommand); + + // Paso 6: Crear la base de datos nuevamente (vacía) + this.logger.log(`🔨 Creando base de datos ${dbName} limpia...`); + const createCommand = `psql "${adminUrl}" -c "CREATE DATABASE \"${dbName}\";"`; + await execAsync(createCommand); + + // Paso 7: Restaurar el backup completo en la base de datos limpia + this.logger.log('📦 Restaurando backup completo en la nueva base de datos...'); + const restoreCommand = `psql "${cleanDatabaseUrl}" -f "${filePath}"`; + + const { stdout, stderr } = await execAsync(restoreCommand); + + // Paso 8: Verificar que TODAS las tablas fueron restauradas correctamente + this.logger.log('Verificando que todas las tablas del schema fueron restauradas...'); + const verifyCommand = `psql "${cleanDatabaseUrl}" -c " + SELECT 'User' as tabla, COUNT(*) as registros FROM \\"User\\" + UNION ALL SELECT 'AccessLog', COUNT(*) FROM \\"AccessLog\\" + UNION ALL SELECT 'Token', COUNT(*) FROM \\"Token\\" + UNION ALL SELECT 'Session', COUNT(*) FROM \\"Session\\" + UNION ALL SELECT 'SessionPriceHistory', COUNT(*) FROM \\"SessionPriceHistory\\" + UNION ALL SELECT 'SessionDateRange', COUNT(*) FROM \\"SessionDateRange\\" + UNION ALL SELECT 'SessionDateSnapshot', COUNT(*) FROM \\"SessionDateSnapshot\\" + UNION ALL SELECT 'Invoice', COUNT(*) FROM \\"Invoice\\" + UNION ALL SELECT 'SystemConfig', COUNT(*) FROM \\"SystemConfig\\" + ORDER BY tabla; + "`; + + try { + const { stdout: verifyOutput } = await execAsync(verifyCommand); + this.logger.log('✅ Verificación completa de todas las tablas:'); + this.logger.log(verifyOutput.trim()); + } catch (error: any) { + this.logger.error('❌ Error en verificación de tablas:', error.message); + throw new Error('La restauración no incluyó todas las tablas esperadas'); + } + + // Paso 9: Verificar integridad de relaciones many-to-many + this.logger.log('Verificando tablas de relación many-to-many...'); + const verifyRelationsCommand = `psql "${cleanDatabaseUrl}" -c " + SELECT + '_InstructorSessions' as relacion, COUNT(*) as registros + FROM \\"_InstructorSessions\\" + UNION ALL + SELECT '_AssistantSessions', COUNT(*) + FROM \\"_AssistantSessions\\" + UNION ALL + SELECT '_PresentInstructorsOnDate', COUNT(*) + FROM \\"_PresentInstructorsOnDate\\" + UNION ALL + SELECT '_PresentAssistantsOnDate', COUNT(*) + FROM \\"_PresentAssistantsOnDate\\" + UNION ALL + SELECT '_SubstituteInstructorsOnDate', COUNT(*) + FROM \\"_SubstituteInstructorsOnDate\\"; + "`; + + try { + const { stdout: relationsOutput } = await execAsync(verifyRelationsCommand); + this.logger.log('✅ Verificación de relaciones many-to-many:'); + this.logger.log(relationsOutput.trim()); + } catch (error: any) { + this.logger.warn('⚠️ Error verificando relaciones (puede ser normal si están vacías):', error.message); + } + + // Extraer información del resultado + const output = stdout + stderr; + + // Contar las operaciones procesadas con más detalle + const createTableMatches = output.match(/CREATE TABLE/g) || []; + const copyMatches = output.match(/COPY \d+/g) || []; + const createIndexMatches = output.match(/CREATE INDEX/g) || []; + const alterTableMatches = output.match(/ALTER TABLE/g) || []; + + this.logger.log(`📊 Resumen de operaciones completadas:`); + this.logger.log(`- Tablas creadas: ${createTableMatches.length}`); + this.logger.log(`- Operaciones COPY (datos): ${copyMatches.length}`); + this.logger.log(`- Índices creados: ${createIndexMatches.length}`); + this.logger.log(`- Constraints/FKs: ${alterTableMatches.length}`); + + // Verificar que tenemos al menos las 9 tablas principales + 5 tablas de relación + const expectedMinTables = 14; // 9 modelos + 5 relaciones many-to-many + if (createTableMatches.length < expectedMinTables) { + this.logger.warn(`⚠️ Se esperaban al menos ${expectedMinTables} tablas, se encontraron ${createTableMatches.length}`); + } + + if (output.includes('ERROR') || stderr.includes('ERROR')) { + this.logger.error('❌ Se encontraron errores en la restauración:', stderr); + throw new Error('La restauración completó con errores'); + } + + // Reconectar Prisma: el pool quedó roto porque se terminaron todas las + // conexiones durante el DROP/CREATE DATABASE + this.logger.log('🔌 Reconectando Prisma al nuevo estado de la base de datos...'); + await this.prisma.$disconnect(); + await this.prisma.$connect(); + this.logger.log('✅ Prisma reconectado exitosamente'); + + // Limpiar archivo después de restaurar + setTimeout(() => { + this.deleteBackupFile(filePath); + }, 1000); + + return { + tablesRestored: `${createTableMatches.length} tablas, ${copyMatches.length} operaciones de datos`, + fileSize: stats.size, + }; + + } catch (error: any) { + this.logger.error('Error restaurando backup:', error.message); + + // Limpiar archivo en caso de error + this.deleteBackupFile(filePath); + + throw new InternalServerErrorException('Error al restaurar el backup de la base de datos'); + } + } + + async validateBackupFile(filePath: string): Promise<{ valid: boolean; message: string; details?: any }> { + try { + if (!fs.existsSync(filePath)) { + return { valid: false, message: 'Archivo no encontrado' }; + } + + const stats = fs.statSync(filePath); + if (stats.size === 0) { + return { valid: false, message: 'El archivo está vacío' }; + } + + // Leer las primeras líneas del archivo para validar el formato + const fileContent = fs.readFileSync(filePath, 'utf8'); + const lines = fileContent.split('\n').slice(0, 20); // Primeras 20 líneas + + // Verificar que parece un dump de PostgreSQL + const hasSQLHeader = lines.some(line => + line.includes('PostgreSQL database dump') || + line.includes('pg_dump') || + line.startsWith('--') || + line.includes('CREATE TABLE') || + line.includes('INSERT INTO') || + line.includes('COPY ') + ); + + if (!hasSQLHeader) { + return { + valid: false, + message: 'El archivo no parece ser un backup válido de PostgreSQL' + }; + } + + return { + valid: true, + message: 'Archivo válido', + details: { + size: stats.size, + sizeFormatted: this.formatBytes(stats.size), + lines: fileContent.split('\n').length, + } + }; + + } catch (error: any) { + this.logger.error('Error validando archivo:', error.message); + return { + valid: false, + message: 'Error al procesar el archivo' + }; + } + } + + private formatBytes(bytes: number): string { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; + } + + async cleanupOldBackups(maxAge: number = 24 * 60 * 60 * 1000): Promise { + try { + const backupDir = path.join(process.cwd(), 'tmp'); + if (!fs.existsSync(backupDir)) { + return; + } + + const files = fs.readdirSync(backupDir); + const now = Date.now(); + + for (const file of files) { + if (file.startsWith('backup-') && file.endsWith('.sql')) { + const filePath = path.join(backupDir, file); + const stats = fs.statSync(filePath); + + if (now - stats.mtime.getTime() > maxAge) { + fs.unlinkSync(filePath); + this.logger.log(`Backup antiguo eliminado: ${file}`); + } + } + } + } catch (error: any) { + this.logger.warn('Error limpiando backups antiguos:', error.message); + } + } + + async debugBackupContent(filePath: string): Promise { + try { + this.logger.log('=== DEBUG: Analizando contenido del backup ==='); + + // Verificar todas las tablas principales del schema + const tables = [ + 'User', 'AccessLog', 'Token', 'Session', + 'SessionPriceHistory', 'SessionDateRange', 'SessionDateSnapshot', + 'Invoice', 'SystemConfig' + ]; + + for (const table of tables) { + const grepCommand = `grep -c 'COPY public."${table}"' "${filePath}" || echo "0"`; + + try { + const { stdout } = await execAsync(grepCommand); + const count = parseInt(stdout.trim()); + if (count > 0) { + this.logger.log(`✅ Tabla "${table}" encontrada en backup`); + } else { + this.logger.warn(`⚠️ Tabla "${table}" NO encontrada en backup`); + } + } catch (error: any) { + this.logger.warn(`❌ Error verificando tabla "${table}":`, error.message); + } + } + + // Verificar tablas de relación many-to-many + const relationTables = [ + '_InstructorSessions', '_AssistantSessions', + '_PresentInstructorsOnDate', '_PresentAssistantsOnDate', + '_SubstituteInstructorsOnDate' + ]; + + this.logger.log('--- Verificando tablas de relación ---'); + for (const table of relationTables) { + const grepCommand = `grep -c 'COPY public."${table}"' "${filePath}" || echo "0"`; + + try { + const { stdout } = await execAsync(grepCommand); + const count = parseInt(stdout.trim()); + if (count > 0) { + this.logger.log(`✅ Relación "${table}" encontrada en backup`); + } else { + this.logger.log(`ℹ️ Relación "${table}" vacía o no encontrada (normal si no hay datos)`); + } + } catch (error: any) { + this.logger.warn(`Error verificando relación "${table}":`, error.message); + } + } + + // Contar líneas totales + const wcCommand = `wc -l "${filePath}"`; + const { stdout: lineCount } = await execAsync(wcCommand); + this.logger.log(`📄 Total de líneas en backup: ${lineCount.trim()}`); + + // Verificar que tiene la estructura completa de PostgreSQL dump + const structureChecks = [ + { pattern: 'PostgreSQL database dump', name: 'Header de PostgreSQL' }, + { pattern: 'CREATE TABLE', name: 'Definiciones de tablas' }, + { pattern: 'CREATE INDEX', name: 'Índices' }, + { pattern: 'ALTER TABLE.*ADD CONSTRAINT', name: 'Foreign Keys' }, + { pattern: 'CREATE TYPE', name: 'Enums (tipos personalizados)' }, + ]; + + for (const check of structureChecks) { + const grepCommand = `grep -c '${check.pattern}' "${filePath}" || echo "0"`; + try { + const { stdout } = await execAsync(grepCommand); + const count = parseInt(stdout.trim()); + this.logger.log(`${count > 0 ? '✅' : '⚠️ '} ${check.name}: ${count} encontrados`); + } catch (error: any) { + this.logger.warn(`Error verificando ${check.name}`); + } + } + + this.logger.log('=== FIN DEBUG ==='); + } catch (error: any) { + this.logger.error('Error en debug:', error.message); + } + } + + deleteBackupFile(filePath: string): void { + try { + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + this.logger.log(`Archivo de backup eliminado: ${path.basename(filePath)}`); + } + } catch (error: any) { + this.logger.warn('Error eliminando archivo de backup:', error.message); + } + } +} \ No newline at end of file diff --git a/bot-wsp/src/common/decoratos/user.decorator.ts b/bot-wsp/src/common/decoratos/user.decorator.ts new file mode 100644 index 0000000..ee2cd82 --- /dev/null +++ b/bot-wsp/src/common/decoratos/user.decorator.ts @@ -0,0 +1,9 @@ +// src/common/decorators/user.decorator.ts +import { createParamDecorator, ExecutionContext } from '@nestjs/common'; + +export const User = createParamDecorator( + (data: unknown, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest(); + return request.user || null; + }, +); diff --git a/bot-wsp/src/common/guards/admin.guard.ts b/bot-wsp/src/common/guards/admin.guard.ts new file mode 100644 index 0000000..dfc8a28 --- /dev/null +++ b/bot-wsp/src/common/guards/admin.guard.ts @@ -0,0 +1,46 @@ +import { + CanActivate, + ExecutionContext, + Injectable, + ForbiddenException, + UnauthorizedException, +} from '@nestjs/common'; +import { PrismaService } from '../../prisma/prisma.service'; +import { UserRole } from '@prisma/client'; + +@Injectable() +export class AdminGuard implements CanActivate { + constructor(private prisma: PrismaService) {} + + async canActivate(context: ExecutionContext): Promise { + const request = context.switchToHttp().getRequest(); + const authHeader = request.headers['authorization']; + + if (!authHeader || !authHeader.toLowerCase().startsWith('bearer ')) { + throw new UnauthorizedException('Token no proporcionado'); + } + + const token = authHeader.substring(7).trim(); + + const found = await this.prisma.token.findUnique({ + where: { token }, + include: { user: true }, + }); + + if (!found) { + throw new UnauthorizedException('Token inválido'); + } + + if (new Date() > found.expiresAt) { + throw new UnauthorizedException('Token expirado'); + } + + // Verificar que el usuario sea ADMIN + // if (found?.user?.role !== UserRole.ADMIN) { + // throw new ForbiddenException('Acceso denegado: se requieren permisos de administrador'); + // } + + request.user = found.user; + return true; + } +} diff --git a/bot-wsp/src/common/guards/auth-token.guard.ts b/bot-wsp/src/common/guards/auth-token.guard.ts new file mode 100644 index 0000000..3148431 --- /dev/null +++ b/bot-wsp/src/common/guards/auth-token.guard.ts @@ -0,0 +1,40 @@ +import { + CanActivate, + ExecutionContext, + Injectable, + UnauthorizedException, +} from '@nestjs/common'; +import { PrismaService } from '../../prisma/prisma.service'; + +@Injectable() +export class AuthTokenGuard implements CanActivate { + constructor(private prisma: PrismaService) {} + + async canActivate(context: ExecutionContext): Promise { + const request = context.switchToHttp().getRequest(); + const authHeader = request.headers['authorization']; + + if (!authHeader || !authHeader.toLowerCase().startsWith('bearer ')) { + throw new UnauthorizedException('Token no proporcionado'); + } + + const token = authHeader.substring(7).trim(); // lo que viene después de "Bearer " + + const found = await this.prisma.token.findUnique({ + where: { token }, + include: { user: true }, + }); + + if (!found) { + throw new UnauthorizedException('Token inválido'); + } + + if (new Date() > found.expiresAt) { + throw new UnauthorizedException('Token expirado'); + } + + // guardamos el usuario en request para que @User() lo pueda leer + request.user = found?.user || undefined; + return true; + } +} diff --git a/bot-wsp/src/common/system-config.controller.ts b/bot-wsp/src/common/system-config.controller.ts new file mode 100644 index 0000000..8aff1a0 --- /dev/null +++ b/bot-wsp/src/common/system-config.controller.ts @@ -0,0 +1,227 @@ +import { Body, Controller, Get, Patch, UseGuards, ValidationPipe, UsePipes, Post } from '@nestjs/common'; +import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiProperty } from '@nestjs/swagger'; +import { SystemConfigService } from './system-config.service'; +import { AdminGuard } from './guards/admin.guard'; +import { User } from './decoratos/user.decorator'; +import { AuthUser } from './types'; +import { IsOptional, IsInt, Min, Max, IsDateString } from 'class-validator'; + +class UpdateSystemConfigDto { + @ApiProperty({ + description: 'Intervalo en minutos para desactivar sesiones vencidas', + example: 30, + required: false, + minimum: 1, + }) + @IsOptional() + @IsInt() + @Min(1) + sessionCleanupIntervalMinutes?: number; + + @ApiProperty({ + description: 'Día del mes (1-28) en que se generan las facturas mensuales', + example: 1, + required: false, + minimum: 1, + maximum: 28, + }) + @IsOptional() + @IsInt() + @Min(1) + @Max(28) + invoiceGenerationDayOfMonth?: number; + + @ApiProperty({ + description: 'Tiempo de expiración de los tokens en minutos', + example: 30, + required: false, + minimum: 1, + }) + @IsOptional() + @IsInt() + @Min(1) + tokenExpirationMinutes?: number; + + @ApiProperty({ + description: 'Intervalo en minutos para limpiar tokens expirados', + example: 60, + required: false, + minimum: 1, + }) + @IsOptional() + @IsInt() + @Min(1) + tokenCleanupIntervalMinutes?: number; + + @ApiProperty({ + description: 'Intervalo en días para actualizar fotos de perfil de WhatsApp', + example: 2, + required: false, + minimum: 1, + }) + @IsOptional() + @IsInt() + @Min(1) + profilePictureUpdateIntervalDays?: number; +} + +class ForceInvoicesDto { + @ApiProperty({ + description: 'Fecha del mes para el cual generar facturas (formato ISO 8601)', + example: '2025-11-01T00:00:00.000Z', + required: true, + }) + @IsDateString() + targetMonth!: string; +} + +@ApiTags('Configuración del Sistema') +@Controller('system-config') +export class SystemConfigController { + constructor(private readonly systemConfigService: SystemConfigService) { } + + @Get() + //@UseGuards(AdminGuard) + @ApiOperation({ + summary: 'Obtener configuración actual del sistema', + description: 'Retorna todos los parámetros de configuración actuales que controlan los trabajos programados y tokens' + }) + @ApiResponse({ + status: 200, + description: 'Configuración obtenida exitosamente', + schema: { + example: { + id: 'clxxx123456', + sessionCleanupIntervalMinutes: 30, + invoiceGenerationDayOfMonth: 1, + tokenExpirationMinutes: 30, + tokenCleanupIntervalMinutes: 60, + profilePictureUpdateIntervalDays: 2, + createdAt: '2025-11-10T00:00:00.000Z', + updatedAt: '2025-11-10T00:00:00.000Z' + } + } + }) + @ApiResponse({ status: 401, description: 'No autorizado - Token no proporcionado o inválido' }) + @ApiResponse({ status: 403, description: 'Acceso denegado - Se requieren permisos de administrador' }) + //@ApiBearerAuth() + async getConfig() { + return this.systemConfigService.getConfig(); + } + + @Patch() + @UseGuards(AdminGuard) + @ApiOperation({ + summary: 'Actualizar configuración del sistema', + description: 'Actualiza uno o más parámetros de configuración. Los cambios toman efecto inmediatamente, excepto tokenExpirationMinutes que requiere reinicio.' + }) + @ApiResponse({ + status: 200, + description: 'Configuración actualizada exitosamente', + schema: { + example: { + id: 'clxxx123456', + sessionCleanupIntervalMinutes: 45, + invoiceGenerationDayOfMonth: 5, + tokenExpirationMinutes: 60, + tokenCleanupIntervalMinutes: 120, + profilePictureUpdateIntervalDays: 3, + createdAt: '2025-11-10T00:00:00.000Z', + updatedAt: '2025-11-10T12:30:00.000Z', + warnings: [ + 'El cambio en tokenExpirationMinutes requiere reiniciar la aplicación para que JwtModule lo tome en cuenta.' + ] + } + } + }) + @ApiResponse({ status: 400, description: 'Datos inválidos - Revisa las validaciones de cada campo' }) + @ApiResponse({ status: 401, description: 'No autorizado - Token no proporcionado o inválido' }) + @ApiResponse({ status: 403, description: 'Acceso denegado - Se requieren permisos de administrador' }) + @ApiBearerAuth() + @UsePipes(new ValidationPipe({ transform: true, whitelist: true })) + async updateConfig( + @Body() data: UpdateSystemConfigDto, + @User() user: AuthUser, + ) { + console.log('=== CONTROLLER UPDATE CONFIG ==='); + console.log('Body received:', JSON.stringify(data, null, 2)); + console.log('Body type:', typeof data); + console.log('Body constructor:', data.constructor.name); + console.log('User:', JSON.stringify(user, null, 2)); + console.log('Body keys:', Object.keys(data)); + console.log('Body values:', Object.values(data)); + console.log('invoiceGenerationDayOfMonth type:', typeof data.invoiceGenerationDayOfMonth); + console.log('invoiceGenerationDayOfMonth value:', data.invoiceGenerationDayOfMonth); + console.log('================================'); + + const result = await this.systemConfigService.updateConfig(data, user); + + // Advertencia si se cambió tokenExpirationMinutes + const warnings = []; + if (data.tokenExpirationMinutes !== undefined) { + warnings.push('El cambio en tokenExpirationMinutes requiere reiniciar la aplicación para que JwtModule lo tome en cuenta.'); + } + + return { + ...result, + ...(warnings.length > 0 && { warnings }) + }; + } + + @Get('reload') + @UseGuards(AdminGuard) + @ApiOperation({ + summary: 'Recargar configuración desde la base de datos', + description: 'Fuerza la recarga de la configuración desde la base de datos en memoria. Útil después de cambios manuales en la BD.' + }) + @ApiResponse({ + status: 200, + description: 'Configuración recargada exitosamente', + schema: { + example: { + message: 'Configuración recargada exitosamente' + } + } + }) + @ApiResponse({ status: 401, description: 'No autorizado - Token no proporcionado o inválido' }) + @ApiResponse({ status: 403, description: 'Acceso denegado - Se requieren permisos de administrador' }) + @ApiBearerAuth() + async reloadConfig() { + await this.systemConfigService.reloadConfig(); + return { message: 'Configuración recargada exitosamente' }; + } + + @Post('force-invoices') + @UseGuards(AdminGuard) + @ApiOperation({ + summary: 'Forzar generación de facturas para un mes específico', + description: 'Genera facturas para todas las sesiones activas y sus asistentes en el mes especificado. Solo crea facturas que no existan previamente.' + }) + @ApiResponse({ + status: 200, + description: 'Facturas generadas exitosamente', + schema: { + example: { + message: 'Facturas generadas exitosamente para 2025-11', + totalCreated: 15, + details: [ + { sessionId: 'xxx', assistantId: 'yyy', invoiceId: 'zzz' } + ] + } + } + }) + @ApiResponse({ status: 400, description: 'Datos inválidos - Fecha requerida' }) + @ApiResponse({ status: 401, description: 'No autorizado' }) + @ApiResponse({ status: 403, description: 'Acceso denegado' }) + @ApiBearerAuth() + async forceGenerateInvoices( + @Body() data: ForceInvoicesDto, + @User() user: AuthUser, + ) { + const result = await this.systemConfigService.forceGenerateMonthlyInvoices( + new Date(data.targetMonth), + user + ); + return result; + } +} diff --git a/bot-wsp/src/common/system-config.module.ts b/bot-wsp/src/common/system-config.module.ts new file mode 100644 index 0000000..166891b --- /dev/null +++ b/bot-wsp/src/common/system-config.module.ts @@ -0,0 +1,20 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { SystemConfigService } from './system-config.service'; +import { SystemConfigController } from './system-config.controller'; +import { PrismaModule } from '../prisma/prisma.module'; +import { InvoicesModule } from '~/invoices/invoices.module'; +import { UserModule } from '~/user/user.module'; +import { AuthModule } from '~/auth/auth.module'; + +@Module({ + controllers: [SystemConfigController], + providers: [SystemConfigService], + imports: [ + PrismaModule, + forwardRef(() => InvoicesModule), + forwardRef(() => UserModule), + forwardRef(() => AuthModule), + ], + exports: [SystemConfigService], +}) +export class SystemConfigModule { } diff --git a/bot-wsp/src/common/system-config.service.ts b/bot-wsp/src/common/system-config.service.ts new file mode 100644 index 0000000..b75c3ba --- /dev/null +++ b/bot-wsp/src/common/system-config.service.ts @@ -0,0 +1,295 @@ +import { forwardRef, Inject, Injectable, Logger, OnModuleInit } from '@nestjs/common'; +import { PrismaService } from '~/prisma/prisma.service'; +import { AuthUser } from './types'; +import { InvoicesService } from '~/invoices/invoices.service'; +import dayjs from 'dayjs'; +import { UserService } from '~/user/user.service'; +import { UpsertUserDto } from '~/user/user.dto'; +import { AuthService } from '~/auth/auth.service'; + +@Injectable() +export class SystemConfigService implements OnModuleInit { + private readonly logger = new Logger(SystemConfigService.name); + private config: { + sessionCleanupIntervalMinutes: number; + invoiceGenerationDayOfMonth: number; + tokenExpirationMinutes: number; + tokenCleanupIntervalMinutes: number; + profilePictureUpdateIntervalDays: number; + } | null = null; + + private firstUrl: string | null = null; + + constructor( + private readonly prisma: PrismaService, + @Inject(forwardRef(() => InvoicesService)) + private readonly invoicesService: InvoicesService, + private readonly userService: UserService, + @Inject(forwardRef(() => AuthService)) + private readonly authService: AuthService, + + ) { } + + async onModuleInit() { + await this.loadConfig(); + } + + /** + * Carga la configuración desde la base de datos. + * Si no existe, crea una configuración por defecto. + */ + private async loadConfig() { + try { + let config = await this.prisma.systemConfig.findFirst(); + + if (!config) { + //NOTE cREO EL PRIMER USUARIO DEL SISTEMA + + const dataUser: UpsertUserDto = { + name: 'ADMIN', + role: 'ADMIN', + customId: '' + } + + const user = await this.userService.upsert(dataUser) + + const token = await this.authService.generarToken(user.id, undefined, 1440); // Token válido por 24 horas + + this.logger.log(`Primer usuario ADMIN creado. token para iniciar sesión: ${token}`); + + this.firstUrl = `${process.env.URL_FRONT}?t=${token}`; + + this.logger.log('No se encontró configuración del sistema, creando valores por defecto...'); + config = await this.prisma.systemConfig.create({ + data: { + sessionCleanupIntervalMinutes: 30, + invoiceGenerationDayOfMonth: 1, + tokenExpirationMinutes: 30, + tokenCleanupIntervalMinutes: 60, + profilePictureUpdateIntervalDays: 2, + }, + }); + } + + this.config = { + sessionCleanupIntervalMinutes: config.sessionCleanupIntervalMinutes, + invoiceGenerationDayOfMonth: config.invoiceGenerationDayOfMonth, + tokenExpirationMinutes: config.tokenExpirationMinutes, + tokenCleanupIntervalMinutes: config.tokenCleanupIntervalMinutes, + profilePictureUpdateIntervalDays: config.profilePictureUpdateIntervalDays, + }; + + this.logger.log('Configuración del sistema cargada exitosamente'); + } catch (err: any) { + this.logger.error('Error cargando configuración del sistema', err?.stack || err); + // Valores por defecto en caso de error + this.config = { + sessionCleanupIntervalMinutes: 30, + invoiceGenerationDayOfMonth: 1, + tokenExpirationMinutes: 30, + tokenCleanupIntervalMinutes: 60, + profilePictureUpdateIntervalDays: 2, + }; + } + } + + /** + * Recarga la configuración desde la base de datos + */ + async reloadConfig() { + await this.loadConfig(); + } + + /** + * Obtiene el intervalo de limpieza de sesiones en minutos + */ + getSessionCleanupInterval(): number { + return this.config?.sessionCleanupIntervalMinutes ?? 30; + } + + /** + * Obtiene el día del mes para generar facturas (1-28) + */ + getInvoiceGenerationDay(): number { + return this.config?.invoiceGenerationDayOfMonth ?? 1; + } + + /** + * Obtiene el tiempo de expiración de tokens en minutos + */ + getTokenExpirationMinutes(): number { + return this.config?.tokenExpirationMinutes ?? 30; + } + + /** + * Obtiene el intervalo de limpieza de tokens en minutos + */ + getTokenCleanupInterval(): number { + return this.config?.tokenCleanupIntervalMinutes ?? 60; + } + + /** + * Obtiene el intervalo de actualización de fotos de perfil en días + */ + getProfilePictureUpdateInterval(): number { + return this.config?.profilePictureUpdateIntervalDays ?? 2; + } + + /** + * Actualiza la configuración del sistema + */ + async updateConfig(data: { + sessionCleanupIntervalMinutes?: number; + invoiceGenerationDayOfMonth?: number; + tokenExpirationMinutes?: number; + tokenCleanupIntervalMinutes?: number; + profilePictureUpdateIntervalDays?: number; + }, actionBy?: AuthUser) { + const actionByInfo = actionBy ? `${actionBy.name || actionBy.id} (${actionBy.role})` : 'Unknown'; + this.logger.log(`Update system config request - data: ${JSON.stringify(data)}, actionBy: ${actionByInfo}`); + + try { + // Validaciones + if (data.invoiceGenerationDayOfMonth !== undefined) { + if (data.invoiceGenerationDayOfMonth < 1 || data.invoiceGenerationDayOfMonth > 28) { + this.logger.warn(`Invalid invoiceGenerationDayOfMonth: ${data.invoiceGenerationDayOfMonth}, attemptedBy: ${actionByInfo}`); + throw new Error('El día de generación de facturas debe estar entre 1 y 28'); + } + } + + if (data.sessionCleanupIntervalMinutes !== undefined && data.sessionCleanupIntervalMinutes < 1) { + this.logger.warn(`Invalid sessionCleanupIntervalMinutes: ${data.sessionCleanupIntervalMinutes}, attemptedBy: ${actionByInfo}`); + throw new Error('El intervalo de limpieza de sesiones debe ser mayor a 0'); + } + + if (data.tokenExpirationMinutes !== undefined && data.tokenExpirationMinutes < 1) { + this.logger.warn(`Invalid tokenExpirationMinutes: ${data.tokenExpirationMinutes}, attemptedBy: ${actionByInfo}`); + throw new Error('El tiempo de expiración de tokens debe ser mayor a 0'); + } + + if (data.tokenCleanupIntervalMinutes !== undefined && data.tokenCleanupIntervalMinutes < 1) { + this.logger.warn(`Invalid tokenCleanupIntervalMinutes: ${data.tokenCleanupIntervalMinutes}, attemptedBy: ${actionByInfo}`); + throw new Error('El intervalo de limpieza de tokens debe ser mayor a 0'); + } + + if (data.profilePictureUpdateIntervalDays !== undefined && data.profilePictureUpdateIntervalDays < 1) { + this.logger.warn(`Invalid profilePictureUpdateIntervalDays: ${data.profilePictureUpdateIntervalDays}, attemptedBy: ${actionByInfo}`); + throw new Error('El intervalo de actualización de fotos debe ser mayor a 0'); + } + + this.logger.log(`Validations passed, searching for existing config - actionBy: ${actionByInfo}`); + + // Buscar configuración existente + const existing = await this.prisma.systemConfig.findFirst(); + + if (!existing) { + this.logger.error(`System config not found in database - attemptedBy: ${actionByInfo}`); + throw new Error('No se encontró configuración del sistema'); + } + + this.logger.log(`Found existing config - id: ${existing.id}, updating with data: ${JSON.stringify(data)}, by: ${actionByInfo}`); + this.logger.log(`Current values in DB - sessionCleanup: ${existing.sessionCleanupIntervalMinutes}, invoiceDay: ${existing.invoiceGenerationDayOfMonth}, tokenExp: ${existing.tokenExpirationMinutes}, tokenCleanup: ${existing.tokenCleanupIntervalMinutes}`); + + console.log('=== SERVICE BEFORE PRISMA UPDATE ==='); + console.log('Existing ID:', existing.id); + console.log('Data to update:', JSON.stringify(data, null, 2)); + console.log('Data keys:', Object.keys(data)); + console.log('Data values:', Object.values(data)); + console.log('Data object type:', typeof data); + console.log('Is data empty?', Object.keys(data).length === 0); + + // Construir el objeto de actualización explícitamente + const updateData: any = {}; + if (data.sessionCleanupIntervalMinutes !== undefined) { + updateData.sessionCleanupIntervalMinutes = data.sessionCleanupIntervalMinutes; + console.log('Adding sessionCleanupIntervalMinutes:', data.sessionCleanupIntervalMinutes); + } + if (data.invoiceGenerationDayOfMonth !== undefined) { + updateData.invoiceGenerationDayOfMonth = data.invoiceGenerationDayOfMonth; + console.log('Adding invoiceGenerationDayOfMonth:', data.invoiceGenerationDayOfMonth); + } + if (data.tokenExpirationMinutes !== undefined) { + updateData.tokenExpirationMinutes = data.tokenExpirationMinutes; + console.log('Adding tokenExpirationMinutes:', data.tokenExpirationMinutes); + } + if (data.tokenCleanupIntervalMinutes !== undefined) { + updateData.tokenCleanupIntervalMinutes = data.tokenCleanupIntervalMinutes; + console.log('Adding tokenCleanupIntervalMinutes:', data.tokenCleanupIntervalMinutes); + } + if (data.profilePictureUpdateIntervalDays !== undefined) { + updateData.profilePictureUpdateIntervalDays = data.profilePictureUpdateIntervalDays; + console.log('Adding profilePictureUpdateIntervalDays:', data.profilePictureUpdateIntervalDays); + } + + console.log('Final updateData object:', JSON.stringify(updateData, null, 2)); + console.log('UpdateData keys:', Object.keys(updateData)); + console.log('===================================='); + + // Actualizar configuración + const updated = await this.prisma.systemConfig.update({ + where: { id: existing.id }, + data: updateData, + }); + + console.log('=== SERVICE AFTER PRISMA UPDATE ==='); + console.log('Updated result:', JSON.stringify(updated, null, 2)); + console.log('==================================='); + + this.logger.log(`Database updated successfully - configId: ${existing.id}, newValues: ${JSON.stringify(updated)}, by: ${actionByInfo}`); + + // Recargar configuración en memoria + await this.loadConfig(); + + this.logger.log(`Configuration reloaded in memory - by: ${actionByInfo}`); + this.logger.log(`System config update completed successfully - by: ${actionByInfo}`); + + return updated; + } catch (err: any) { + this.logger.error(`Error updating system config by ${actionByInfo}: ${err.message}`, err?.stack || err); + throw err; + } + } + + /** + * Obtiene toda la configuración + */ + async getConfig() { + return this.prisma.systemConfig.findFirst(); + } + + /** + * Fuerza la generación de facturas para un mes específico + */ + async forceGenerateMonthlyInvoices(targetMonth: Date, actionBy?: AuthUser) { + const actionByInfo = actionBy ? `${actionBy.name || actionBy.id} (${actionBy.role})` : 'Unknown'; + const monthStr = dayjs(targetMonth).format('YYYY-MM'); + + this.logger.log(`Forzando generación de facturas para ${monthStr} - actionBy: ${actionByInfo}`); + + try { + const invoices = await this.invoicesService.createMonthlyInvoicesForActiveAssistants(targetMonth); + + this.logger.log(`Facturas generadas exitosamente para ${monthStr} - total: ${invoices.length}, by: ${actionByInfo}`); + + return { + message: `Facturas generadas exitosamente para ${monthStr}`, + totalCreated: invoices.length, + details: invoices.map(inv => ({ + sessionId: inv.sessionId, + userId: inv.userId, + invoiceId: inv.id, + amount: inv.amount + })) + }; + } catch (err: any) { + this.logger.error(`Error forzando generación de facturas para ${monthStr} by ${actionByInfo}: ${err.message}`, err?.stack || err); + throw err; + } + } + + getFirstUrl(): string | null { + const url = this.firstUrl; + this.firstUrl = null; // consumir: solo válido una vez + return url; + } +} diff --git a/bot-wsp/src/common/types.ts b/bot-wsp/src/common/types.ts new file mode 100644 index 0000000..c01fba9 --- /dev/null +++ b/bot-wsp/src/common/types.ts @@ -0,0 +1,18 @@ +// common/types.ts +import { UserRole } from '@prisma/client'; + +export type AuthUser = { + id: string; + role: UserRole; + name?: string; + customId?: string; +}; + +// typings/express.d.ts (asegurate que el tsconfig incluya este archivo) +declare global { + namespace Express { + interface Request { + user?: AuthUser; + } + } +} diff --git a/bot-wsp/src/custom-id/custom-id.module.ts b/bot-wsp/src/custom-id/custom-id.module.ts new file mode 100644 index 0000000..37ef42d --- /dev/null +++ b/bot-wsp/src/custom-id/custom-id.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { CustomIdService } from './custom-id.service'; +import { PrismaModule } from '../prisma/prisma.module'; + +@Module({ + providers: [CustomIdService], + imports: [PrismaModule], + exports: [CustomIdService], +}) +export class CustomIdModule { } diff --git a/bot-wsp/src/custom-id/custom-id.service.spec.ts b/bot-wsp/src/custom-id/custom-id.service.spec.ts new file mode 100644 index 0000000..2eeb1a7 --- /dev/null +++ b/bot-wsp/src/custom-id/custom-id.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { CustomIdService } from './custom-id.service'; + +describe('CustomIdService', () => { + let service: CustomIdService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [CustomIdService], + }).compile(); + + service = module.get(CustomIdService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/custom-id/custom-id.service.ts b/bot-wsp/src/custom-id/custom-id.service.ts new file mode 100644 index 0000000..aba9336 --- /dev/null +++ b/bot-wsp/src/custom-id/custom-id.service.ts @@ -0,0 +1,40 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class CustomIdService { + private readonly logger = new Logger(CustomIdService.name); + + constructor(private readonly prisma: PrismaService) { } + + async generateCustomId(modelName: keyof PrismaClient, prefix: string): Promise { + this.logger.log(`Creando nuevo Custom ID para modelo: ${String(modelName)}`); + try { + const model = (this.prisma as any)?.[modelName]; + + const lastRecord = await model.findFirst({ + where: { customId: { startsWith: `${prefix}-` } }, + orderBy: { customId: 'desc' }, + }); + + let nextNumber = 1; + if (lastRecord?.customId) { + const lastNumber = parseInt(lastRecord.customId.slice(prefix.length + 1), 36); + nextNumber = lastNumber + 1; + } + + const nextIdPart = nextNumber.toString(36).padStart(3, '0').toUpperCase(); + const customId = `${prefix}-${nextIdPart}`.toLocaleUpperCase(); + + this.logger.log(`Custom ID generado: ${customId}`); + return customId; + } catch (error: any) { + this.logger.error( + `Error al generar Custom ID para modelo: ${String(modelName)}`, + error.message + ); + throw new Error('No se pudo generar el Custom ID.'); + } + } +} diff --git a/bot-wsp/src/custom-id/dto/create-custom-id.dto.ts b/bot-wsp/src/custom-id/dto/create-custom-id.dto.ts new file mode 100644 index 0000000..dd3777b --- /dev/null +++ b/bot-wsp/src/custom-id/dto/create-custom-id.dto.ts @@ -0,0 +1 @@ +export class CreateCustomIdDto {} diff --git a/bot-wsp/src/custom-id/dto/update-custom-id.dto.ts b/bot-wsp/src/custom-id/dto/update-custom-id.dto.ts new file mode 100644 index 0000000..763b817 --- /dev/null +++ b/bot-wsp/src/custom-id/dto/update-custom-id.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateCustomIdDto } from './create-custom-id.dto'; + +export class UpdateCustomIdDto extends PartialType(CreateCustomIdDto) {} diff --git a/bot-wsp/src/custom-id/entities/custom-id.entity.ts b/bot-wsp/src/custom-id/entities/custom-id.entity.ts new file mode 100644 index 0000000..b0bd69c --- /dev/null +++ b/bot-wsp/src/custom-id/entities/custom-id.entity.ts @@ -0,0 +1 @@ +export class CustomId {} diff --git a/bot-wsp/src/dashboard/dashboard.controller.ts b/bot-wsp/src/dashboard/dashboard.controller.ts new file mode 100644 index 0000000..014918f --- /dev/null +++ b/bot-wsp/src/dashboard/dashboard.controller.ts @@ -0,0 +1,22 @@ +import { Controller, ForbiddenException, Get, UseGuards } from '@nestjs/common'; +import { DashboardService } from './dashboard.service'; +import { AuthTokenGuard } from '../common/guards/auth-token.guard'; +import { AuthUser } from '../common/types'; +import { DashboardUser } from './dto/dashboard.dto'; +import { User } from '../common/decoratos/user.decorator'; + +@UseGuards(AuthTokenGuard) +@Controller('dashboard') +export class DashboardController { + constructor(private readonly dashboardService: DashboardService) { } + + + @Get() + async getDashboard(@User() user: AuthUser): Promise { + const allowed = user?.role === 'ADMIN' || user?.role === 'INSTRUCTOR'; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para ver el dashboard'); + } + return this.dashboardService.getDashboard(user); + } +} diff --git a/bot-wsp/src/dashboard/dashboard.module.ts b/bot-wsp/src/dashboard/dashboard.module.ts new file mode 100644 index 0000000..c42e9c3 --- /dev/null +++ b/bot-wsp/src/dashboard/dashboard.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common'; +import { DashboardService } from './dashboard.service'; +import { DashboardController } from './dashboard.controller'; +import { PrismaModule } from '../prisma/prisma.module'; + +@Module({ + controllers: [DashboardController], + providers: [DashboardService], + imports: [PrismaModule], + +}) +export class DashboardModule { } diff --git a/bot-wsp/src/dashboard/dashboard.service.ts b/bot-wsp/src/dashboard/dashboard.service.ts new file mode 100644 index 0000000..5aa1548 --- /dev/null +++ b/bot-wsp/src/dashboard/dashboard.service.ts @@ -0,0 +1,182 @@ +import { Injectable } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { DashboardUser } from './dto/dashboard.dto'; +import { AuthUser } from '../common/types'; +import { LogDirection, UserRole } from '@prisma/client'; +import dayjs from 'dayjs'; + +@Injectable() +export class DashboardService { + constructor(private prisma: PrismaService) { } + + async getDashboard(user: AuthUser): Promise { + const now = dayjs().startOf('day').toDate() //new Date(); + const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0); + const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999); + + //NOTE Primer INGRESS de hoy (inicio del día) + const currentAccess = await this.prisma.accessLog.findFirst({ + where: { + userId: user.id, + direction: LogDirection.INGRESS, + timestamp: { gte: start, lte: end }, + }, + orderBy: { timestamp: 'asc' }, + }); + + const previousIngress = await this.prisma.accessLog.findFirst({ + where: { + userId: user.id, + direction: LogDirection.INGRESS, + timestamp: currentAccess + ? { lt: currentAccess.timestamp } // anterior al primer INGRESS de hoy + : { lt: start }, // si hoy no hubo, el último antes de hoy + }, + orderBy: { timestamp: 'desc' }, // el más reciente anterior + }); + + + const nextSessions = await this.prisma.sessionDateSnapshot.findMany({ + where: { + session: { isActive: true }, + AND: { + dateRange: { start: { gte: now } }, + session: { + ...(user.role === UserRole.INSTRUCTOR ? { instructors: { some: { id: user.id } } } : {}), + } + } + }, + orderBy: { dateRange: { start: 'asc' } }, + take: 10, + select: { + id: true, + dateRange: { select: { start: true } }, + session: { + select: { + id: true, + description: true, + instructors: { select: { name: true } }, + }, + }, + }, + }); + + // Calcular sesiones activas e inactivas + const sessionsFilter = user.role === UserRole.INSTRUCTOR + ? { instructors: { some: { id: user.id } } } + : {}; + + const [activeSessions, inactiveSessions] = await Promise.all([ + this.prisma.session.count({ + where: { isActive: true, ...sessionsFilter } + }), + this.prisma.session.count({ + where: { isActive: false, ...sessionsFilter } + }) + ]); + + // Calcular usuarios activos e inactivos (solo para admin) + let usersData = { total: 0, active: 0, inactive: 0 }; + if (user.role !== UserRole.INSTRUCTOR) { + const [activeUsers, inactiveUsers] = await Promise.all([ + this.prisma.user.count({ where: { deleted: null } }), + this.prisma.user.count({ where: { deleted: { not: null } } }) + ]); + usersData = { + total: activeUsers + inactiveUsers, + active: activeUsers, + inactive: inactiveUsers + }; + } + + // Contar asistentes en sesiones activas + const assistantsCount = user.role === UserRole.INSTRUCTOR + ? await this.prisma.user.count({ + where: { + assistantSessions: { + some: { + isActive: true, + instructors: { some: { id: user.id } } + } + } + } + }) + : await this.prisma.user.count({ + where: { + assistantSessions: { + some: { isActive: true } + } + } + }); + + // Calcular facturas del mes actual: total, pagadas y adeudadas + const startOfMonth = dayjs().startOf('month').toDate(); + const endOfMonth = dayjs().endOf('month').toDate(); + + const [totalInvoices, paidInvoices, pendingInvoices] = await Promise.all([ + // Total de facturas del mes + this.prisma.invoice.count({ + where: { + dateInvoice: { + gte: startOfMonth, + lte: endOfMonth + } + } + }), + // Facturas pagadas (PAID o CANCELED) + this.prisma.invoice.count({ + where: { + dateInvoice: { + gte: startOfMonth, + lte: endOfMonth + }, + status: { + in: ['PAID', 'CANCELED'] + } + } + }), + // Facturas adeudadas (PENDING) + this.prisma.invoice.count({ + where: { + dateInvoice: { + gte: startOfMonth, + lte: endOfMonth + }, + status: 'PENDING' + } + }) + ]); + + const reponse: DashboardUser = { + message: 'OK', + accessLog: { + currentAccess: currentAccess?.timestamp ? currentAccess.timestamp.toISOString() : 'Sin registro', + lastAccess: previousIngress?.timestamp ? previousIngress.timestamp.toISOString() : 'Sin registro', + }, + cardDetails: { + sessions: { + total: activeSessions + inactiveSessions, + active: activeSessions, + inactive: inactiveSessions + }, + users: usersData, + assistants: assistantsCount, + invoices: { + total: totalInvoices, + paid: paidInvoices, + pending: pendingInvoices + }, + revenue: 0, // TODO: sumarizar desde tu tabla de pagos/suscripciones + }, + sessions: nextSessions.map(snapshot => ({ + id: snapshot.id, + description: snapshot.session.description, + instructors: snapshot.session.instructors.map(i => i.name).join(', '), + startDate: snapshot.dateRange.start.toISOString(), + })), + }; + + return reponse; + } + +} diff --git a/bot-wsp/src/dashboard/dto/create-dashboard.dto.ts b/bot-wsp/src/dashboard/dto/create-dashboard.dto.ts new file mode 100644 index 0000000..486209c --- /dev/null +++ b/bot-wsp/src/dashboard/dto/create-dashboard.dto.ts @@ -0,0 +1 @@ +export class CreateDashboardDto {} diff --git a/bot-wsp/src/dashboard/dto/dashboard.dto.ts b/bot-wsp/src/dashboard/dto/dashboard.dto.ts new file mode 100644 index 0000000..ee9d208 --- /dev/null +++ b/bot-wsp/src/dashboard/dto/dashboard.dto.ts @@ -0,0 +1,32 @@ +export type DashboardUser = { + message: string; + accessLog: { + currentAccess: string; + lastAccess: string; + }, + cardDetails: { + sessions: { + total: number; + active: number; + inactive: number; + }; + users: { + total: number; + active: number; + inactive: number; + }; + assistants: number; // total de usuarios inscriptos a clases activas + invoices: { + total: number; // total de facturas del mes actual + paid: number; // facturas pagadas (PAID o CANCELED) + pending: number; // facturas adeudadas (PENDING) + }; + revenue: number; + }, + sessions: { + id: string; + description: string; + instructors: string; + startDate: string; + }[] +} \ No newline at end of file diff --git a/bot-wsp/src/dashboard/dto/update-dashboard.dto.ts b/bot-wsp/src/dashboard/dto/update-dashboard.dto.ts new file mode 100644 index 0000000..1b2b5aa --- /dev/null +++ b/bot-wsp/src/dashboard/dto/update-dashboard.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateDashboardDto } from './create-dashboard.dto'; + +export class UpdateDashboardDto extends PartialType(CreateDashboardDto) {} diff --git a/bot-wsp/src/dashboard/entities/dashboard.entity.ts b/bot-wsp/src/dashboard/entities/dashboard.entity.ts new file mode 100644 index 0000000..3d15143 --- /dev/null +++ b/bot-wsp/src/dashboard/entities/dashboard.entity.ts @@ -0,0 +1 @@ +export class Dashboard {} diff --git a/bot-wsp/src/ia/dto/create-ia.dto.ts b/bot-wsp/src/ia/dto/create-ia.dto.ts new file mode 100644 index 0000000..9a34b2d --- /dev/null +++ b/bot-wsp/src/ia/dto/create-ia.dto.ts @@ -0,0 +1 @@ +export class CreateIaDto {} diff --git a/bot-wsp/src/ia/dto/update-ia.dto.ts b/bot-wsp/src/ia/dto/update-ia.dto.ts new file mode 100644 index 0000000..4bc06d8 --- /dev/null +++ b/bot-wsp/src/ia/dto/update-ia.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateIaDto } from './create-ia.dto'; + +export class UpdateIaDto extends PartialType(CreateIaDto) {} diff --git a/bot-wsp/src/ia/entities/ia.entity.ts b/bot-wsp/src/ia/entities/ia.entity.ts new file mode 100644 index 0000000..ae13044 --- /dev/null +++ b/bot-wsp/src/ia/entities/ia.entity.ts @@ -0,0 +1 @@ +export class Ia {} diff --git a/bot-wsp/src/ia/ia.controller.spec.ts b/bot-wsp/src/ia/ia.controller.spec.ts new file mode 100644 index 0000000..0a97ee4 --- /dev/null +++ b/bot-wsp/src/ia/ia.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { IaController } from './ia.controller'; +import { IaService } from './ia.service'; + +describe('IaController', () => { + let controller: IaController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [IaController], + providers: [IaService], + }).compile(); + + controller = module.get(IaController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/ia/ia.controller.ts b/bot-wsp/src/ia/ia.controller.ts new file mode 100644 index 0000000..c01bd45 --- /dev/null +++ b/bot-wsp/src/ia/ia.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +// import { IaService } from './ia.service'; +import { CreateIaDto } from './dto/create-ia.dto'; +import { UpdateIaDto } from './dto/update-ia.dto'; + +@Controller('ia') +export class IaController { + constructor() {} + + // @Post() + // create(@Body() createIaDto: CreateIaDto) { + // return this.iaService.create(createIaDto); + // } + + // @Get() + // findAll() { + // return this.iaService.findAll(); + // } + + // @Get(':id') + // findOne(@Param('id') id: string) { + // return this.iaService.findOne(+id); + // } + + // @Patch(':id') + // update(@Param('id') id: string, @Body() updateIaDto: UpdateIaDto) { + // return this.iaService.update(+id, updateIaDto); + // } + + // @Delete(':id') + // remove(@Param('id') id: string) { + // return this.iaService.remove(+id); + // } +} diff --git a/bot-wsp/src/ia/ia.module.ts b/bot-wsp/src/ia/ia.module.ts new file mode 100644 index 0000000..ffe9b01 --- /dev/null +++ b/bot-wsp/src/ia/ia.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common'; +// import { IaService } from './ia.service'; +import { IaController } from './ia.controller'; +import { PrismaModule } from '../prisma/prisma.module'; +import { HttpModule } from '@nestjs/axios'; +import { IaSubscriptionService } from './services/ia.subscription.service'; + +@Module({ + controllers: [IaController], + providers: [ + // // IaService, + IaSubscriptionService], + imports: [PrismaModule, HttpModule], + exports: [ + // // IaService, + IaSubscriptionService], +}) +export class IaModule { } diff --git a/bot-wsp/src/ia/ia.service.spec.ts b/bot-wsp/src/ia/ia.service.spec.ts new file mode 100644 index 0000000..82781e1 --- /dev/null +++ b/bot-wsp/src/ia/ia.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { IaService } from './ia.service'; + +describe('IaService', () => { + let service: IaService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [IaService], + }).compile(); + + service = module.get(IaService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/ia/ia.service.ts b/bot-wsp/src/ia/ia.service.ts new file mode 100644 index 0000000..27be87e --- /dev/null +++ b/bot-wsp/src/ia/ia.service.ts @@ -0,0 +1,498 @@ +// import { get_encoding, Tiktoken } from '@dqbd/tiktoken'; +// import { HttpService } from '@nestjs/axios'; +// import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; +// import { Prisma, UserRole } from '@prisma/client'; +// import dayjs from 'dayjs'; +// import { firstValueFrom } from 'rxjs'; +// import { PrismaService } from '../prisma/prisma.service'; +// import { buildPromptInferAction } from './prompts/buildPromptInferAction'; +// import { SessionsService } from '../sessions/sessions.service'; +// import { UserDataUpdate } from '../user/user.dto'; + + +// export type UserIntentEnum = +// | "payment_status" +// | "view_enrolled_classes" +// | "view_new_keys" +// | "enroll_new_classes"; + +// /** Intents permitidos por rol (ajusta si querés diferenciar más) */ +// const ROLE_ALLOWED: Record> = { +// [UserRole.ADMIN]: [ +// "payment_status", +// "view_enrolled_classes", +// "view_new_keys", +// "enroll_new_classes", +// ], +// [UserRole.INSTRUCTOR]: [ +// "payment_status", +// "view_enrolled_classes", +// "view_new_keys", +// "enroll_new_classes", +// ], +// [UserRole.USER]: [ +// "payment_status", +// "view_enrolled_classes", +// "view_new_keys", +// "enroll_new_classes", +// ], +// // Invitado: no puede ver pagos ni “mis clases” +// [UserRole.GUEST]: [], +// }; + +// /** Normaliza texto para matching robusto */ +// const norm = (s: string) => +// s +// .normalize("NFKD") +// .replace(/\p{Diacritic}/gu, "") +// .toLowerCase() +// .trim(); + +// /** Sinónimos rápidos por intent (ES + algo de EN) */ +// const KEYWORDS: Record = { +// payment_status: [ +// /pago(s)?\b/, +// /\bestado.*pago/, +// /\bestoy.*al dia/, +// /\bal dia\b/, +// /factur(a|as)|cuota|vencim(iento|entos)/, +// /\bpagar\b|\bpague\b/, +// /payment|paid|invoice|bill|due/, +// ], +// view_enrolled_classes: [ +// /mis?\s+clases/, +// /clases?.*inscrit[oa]s?/, +// /inscripc(ion|iones)\s+vigentes?/, +// /\bver\s+clases\b|\bmis\s+cursos?\b/, +// /matriculad[oa]s?/, +// /enrolled|my\s+classes|my\s+courses/, +// ], +// view_new_keys: [ +// /claves?\s+(nuevas?|disponibles?)/, +// /\bnuevas?\s+claves?\b/, +// /\bcodigos?\b|\baccesos?\b|\bkeys?\b/, +// /generate.*key|new.*key/, +// ], +// enroll_new_classes: [ +// /inscrib(irme|ir|irnos)|anotar(me)?|apuntar(me)?|registrar(me)?/, +// /inscripcion\s+nuev(a|as)|nuevas?\s+clases/, +// /\bquiero\s+(sumarme|anotarme|inscribirme)\b/, +// /enroll|sign\s*up|register.*class/, +// ], +// }; + +// /** Heurística: primer intent cuyo regex matchee */ +// const quickHeuristic = (text: string): UserIntentEnum | null => { +// const t = norm(text); +// for (const intent of Object.keys(KEYWORDS) as UserIntentEnum[]) { +// const found = KEYWORDS[intent].some((rx) => rx.test(t)); +// if (found) return intent; +// } +// return null; +// }; + +// /** Prompt builder acotado por rol */ +// export const buildPromptInferUserMenuAction = ( +// message: string, +// role: UserRole +// ): string => { +// const allowed = ROLE_ALLOWED[role]; +// const labels = allowed +// .map((k) => `"${k}"`) +// .join(", "); +// // Unos mini-ejemplos para anclar +// const examples = [ +// { in: "necesito ver si estoy al dia con mis pagos", out: "payment_status" }, +// { in: "quiero ver mis clases inscritas", out: "view_enrolled_classes" }, +// { in: "tienen nuevas claves de acceso?", out: "view_new_keys" }, +// { in: "quiero inscribirme a una clase nueva", out: "enroll_new_classes" }, +// ] +// // filtra ejemplos que no estén permitidos al rol para no confundir al modelo +// .filter((e) => (allowed as string[]).includes(e.out)) +// .map((e) => `Entrada: "${e.in}"\nRespuesta: "${e.out}"`) +// .join("\n\n"); + +// return ` +// Eres un asistente que clasifica la intención del usuario en una de las siguientes opciones PERMITIDAS según su rol (${role}): +// ${labels} + +// Analiza el siguiente mensaje y responde SOLO con una de esas claves exactas (sin texto adicional). +// Si la intención NO coincide con ninguna de las opciones permitidas, responde exactamente "null". + +// ${examples ? `\nEjemplos:\n\n${examples}\n` : ""} + +// Entrada: "${message}" +// Respuesta: +// `.trim(); +// }; + +// /** Timeout helper: evita congelar la UX si la IA tarda */ +// const withTimeout = async ( +// p: Promise, +// ms = 1200 +// ): Promise => +// Promise.race([ +// p, +// new Promise((_, rej) => setTimeout(() => rej(new Error("IA_TIMEOUT")), ms)), +// ]) as Promise; + +// /** Mapea string → intent válido o null */ +// const parseModelLabel = ( +// raw: string | null | undefined, +// allowed: ReadonlyArray +// ): UserIntentEnum | null => { +// if (!raw) return null; +// const cleaned = raw.replace(/[\s"'`]/g, "").toLowerCase(); + +// if (cleaned === "null") return null; + +// // Intent labels exactos +// const candidates: UserIntentEnum[] = [ +// "payment_status", +// "view_enrolled_classes", +// "view_new_keys", +// "enroll_new_classes", +// ]; + +// const match = candidates.find((c) => c === cleaned); +// if (!match) return null; + +// // Respeta permisos por rol +// return allowed.includes(match) ? match : null; +// }; + + +// export enum ActionsAdmin { +// CREATE_SESSION = 'create_session', +// GET_SESSIONS = 'get_sessions', +// UPDATE_USER = 'update_user', +// GET_USERS = 'get_users', +// } + +// //xport type SessionWithSchedules = Partial> +// @Injectable() +// export class IaService implements OnModuleInit { + +// constructor( +// private readonly httpService: HttpService, +// private prisma: PrismaService, +// ) { } + +// private readonly logger = new Logger(IaService.name); +// private readonly apiUrl = 'http://localhost:5000/v1/completions'; +// //@ts-ignores +// private tokenizer: Tiktoken; +// private readonly ctxSize = 4096; // tamaño de contexto que configuraste en el modelo +// private readonly maxTokens = 512; // tokens máximos que le permitimos al modelo generar +// private readonly safetyMargin = 10; // margen de seguridad + +// onModuleInit() { +// this.tokenizer = get_encoding('cl100k_base'); +// } + +// /** Implementa la llamada real a tu LLM/endpoint */ +// private async callModel(prompt: string): Promise { +// // TODO: reemplaza por tu cliente real (OpenAI, local, etc.) +// // Debe devolver el texto "payment_status" | ... | "null" +// throw new Error("callModelNot implemented"); +// } + +// async detectIntent( +// text: string, +// role: UserRole +// ): Promise { +// const allowed = ROLE_ALLOWED[role]; + +// // 1) Heurística rápida (barata y rápida) +// const byHeuristic = quickHeuristic(text); +// if (byHeuristic && allowed.includes(byHeuristic)) { +// return byHeuristic; +// } + +// // 2) LLM (con timeout) usando prompt limitado por rol +// try { +// const prompt = buildPromptInferUserMenuAction(text, role); +// const raw = await withTimeout(this.callModel(prompt), 1500) as string | null; +// const intent = parseModelLabel(raw, allowed); +// if (intent) return intent; +// } catch { +// // caemos a null si hay timeout/errores +// } + +// // 3) Nada concluyente +// return null; +// } + +// async getActionAdmin(input: string): Promise { +// try { +// const prompt = buildPromptInferAction(input); +// const response = await this.executePrompt(prompt) + +// if (!Object.values(ActionsAdmin).includes(response as ActionsAdmin)) { +// this.logger.error(`Acción no válida: ${response}`); +// throw new Error('La acción inferida no es válida.'); +// } +// return response as ActionsAdmin; +// } +// catch (error: any) { +// this.logger.error('Error al obtener la acción de administrador', error); +// throw new Error('No se pudo obtener la acción de administrador.'); +// } +// } + +// async getUserUpdatePayload(input: string): Promise { +// try { +// const prompt = this.buildPromptUpdateUser(input); +// const promptTokens = this.countTokens(prompt); +// // Validación: aseguramos que no exceda el tamaño de contexto +// if (promptTokens + this.maxTokens + this.safetyMargin > this.ctxSize) { +// this.logger.error(`Prompt demasiado largo. Tokens en prompt: ${promptTokens}`); +// throw new Error('El prompt es demasiado largo para el contexto disponible.'); +// } +// const { data } = await firstValueFrom( +// this.httpService.post(this.apiUrl, { +// prompt, +// max_tokens: 256, +// temperature: 0.2, +// stop: ['Entrada:', '\n\n'], +// }), +// ); + +// const { choices } = data; +// const choice = choices[0]; + +// if (choice.finish_reason !== 'stop') { +// throw new Error('La respuesta fue incompleta o abortada.'); +// } + +// const responseText = choice.text.trim(); + +// // Parseamos el JSON que viene como string +// const jsonResponse = JSON.parse(responseText); + +// const response: UserDataUpdate = { +// customId: jsonResponse.customId, +// name: jsonResponse.name, +// phone: jsonResponse.phone.replace(/\D/g, ''), // Eliminamos todo lo que no sea dígito +// birth: dayjs(jsonResponse.birth).toDate(), +// } + +// return response; +// } +// catch (error: any) { +// this.logger.error('Error al obtener el payload de actualización del usuario', error); +// throw new Error('No se pudo obtener el payload de actualización del usuario.'); +// } +// } + + +// //TODO cambiarle el nombre , lo que hace es parsear de natural a json +// // async createSession(input: string): Promise { +// // const prompt = this.buildPromptCreateSession(input); + +// // const promptTokens = this.countTokens(prompt); + +// // // Validación: aseguramos que no exceda el tamaño de contexto +// // if (promptTokens + this.maxTokens + this.safetyMargin > this.ctxSize) { +// // this.logger.error(`Prompt demasiado largo. Tokens en prompt: ${promptTokens}`); +// // throw new Error('El prompt es demasiado largo para el contexto disponible.'); +// // } +// // try { +// // const { data } = await firstValueFrom( +// // this.httpService.post(this.apiUrl, { +// // prompt, +// // max_tokens: 512, +// // temperature: 0.2, +// // stop: ['\n\n', 'Entrada:'], +// // }), +// // ); + +// // const { choices } = data; +// // const choice = choices[0]; + +// // if (choice.finish_reason !== 'stop') { +// // throw new Error('La respuesta fue incompleta o abortada.'); +// // } + +// // const responseText = choice.text.trim(); + +// // // Parseamos el JSON que viene como string +// // const jsonResponse = JSON.parse(responseText); + +// // const response: SessionWithSchedules = { +// // description: jsonResponse.description, +// // type: jsonResponse.type, +// // schedules: jsonResponse?.schedules?.map((item: any) => { +// // return { +// // dayOfWeek: item.dayOfWeek || null, +// // specificDate: item.specificDate ? dayjs(item.specificDate).toDate() : null, +// // startTime: dayjs(item.startDateTime).toDate(), +// // endTime: dayjs(item.endDateTime).toDate(), +// // } +// // }), +// // } +// // return response; +// // } catch (error) { +// // this.logger.error('Error al generar la sesión', error); +// // throw new Error('No se pudo generar la sesión.'); +// // } +// // } + +// private countTokens(text: string): number { +// const tokens = this.tokenizer.encode(text); +// return tokens.length; +// } + +// async executePrompt( +// prompt: string, +// options?: { +// maxTokens?: number; +// temperature?: number; +// stop?: string[]; +// } +// ): Promise { + +// const promptTokens = this.countTokens(prompt); + +// // Configuración por defecto +// const maxTokens = options?.maxTokens ?? 256; +// const temperature = options?.temperature ?? 0.2; +// const stop = options?.stop ?? ['Entrada:', '\n\n']; + +// if (promptTokens + maxTokens + this.safetyMargin > this.ctxSize) { +// this.logger.error(`Prompt demasiado largo. Tokens en prompt: ${promptTokens}`); +// throw new Error('El prompt es demasiado largo para el contexto disponible.'); +// } + +// const { data } = await firstValueFrom( +// this.httpService.post(this.apiUrl, { +// prompt, +// max_tokens: maxTokens, +// temperature, +// stop, +// }), +// ); + +// const { choices } = data; +// const choice = choices[0]; + +// if (choice.finish_reason !== 'stop') { +// throw new Error('La respuesta fue incompleta o abortada.'); +// } + +// const responseText = choice.text.trim(); + +// try { +// return JSON.parse(responseText) as T; +// } catch (error) { +// this.logger.error('Error al parsear la respuesta JSON:', error); +// throw new Error('La respuesta no es un JSON válido.'); +// } +// } + +// private buildPromptCreateSession(message: string): string { +// return ` +// Eres un asistente que solo responde en formato JSON válido y nunca agrega texto adicional. + +// Devuelve solo la estructura JSON con este formato: +// { +// "description": string, +// "type": "RECURRING" o "ONE_TIME", +// "schedules": [ +// { +// "dayOfWeek": string o null, +// "specificDate": string o null //en formato DD-MM-YYYY HH-mm , +// "startDateTime": string //en formato DD-MM-YYYY HH-mm, +// "endDateTime": string //en formato DD-MM-YYYY HH-mm +// } +// ] +// } + +// Reglas importantes: +// - Extrae siempre la fecha y hora que aparecen escritas en el mensaje. No inventes, no uses la fecha ni la hora actuales. +// - Si el mensaje contiene una fecha específica (por ejemplo, "2/7/2025"), úsala exactamente como aparece para los campos "specificDate", "startDateTime" y "endDateTime". +// - Si el evento es recurrente, usa palabras clave como "recurrente", "todos los", "cada", "se repite" para detectarlo. En ese caso, el campo "specificDate" debe ser null, "dayOfWeek" debe tener el nombre del día en inglés, y las horas deben colocarse con una fecha ficticia: "1970-01-01". +// - Si el evento es puntual, el campo "dayOfWeek" debe ser null y "specificDate" debe ser la fecha real extraída del mensaje. +// - Convierte siempre las horas al formato de 24 horas y en formato ISO: yyyy-mm-ddTHH:MM:SSZ. +// - Si el mensaje tiene un horario como "11:00AM - 14:00PM", interpreta que: +// - "11:00AM" es la hora de inicio +// - "14:00PM" es la hora de fin (corrige a formato 24h si es necesario) + +// Ejemplos: + +// Entrada: "Clase 'Zumba' 15/12/2025 de 8:30am a 10:00am" +// Respuesta: +// { +// "description": "Zumba", +// "type": "ONE_TIME", +// "schedules": [ +// { +// "dayOfWeek": null, +// "specificDate": "2025-12-15T08:30:00Z", +// "startDateTime": "2025-12-15T08:30:00Z", +// "endDateTime": "2025-12-15T10:00:00Z" +// } +// ] +// } + +// Entrada: "Clase Yoga recurrente lunes de 8:30am a 10:00am" +// Respuesta: +// { +// "description": "Yoga", +// "type": "RECURRING", +// "schedules": [ +// { +// "dayOfWeek": "Monday", +// "specificDate": null, +// "startDateTime": "1970-01-01T08:30:00Z", +// "endDateTime": "1970-01-01T10:00:00Z" +// } +// ] +// } + +// Entrada: ${message} +// Respuesta: +// `.trim(); +// } + + +// private buildPromptUpdateUser(message: string): string { +// return ` +// Eres un asistente que responde únicamente en formato JSON válido. No agregues texto adicional ni explicaciones. + +// Formato esperado: +// { +// "customId": string, // Ejemplo: "U-001" +// "name": string, // Nombre completo +// "phone": string, // Solo dígitos, sin espacios ni símbolos +// "birth": string // Fecha en formato ISO: YYYY-MM-DD +// } + +// Reglas: +// - El primer token siempre es el customId (ejemplo: U-001). +// - El nombre puede incluir espacios y letras, ignora palabras como "nombre". +// - El teléfono puede venir con espacios o símbolos, pero debes devolver solo los dígitos. +// - La fecha de nacimiento puede venir como DD/MM/YYYY o D/M/YYYY y debes convertirla a formato YYYY-MM-DD. + +// Ejemplo: +// Entrada: +// U-001 nombre Leandro Leones 3435077510 18/12/1995 + +// Salida: +// { +// "customId": "U-001", +// "name": "Leandro Leones", +// "phone": "3435077510", +// "birth": "1995-12-18" +// } + +// Entrada: +// ${message} +// Salida: +// `.trim(); +// } + + +// } + + diff --git a/bot-wsp/src/ia/prompts/buildPromptGetUser.ts b/bot-wsp/src/ia/prompts/buildPromptGetUser.ts new file mode 100644 index 0000000..f0c26b3 --- /dev/null +++ b/bot-wsp/src/ia/prompts/buildPromptGetUser.ts @@ -0,0 +1,42 @@ +export const buildPromptGetUser = (message: string): string => { + return ` +Eres un asistente que interpreta mensajes para buscar usuarios en la base de datos. + +Analiza el siguiente mensaje y responde solo con un JSON así: + +{ + "nombre": string | null, // nombre o parte del nombre del usuario a buscar, o null si no se especifica + "birthdayMonth": number | null // número del mes de cumpleaños del usuario (1 = enero, 12 = diciembre), o null si no se especifica +} + +Reglas: +- Si el usuario menciona un nombre o parte del nombre, debes colocar ese valor en "nombre". +- Si el usuario menciona un mes de cumpleaños (por ejemplo "cumpleaños en mayo"), debes colocar el número correspondiente en "birthdayMonth". +- Si no se especifica un dato, debes ponerlo como null. + +Ejemplos: +Entrada: "Buscar usuarios que se llaman Juan y cumplen en mayo" +Respuesta: +{ + "nombre": "Juan", + "birthdayMonth": 5 +} + +Entrada: "Buscar usuarios que cumplen en noviembre" +Respuesta: +{ + "nombre": null, + "birthdayMonth": 11 +} + +Entrada: "Buscar usuarios llamados María" +Respuesta: +{ + "nombre": "María", + "birthdayMonth": null +} + +Entrada: ${message} +Respuesta: + `.trim(); +}; diff --git a/bot-wsp/src/ia/prompts/buildPromptInferAction.ts b/bot-wsp/src/ia/prompts/buildPromptInferAction.ts new file mode 100644 index 0000000..2157d60 --- /dev/null +++ b/bot-wsp/src/ia/prompts/buildPromptInferAction.ts @@ -0,0 +1,27 @@ +export const buildPromptInferAction = (message: string): string => { + return ` +Eres un asistente que clasifica la intención de un usuario. + +Analiza el siguiente mensaje y devuelve solo una de las siguientes claves JSON válidas según la intención detectada: +- "create_session" si el usuario quiere crear una sesión, agendar, programar, registrar una clase o similar. +- "update_user" si el usuario quiere actualizar personales, cambiar nombre, cambiar teléfono, modificar información de usuario. +- "get_sessions" si el usuario quiere ver las sesiones, clases, horarios, agenda, calendario o similar. +- "get_users" si el usuario quiere ver o listar usuarios, personas, alumnos, estudiantes o similar. + +Solo responde la clave exacta sin agregar texto adicional. + +Ejemplo: +Entrada: "Quiero crear una nueva clase para mañana" +Respuesta: "create_session" + +Entrada: "Necesito actualizar el telefono del usuario U-001" +Respuesta: "update_user" + +Entrada: "Quiero ver las clases para mañana" +Respuesta: "get_sessions" + +Entrada: ${message} + +Respuesta: +`.trim(); +} diff --git a/bot-wsp/src/ia/prompts/promptGetSession.ts b/bot-wsp/src/ia/prompts/promptGetSession.ts new file mode 100644 index 0000000..95728f5 --- /dev/null +++ b/bot-wsp/src/ia/prompts/promptGetSession.ts @@ -0,0 +1,46 @@ +export const buildPromptGetSession = (message: string): string => { + return ` +Eres un asistente que interpreta mensajes para buscar sesiones en la base de datos. + +Analiza el siguiente mensaje y responde solo con un JSON así: + +{ + "modo": "filtrar" | "proxima", // "filtrar" si el usuario quiere buscar clases específicas, "proxima" si solo quiere saber cuál es la próxima clase sin filtros + "descripcion": string | null, // palabra clave (ej: yoga), o null + "instructor": string | null, // nombre del instructor, o null + "assistant": string | null, // nombre del asistente, o null + "temporalReference": string | null, // frase sobre fecha u hora, sin convertir. Ej: "lunes siguiente a las 11 AM" + "daysOfWeek": string[] // array con días de la semana en español, puede estar vacío +} + +Reglas: +- Si el usuario pregunta por "la próxima clase", "la siguiente clase", o algo similar, debes responder con modo: "proxima" y dejar los otros campos en null o vacío. +- Si el usuario busca por nombre de clase, día o instructor, responde con modo: "filtrar" y llena los campos correspondientes. + +Ejemplos: +Entrada: "Dame las clases del lunes siguiente a las 11 AM de yoga con el profesor Juan" +Respuesta: +{ + "modo": "filtrar", + "descripcion": "yoga", + "instructor": "Juan", + "assistant": null, + "temporalReference": "lunes siguiente a las 11 AM", + "daysOfWeek": ["LUNES"] +} + +Entrada: "¿Cuál es la próxima clase?" +Respuesta: +{ + "modo": "proxima", + "descripcion": null, + "instructor": null, + "assistant": null, + "temporalReference": null, + "daysOfWeek": [] +} + +Entrada: ${message} +Respuesta: +`.trim(); +} diff --git a/bot-wsp/src/ia/services/builderSubscriptionPrompt.ts b/bot-wsp/src/ia/services/builderSubscriptionPrompt.ts new file mode 100644 index 0000000..97cbf6f --- /dev/null +++ b/bot-wsp/src/ia/services/builderSubscriptionPrompt.ts @@ -0,0 +1,45 @@ +export const builderSubscriptionPrompt = (message: string): string => { + return ` +Eres un asistente que solo responde en formato JSON válido y nunca agrega texto adicional. + +Debes inferir y devolver solo la estructura JSON con este formato: +{ + "user": { + "name": string, + "customId": string | null + }, + "product": { + "description": string, + "customId": string | null + }, + "discount": number | null, + "mode": "assistant" | "instructor" +} + +Reglas: +- El "customId" es un string con el formato: una letra, seguida de un guion y tres caracteres (ejemplo: A-123). Si no está presente, devolver null. +- El "discount" debe ser un número si el mensaje hace referencia a un descuento, caso contrario devolver null. +- El "mode" debe ser "assistant" por defecto. Si el mensaje menciona que el usuario es un profesor o instructor, el modo debe ser "instructor". +- El nombre debe inferirse como el nombre completo de la persona mencionada. +- La descripción debe inferirse como el nombre de la clase o producto mencionado. + +Ejemplo: +Entrada: "Agregar a valentin romero a la clase de latino con un descuento del 30%" +Respuesta: +{ + "user": { + "name": "valentin romero", + "customId": null + }, + "product": { + "description": "latino", + "customId": null + }, + "discount": 30, + "mode": "assistant" +} + +Entrada: ${message} +Respuesta: +`.trim(); +} diff --git a/bot-wsp/src/ia/services/ia.subscription.service.ts b/bot-wsp/src/ia/services/ia.subscription.service.ts new file mode 100644 index 0000000..c9a45a3 --- /dev/null +++ b/bot-wsp/src/ia/services/ia.subscription.service.ts @@ -0,0 +1,255 @@ +import { HttpService } from '@nestjs/axios'; +import { Injectable, Logger } from '@nestjs/common'; +import { Session, User, Prisma, } from '@prisma/client'; +import { firstValueFrom, lastValueFrom } from 'rxjs'; +import { PrismaService } from '../../prisma/prisma.service'; +// import { IaService } from '../ia.service'; +import { link } from 'fs'; +import { builderSubscriptionPrompt } from './builderSubscriptionPrompt'; + +type SubscriptionWithDataInvoices = { + id: string; + userId: string; + sessionId: string; + base64: string; + linkPayment: string; +} + +type CreateInvoiceOdoo = { + user: { + userCode: string; + dni?: string; + } + product: { + description: string; + productCode: string; + amount: number; + } +} + +type ResponseInvoiceOdoo = { + linkPayment: string; + linkInvoice: string; // URL de la factura + invoice: string // base 64 +} + +type ResponseSubscribeFromNaturalMessage = { + message: string; + invoice64: string; + linkPayment: string; +} + + +type ProductsModels = Session + +@Injectable() +export class IaSubscriptionService { + private readonly logger = new Logger(IaSubscriptionService.name); + + constructor( + // private iaService: any, // Asegúrate de importar IaService correctamente + private readonly prisma: PrismaService, + private httpService: HttpService, // Asegúrate de importar HttpService si lo necesitas + ) { + this.logger.log('IaSubscriptionService initialized'); + } + + async subscribeFromNaturalMessage(input: string, esAdmin: boolean = false): Promise { + try { + //const a = await this.iaService. + type ResponseIaSubscription = { + user: { + name: string, + customId: string, + }, + product: { + description: string, + customId: string, + }, + discount?: number, + mode: 'assistant' | 'instructor', + } + const prompt = builderSubscriptionPrompt(input); + + const { data } = await firstValueFrom( + this.httpService.post(process.env.URL_IA!, { + prompt, + max_tokens: 256, + temperature: 0.2, + stop: ['Entrada:', '\n\n'], + }), + ); + + const { choices } = data; + const choice = choices[0]; + + if (choice.finish_reason !== 'stop') { + throw new Error('La respuesta fue incompleta o abortada.'); + } + + const responseText = choice.text.trim(); + + // Parseamos el JSON que viene como string + const jsonResponse = JSON.parse(responseText); + // TODO: Replace this with actual response from IA service + const response = jsonResponse as ResponseIaSubscription; + if (!response) { + throw new Error('No response from IA service'); + } + + const nameParts = response.user.name?.split(' ').filter(part => part.length >= 3) || []; + + if (nameParts.length < 2 && !response.user.customId) { + throw new Error('No se pudo inferir suficiente información para buscar el usuario.'); + } + + const whereConditions: any = {}; + + if (response.user.customId) { + whereConditions.customId = response.user.customId; + } else if (nameParts.length >= 2) { + whereConditions.AND = [ + { name: { contains: nameParts[0], mode: 'insensitive' } }, + { name: { contains: nameParts[nameParts.length - 1], mode: 'insensitive' } } + ]; + } + + const user = await this.prisma.user.findMany({ + where: whereConditions, + take: 1 + }); + + if (user.length === 0) { + throw new Error('User not found'); + } else if (user.length > 1) { + this.logger.warn(`Multiple users found for query: ${JSON.stringify(whereConditions)}. Using the first one.`); + } + + const descriptionParts = response.product.description?.split(' ').filter(part => part.length >= 3) || []; + + if (descriptionParts.length === 0 && !response.product.customId) { + throw new Error('No se pudo inferir suficiente información para buscar el producto.'); + } + + const whereProductConditions: any = {}; + + if (response.product.customId) { + whereProductConditions.customId = response.product.customId; + } else { + whereProductConditions.AND = [ + // oj que busca solo por el primer + { description: { contains: descriptionParts[0], mode: 'insensitive' } }, + // { description: { contains: descriptionParts[descriptionParts.length - 1], mode: 'insensitive' } } + ]; + } + const modelName = 'session'; // Asumiendo que el modelo es Session + const product = await this.prisma?.[modelName].findMany({ + where: whereProductConditions + }); + + if (product.length === 0) { + throw new Error('Producto no encontrado.'); + } + + if (product.length > 1) { + throw new Error('La búsqueda devolvió múltiples productos. Por favor, proporciona más información para identificarlo correctamente.'); + } + + if (!user || !product) { + throw new Error('User or product not found'); + } + + if (!response.mode) { + this.logger.debug(`No mode provided for subscription, defaulting to 'assistant'`); + } + + const subscribe = await this.subscribe(user[0], product[0], response.mode); + + const responseService = { + message: `User ${user[0].name} subscribed to product ${product[0].description} with mode ${response.mode}. Invoice ID: ${subscribe.id}`, + invoice64: subscribe.base64, // Asumiendo que la factura es un base64 + linkPayment: subscribe.linkPayment, // URL de pago + } + + return responseService + + } + catch (error: any) { + throw new Error(`Failed to subscribe: ${error.message}`); + } + } + + + // Ejemplo de método para suscribirse + async subscribe(user: User, product: ProductsModels, mode: 'assistant' | 'instructor'): Promise { + try { + this.logger.log(`User ${user.id} subscribed`); + + // Use explicit model access instead of dynamic string indexing + const updateProduct = await this.prisma.session.update({ + where: { id: product.id }, + data: { + ...(mode === 'instructor' ? { instructors: { connect: { id: user.id } } } : {}), // Conectar el usuario como instructor + ...(mode === 'assistant' ? { assistants: { connect: { id: user.id } } } : {}), // Conectar el usuario como asistente + } + }) + + const createInvoiceOdoo: CreateInvoiceOdoo = { + user: { + userCode: user.id, + dni: user.dni || undefined, // Asumiendo que el usuario tiene un campo dni + }, + product: { + description: updateProduct.description, + productCode: updateProduct.customId, + amount: updateProduct.amount || 11, // Monto ficticio + } + } + + const { data } = await lastValueFrom( + this.httpService.post( + process.env.URL_INVOICE_ODOO!, // URL ficticia del API de Odoo + createInvoiceOdoo as CreateInvoiceOdoo , { + headers: { + 'Content-Type': 'application/json', + }} + ) + ) + //@ts-ignore + const { invoice, linkInvoice, linkPayment } = data['result'] || {} + + // Crear factura directamente sin suscripción intermedia + const createdInvoice = await this.prisma.invoice.create({ + data: { + userId: user.id, + sessionId: product.id, + amount: product.amount || 1, // Monto ficticio + dateInvoice: new Date(), // Mes actual + base64Invoice: invoice, + linkPayment: linkPayment, + status: 'PENDING' + } + }); + + // Retornar en formato compatible + return { + id: createdInvoice.id, + userId: user.id, + sessionId: product.id, + base64: invoice, + linkPayment + }; + } + catch (error: any) { + + throw new Error(`Failed to subscribe user ${user.id}: ${error.message}`); + + } + } + + // Ejemplo de método para cancelar suscripción + unsubscribe(userId: string): string { + this.logger.log(`User ${userId} unsubscribed`); + return `User ${userId} unsubscribed successfully`; + } +} \ No newline at end of file diff --git a/bot-wsp/src/invoices/invoices.controller.spec.ts b/bot-wsp/src/invoices/invoices.controller.spec.ts new file mode 100644 index 0000000..5eb2eb7 --- /dev/null +++ b/bot-wsp/src/invoices/invoices.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { InvoicesController } from './invoices.controller'; +import { InvoicesService } from './invoices.service'; + +describe('InvoicesController', () => { + let controller: InvoicesController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [InvoicesController], + providers: [InvoicesService], + }).compile(); + + controller = module.get(InvoicesController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/invoices/invoices.controller.ts b/bot-wsp/src/invoices/invoices.controller.ts new file mode 100644 index 0000000..bcd5f98 --- /dev/null +++ b/bot-wsp/src/invoices/invoices.controller.ts @@ -0,0 +1,84 @@ +import { Controller, ForbiddenException, Get, Param, Res, NotFoundException, UseGuards, Put, Body } from '@nestjs/common'; +import { Response } from 'express'; +import { InvoicesService } from './invoices.service'; +import { User } from '~/common/decoratos/user.decorator'; +import { AuthUser } from '~/common/types'; +import { Invoice, UserRole, InvoiceStatus } from '@prisma/client'; +import { AuthTokenGuard } from '~/common/guards/auth-token.guard'; + +@Controller('invoices') +@UseGuards(AuthTokenGuard) +export class InvoicesController { + constructor(private readonly invoicesService: InvoicesService) { } + + @Get(':userId') + async getAttendeesSnapshot( + @Param('userId') userId: string, + @User() user: AuthUser, + ): Promise<(Invoice & { description: string })[] | null> { + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR || user?.id === userId; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para ver facturas'); + } + return this.invoicesService.findInvoicesByUserId(userId); + } + + @Get('download/:invoiceId') + async downloadInvoicePdf( + @Param('invoiceId') invoiceId: string, + @User() user: AuthUser, + @Res() res: Response, + ): Promise { + // Buscar la factura con las relaciones necesarias + const invoice = await this.invoicesService.findById(invoiceId); + if (!invoice) { + throw new NotFoundException('Factura no encontrada'); + } + + // Verificar permisos - debe ser admin, instructor o el dueño de la factura + const allowed = user?.role === UserRole.ADMIN || + user?.role === UserRole.INSTRUCTOR || + invoice.userId === user?.id; + + if (!allowed) { + throw new ForbiddenException('No tienes permisos para descargar esta factura'); + } + + // Verificar que la factura tiene contenido PDF + if (!invoice.base64Invoice) { + throw new NotFoundException('La factura no tiene contenido PDF disponible'); + } + + try { + // Decodificar el base64 + const pdfBuffer = Buffer.from(invoice.base64Invoice, 'base64'); + + // Configurar headers para la descarga + res.setHeader('Content-Type', 'application/pdf'); + res.setHeader('Content-Disposition', `attachment; filename="factura-${invoice.id}.pdf"`); + res.setHeader('Content-Length', pdfBuffer.length); + + // Enviar el archivo + res.send(pdfBuffer); + } catch (error) { + throw new NotFoundException('Error al procesar el archivo PDF'); + } + } + + @Put(':userId/:invoiceId') + async updateInvoiceStatus( + @Param('userId') userId: string, + @Param('invoiceId') invoiceId: string, + @Body('status') status: InvoiceStatus, + @User() user: AuthUser, + ): Promise { + // Verificar permisos - solo admin o instructor pueden actualizar facturas + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para actualizar facturas'); + } + + return this.invoicesService.updateInvoiceStatus(userId, invoiceId, status, user); + } + +} \ No newline at end of file diff --git a/bot-wsp/src/invoices/invoices.module.ts b/bot-wsp/src/invoices/invoices.module.ts new file mode 100644 index 0000000..b0c907b --- /dev/null +++ b/bot-wsp/src/invoices/invoices.module.ts @@ -0,0 +1,16 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { InvoicesService } from './invoices.service'; +import { InvoicesController } from './invoices.controller'; +import { PrismaModule } from '../prisma/prisma.module'; +import { OdooModule } from '../odoo/odoo.module'; + +@Module({ + imports: [ + PrismaModule, + forwardRef(() => OdooModule), + ], + controllers: [InvoicesController], + providers: [InvoicesService], + exports: [InvoicesService], +}) +export class InvoicesModule { } diff --git a/bot-wsp/src/invoices/invoices.service.spec.ts b/bot-wsp/src/invoices/invoices.service.spec.ts new file mode 100644 index 0000000..466a87f --- /dev/null +++ b/bot-wsp/src/invoices/invoices.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { InvoicesService } from './invoices.service'; + +describe('InvoicesService', () => { + let service: InvoicesService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [InvoicesService], + }).compile(); + + service = module.get(InvoicesService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/invoices/invoices.service.ts b/bot-wsp/src/invoices/invoices.service.ts new file mode 100644 index 0000000..1a54059 --- /dev/null +++ b/bot-wsp/src/invoices/invoices.service.ts @@ -0,0 +1,404 @@ +import { forwardRef, Inject, Injectable, InternalServerErrorException, Logger } from '@nestjs/common'; +import { Invoice, InvoiceStatus } from '@prisma/client'; +import dayjs from 'dayjs'; +import { OdooInvoiceInput } from '../odoo/entities/odoo.entity'; +import { OdooService } from '../odoo/odoo.service'; +import { PrismaService } from '../prisma/prisma.service'; +import { AuthUser } from '~/common/types'; + +@Injectable() +export class InvoicesService { + private logger = new Logger(InvoicesService.name); + constructor( + private prisma: PrismaService, + @Inject(forwardRef(() => OdooService)) + private readonly odooService: OdooService, + ) { } + + /** + * Comprueba si el usuario tiene alguna factura no pagada en el mes actual. + * @param userId ID del usuario + * @returns true si existe al menos una factura con status PENDING o CANCELED dentro del mes en curso + */ + async hasUnpaidInvoiceThisMonth(userId: string): Promise { + this.logger.log(`Checking unpaid invoices for user ${userId} in the current month`); + const startOfMonth = dayjs().startOf('month').toDate(); + const endOfMonth = dayjs().endOf('month').toDate(); + + const unpaidInvoice = await this.prisma.invoice.findFirst({ + where: { + userId, + status: { + in: [InvoiceStatus.PENDING] + }, + dateInvoice: { + gte: startOfMonth, + lte: endOfMonth + } + } + }); + + return !!unpaidInvoice; + } + + async getLinkPayment(userId: string): Promise { + try { + return 'www.mercadopago.com.ar/asd' + } + catch (error: any) { + this.logger.error(`Error getting payment link for user ${userId}: ${error.message}`); + return null; + } + } + /** + * Devuelve la suma de los precios efectivos de todas las sesiones + * en las que el usuario es asistente y que tienen al menos un día + * dentro del mes actual. + * + * @param userId ID del usuario + * @returns total en la moneda del sistema (Float) + */ + async getTotalAssistantSessionAmount(userId: string): Promise { + const startOfMonth = dayjs().startOf('month').toDate(); + const endOfMonth = dayjs().endOf('month').toDate(); + + // 1️⃣ Obtener todas las sesiones donde el usuario es asistente + const sessions = await this.prisma.session.findMany({ + where: { + assistants: { some: { id: userId } }, + }, + include: { + priceHistories: true, // historial de precios + }, + }); + + let total = 0; + + // 2️⃣ Para cada sesión, encontrar el precio que estaba vigente + // en el rango del mes y sumarlo + for (const s of sessions) { + // Usar la nueva lógica corregida para obtener el precio del mes + const priceForMonth = this.getCurrentPriceForDate(s, startOfMonth); + total += priceForMonth; + } + + this.logger.log( + `Total effective amount for assistants of user ${userId} this month: ${total}`, + ); + return total; + } + + async newInvoiceForSession(userId: string, sessionId: string, dateInvoice: Date = new Date(), prismaClient?: any) { + try { + // Usar el cliente de transacción si se proporciona, o el cliente normal + const client = prismaClient || this.prisma; + + // Obtener información de la sesión para el monto y descripción + const session = await client.session.findUnique({ + where: { id: sessionId }, + include: { priceHistories: true } + }); + + if (!session) { + this.logger.error(`Session not found: ${sessionId}`); + throw new InternalServerErrorException('Sesión no encontrada'); + } + + // Obtener el precio efectivo para el mes de la factura + const currentPrice = this.getCurrentPriceForDate(session, dateInvoice); + + const invoice = await client.invoice.create({ + data: { + userId, + sessionId, + amount: currentPrice, + dateInvoice, + status: InvoiceStatus.PENDING, + } + }); + + if (!invoice) { + this.logger.error(`Failed to create invoice for user ${userId} and session ${sessionId}`); + throw new InternalServerErrorException('Error al crear la factura'); + } + + // Crear factura en Odoo + const user = await client.user.findUnique({ where: { id: userId } }); + if (!user) { + this.logger.error(`User not found: ${userId}`); + throw new InternalServerErrorException('Usuario no encontrado'); + } + + const data: OdooInvoiceInput = { + product: { + amount: currentPrice, + description: session.description, + invoiceId: invoice.id, + sessionId: session.id + }, + user: { + dni: user.dni || '000000', + id: user.id + } + }; + + const facturaOdoo = await this.odooService.createInvoice(data); + + if (!facturaOdoo) { + this.logger.error(`Error creating invoice in Odoo for user ${userId} and session ${sessionId}`); + throw new InternalServerErrorException('Error al crear la factura en Odoo'); + } + + const updatedInvoice = await client.invoice.update({ + where: { id: invoice.id }, + data: { + base64Invoice: facturaOdoo.result.base64Invoice, + linkPayment: facturaOdoo.result.linkPayment, + } + }); + + this.logger.log(`Invoice created successfully for user ${userId} and session ${sessionId} with invoice ID ${updatedInvoice.id} , amount: ${updatedInvoice.amount}, dateService : ${dateInvoice}`); + return updatedInvoice; + } catch (error: any) { + this.logger.error(`Error creating invoice: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error al crear la factura'); + } + } + + /** + * Obtiene el precio vigente de una sesión para una fecha determinada + */ + private getCurrentPriceForDate(session: any, targetDate: Date): number { + if (!session.priceHistories?.length) { + return session.amount || 0; + } + + // Ordenar por fecha de inicio (más reciente primero) + const sortedHistory = session.priceHistories + .sort((a: any, b: any) => new Date(b.effectiveFrom).getTime() - new Date(a.effectiveFrom).getTime()); + + // Buscar el precio aplicable para la fecha objetivo + const applicablePrice = sortedHistory.find((h: any) => { + const from = new Date(h.effectiveFrom); + const to = h.effectiveTo ? new Date(h.effectiveTo) : null; + + // Si es el precio vigente (effectiveTo = null) y la fecha es posterior al inicio + if (!to && from <= targetDate) { + return true; + } + + // Si tiene fecha de fin, verificar que esté en el rango + if (to && from <= targetDate && targetDate < to) { + return true; + } + + return false; + }); + + return applicablePrice ? applicablePrice.amount : session.amount || 0; + } + + async findInvoiceThisMonthByUserId(userId: string): Promise<(Invoice & { description: string })[] | null> { + try { + const startOfMonth = dayjs().startOf('month').toDate(); + const endOfMonth = dayjs().endOf('month').toDate(); + + const invoices = await this.prisma.invoice.findMany({ + where: { + userId, + OR: [ + { + dateInvoice: { + gte: startOfMonth, + lte: endOfMonth + } + }, + { + status: InvoiceStatus.PENDING + } + ] + }, + include: { + session: true + } + }); + + const facturas: (Invoice & { description: string })[] = invoices.map(invoice => ({ + ...invoice, + description: invoice.session.description + })); + + return facturas || null; + } catch (error: any) { + this.logger.error(`Error fetching invoices for user ${userId}: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error al buscar las facturas'); + } + } + + async findInvoicesByUserId(userId: string): Promise<(Invoice & { description: string })[] | null> { + try { + const invoices = await this.prisma.invoice.findMany({ + where: { userId }, + include: { + session: true + } + }); + + const facturas: (Invoice & { description: string })[] = invoices.map(invoice => ({ + ...invoice, + description: invoice.session.description + })); + + return facturas || null; + } catch (error: any) { + this.logger.error(`Error fetching invoices for user ${userId}: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error al buscar las facturas'); + } + } + + async updateStatus(invoiceId: string, status: InvoiceStatus) { + try { + const invoice = await this.prisma.invoice.update({ + where: { id: invoiceId }, + data: { status } + }); + + return invoice; + } + catch (error: any) { + this.logger.error(`Error updating invoice status: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error al actualizar el estado de la factura'); + } + } + + async findById(id: string) { + try { + return await this.prisma.invoice.findUnique({ + where: { id }, + include: { + user: true, + session: true + } + }); + } catch (error: any) { + this.logger.error('Error al buscar invoice por id', error?.message); + throw new InternalServerErrorException('Error al buscar la factura'); + } + } + + async updateInvoiceStatus(userId: string, invoiceId: string, status: InvoiceStatus, actionBy?: AuthUser): Promise { + const actionByInfo = actionBy ? `${actionBy.name || actionBy.id} (${actionBy.role})` : 'Unknown'; + this.logger.log(`Updating invoice status - userId: ${userId}, invoiceId: ${invoiceId}, newStatus: ${status}, actionBy: ${actionByInfo}`); + + try { + // Verificar que la factura existe y pertenece al usuario + const invoice = await this.prisma.invoice.findFirst({ + where: { + id: invoiceId, + userId: userId + } + }); + + if (!invoice) { + this.logger.warn(`Invoice not found or doesn't belong to user - invoiceId: ${invoiceId}, userId: ${userId}, attemptedBy: ${actionByInfo}`); + throw new InternalServerErrorException('Factura no encontrada o no pertenece al usuario'); + } + + this.logger.log(`Found invoice - currentStatus: ${invoice.status}, updating to: ${status}, actionBy: ${actionByInfo}`); + + // Si el estado es PAID o CANCELED, actualizar en Odoo primero + if (status === InvoiceStatus.PAID || status === InvoiceStatus.CANCELED) { + this.logger.log(`Updating invoice status in Odoo - invoiceId: ${invoiceId}, status: ${status}`); + + try { + await this.odooService.updateInvoiceStatus(invoiceId, status); + this.logger.log(`Invoice status updated in Odoo successfully - invoiceId: ${invoiceId}`); + } catch (odooError: any) { + this.logger.error(`Failed to update invoice status in Odoo - invoiceId: ${invoiceId}, error: ${odooError.message}`); + throw new InternalServerErrorException(`Error al actualizar el estado en Odoo: ${odooError.message}`); + } + } + + // Actualizar el estado en la base de datos + const updatedInvoice = await this.prisma.invoice.update({ + where: { id: invoiceId }, + data: { status }, + include: { + user: true, + session: true + } + }); + + this.logger.log(`Invoice status updated successfully - invoiceId: ${invoiceId}, from: ${invoice.status} to: ${status}, by: ${actionByInfo}`); + + return updatedInvoice; + } catch (error: any) { + this.logger.error(`Error updating invoice status by ${actionByInfo}: ${error.message}`, error.stack); + + // Si el error ya es de Odoo, re-lanzarlo + if (error instanceof InternalServerErrorException) { + throw error; + } + + throw new InternalServerErrorException('Error al actualizar el estado de la factura'); + } + } + + /** + * Crea facturas para todos los usuarios asistentes de sesiones activas + * para el mes especificado (o mes actual si no se especifica) + */ + async createMonthlyInvoicesForActiveAssistants(month?: Date) { + try { + const targetMonth = month || new Date(); + const startOfMonth = dayjs(targetMonth).startOf('month').toDate(); + + this.logger.log(`Creating monthly invoices for ${dayjs(targetMonth).format('YYYY-MM')}`); + + // Obtener todas las sesiones activas con sus asistentes + const activeSessions = await this.prisma.session.findMany({ + where: { isActive: true }, + include: { + assistants: true, + priceHistories: true + } + }); + + const invoicesCreated = []; + + for (const session of activeSessions) { + for (const assistant of session.assistants) { + // Verificar que no exista ya una factura para este usuario, sesión y mes + const existingInvoice = await this.prisma.invoice.findFirst({ + where: { + userId: assistant.id, + sessionId: session.id, + dateInvoice: { + gte: startOfMonth, + lt: dayjs(targetMonth).endOf('month').toDate() + } + } + }); + + if (!existingInvoice) { + const invoice = await this.newInvoiceForSession( + assistant.id, + session.id, + startOfMonth + ); + invoicesCreated.push(invoice); + } + } + } + + this.logger.log(`Created ${invoicesCreated.length} invoices for ${dayjs(targetMonth).format('YYYY-MM')}`); + return invoicesCreated; + } + catch (error: any) { + this.logger.error(`Error creating monthly invoices: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error en la creación masiva de facturas'); + } + } + + +} diff --git a/bot-wsp/src/main.ts b/bot-wsp/src/main.ts new file mode 100644 index 0000000..6e237ab --- /dev/null +++ b/bot-wsp/src/main.ts @@ -0,0 +1,74 @@ +import { ValidationPipe } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; +import 'reflect-metadata'; +import { AppModule } from './app.module.js'; + +// ─── Silenciar logs verbosos de libsignal-node ──────────────────────────────── +// @whiskeysockets/libsignal-node emite console.info hardcodeado para gestión +// interna de sesiones E2E (Closing/Opening session, etc.). Es comportamiento +// normal del protocolo Signal; no aporta valor en producción. +const _originalConsoleInfo = console.info.bind(console); +const LIBSIGNAL_PATTERNS = [ + 'Closing session:', + 'Opening session:', + 'Removing old closed session:', + 'Migrating session to:', +]; +console.info = (...args: any[]) => { + const msg = String(args[0] ?? ''); + if (LIBSIGNAL_PATTERNS.some((p) => msg.includes(p))) return; + _originalConsoleInfo(...args); +}; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + + // Pipes de validación + app.useGlobalPipes(new ValidationPipe({ whitelist: true, transform: true })); + + // CORS + app.enableCors({ + origin: '*', + credentials: true, + }); + + // Configuración de Swagger + const config = new DocumentBuilder() + .setTitle('Bot WhatsApp API') + .setDescription('API de gestión de usuarios, sesiones, asistencia, facturación y configuración del sistema') + .setVersion('1.0') + .addBearerAuth( + { + type: 'http', + scheme: 'bearer', + bearerFormat: 'JWT', + description: 'Ingresa tu token de autenticación', + }, + 'bearer', + ) + .addTag('Configuración del Sistema', 'Endpoints para gestionar la configuración dinámica del sistema') + .addTag('Autenticación', 'Endpoints de autenticación y gestión de tokens') + .addTag('Usuarios', 'Gestión de usuarios del sistema') + .addTag('Sesiones', 'Gestión de sesiones y clases') + .addTag('Facturas', 'Gestión de facturación') + .addTag('Asistencia', 'Control de asistencia') + .addTag('WhatsApp', 'Estado y gestión del bot de WhatsApp') + .build(); + + const document = SwaggerModule.createDocument(app, config); + SwaggerModule.setup('api/docs', app, document, { + customSiteTitle: 'Bot WhatsApp API - Documentación', + customfavIcon: 'https://nestjs.com/img/logo-small.svg', + customCss: '.swagger-ui .topbar { display: none }', + }); + + const port = process.env.PORT || 3001; + await app.listen(Number(port), '0.0.0.0'); + console.log(`Server running on http://localhost:${port}`); + console.log(`Swagger documentation available at http://localhost:${port}/api/docs`); +} +bootstrap().catch((err) => { + console.error('Error starting application:', err); + process.exit(1); +}); diff --git a/bot-wsp/src/odoo/entities/odoo.entity.ts b/bot-wsp/src/odoo/entities/odoo.entity.ts new file mode 100644 index 0000000..9b6632d --- /dev/null +++ b/bot-wsp/src/odoo/entities/odoo.entity.ts @@ -0,0 +1,29 @@ + +export type OdooInvoiceInput = { + user: { + id: string; + dni: string; + }, + product: { + description: string; + invoiceId: string; + sessionId: string; + amount: number; + } +} + +export type OdooInvoiceResponse = { + jsonrpc: string, + id: string, + result: { + invoiceId: string; + base64Invoice: string; // PDF en base64 + linkPayment: string; // URL para pagar la factura +}} + + +export type OdooWebhook = { + invoiceId: string; + status: 'PENDING' | 'PAID' | 'CANCELED'; +} + diff --git a/bot-wsp/src/odoo/odoo.controller.spec.ts b/bot-wsp/src/odoo/odoo.controller.spec.ts new file mode 100644 index 0000000..832a833 --- /dev/null +++ b/bot-wsp/src/odoo/odoo.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OdooController } from './odoo.controller'; +import { OdooService } from './odoo.service'; + +describe('OdooController', () => { + let controller: OdooController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [OdooController], + providers: [OdooService], + }).compile(); + + controller = module.get(OdooController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/odoo/odoo.controller.ts b/bot-wsp/src/odoo/odoo.controller.ts new file mode 100644 index 0000000..11e14a6 --- /dev/null +++ b/bot-wsp/src/odoo/odoo.controller.ts @@ -0,0 +1,19 @@ +import { Body, Controller, Post, Res } from '@nestjs/common'; +import { OdooWebhook } from './entities/odoo.entity'; +import { OdooService } from './odoo.service'; +import { Response } from 'express'; + +@Controller('odoo') +export class OdooController { + constructor(private readonly odooService: OdooService) { } + + @Post('/webhook') + async webhook( + @Body() data: OdooWebhook, + @Res() res: Response + ) { + await this.odooService.webhook(data); + return res.status(200).send('OK'); + } + +} diff --git a/bot-wsp/src/odoo/odoo.module.ts b/bot-wsp/src/odoo/odoo.module.ts new file mode 100644 index 0000000..e321c6f --- /dev/null +++ b/bot-wsp/src/odoo/odoo.module.ts @@ -0,0 +1,15 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { OdooService } from './odoo.service'; +import { OdooController } from './odoo.controller'; +import { HttpModule } from '@nestjs/axios'; +import { InvoicesModule } from '../invoices/invoices.module'; + +@Module({ + controllers: [OdooController], + providers: [OdooService], + imports: [HttpModule, + forwardRef(() => InvoicesModule), + ], + exports: [OdooService], +}) +export class OdooModule { } diff --git a/bot-wsp/src/odoo/odoo.service.spec.ts b/bot-wsp/src/odoo/odoo.service.spec.ts new file mode 100644 index 0000000..3285f19 --- /dev/null +++ b/bot-wsp/src/odoo/odoo.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OdooService } from './odoo.service'; + +describe('OdooService', () => { + let service: OdooService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [OdooService], + }).compile(); + + service = module.get(OdooService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/odoo/odoo.service.ts b/bot-wsp/src/odoo/odoo.service.ts new file mode 100644 index 0000000..808a3e4 --- /dev/null +++ b/bot-wsp/src/odoo/odoo.service.ts @@ -0,0 +1,258 @@ +import { HttpService } from '@nestjs/axios'; +import { + BadRequestException, + forwardRef, + Inject, + Injectable, + InternalServerErrorException, + Logger, +} from '@nestjs/common'; +import { firstValueFrom } from 'rxjs'; +import { OdooInvoiceInput, OdooInvoiceResponse, OdooWebhook } from './entities/odoo.entity'; +import { InvoicesService } from '../invoices/invoices.service'; +import { randomUUID } from 'crypto'; +import type { AxiosError } from 'axios'; + +@Injectable() +export class OdooService { + private readonly logger = new Logger(OdooService.name); + private readonly url: string; + private readonly httpTimeoutMs: number; + + constructor( + private readonly httpService: HttpService, + @Inject(forwardRef(() => InvoicesService)) // 👈 rompe el ciclo + private readonly invoicesService: InvoicesService, + ) { + const url = process.env.URL_ODOO; + if (!url) { + this.logger.error('Odoo URL is not defined in environment variables'); + throw new Error('Odoo URL is not defined'); + } + this.url = url; + this.httpTimeoutMs = Number(process.env.ODOO_HTTP_TIMEOUT ?? 10_000); + + this.logger.log(`Server Odoo URL: ${this.url}`); + } + + /** Crea una factura en Odoo con reintentos, logs y validación mínima */ + async createInvoice( + data: OdooInvoiceInput, + opts?: { correlationId?: string; retries?: number; timeoutMs?: number }, + ): Promise { + const correlationId = opts?.correlationId ?? randomUUID(); + const retries = Math.max(0, opts?.retries ?? 1); + const timeoutMs = opts?.timeoutMs ?? this.httpTimeoutMs; + //NOTE PATH ENDPOINT FACTURAS + const endpoint = `${this.url}/account/move/create`; + const startedAt = Date.now(); + + this.logger.log( + `[${correlationId}] ➜ POST ${endpoint} | user=${data?.user?.id ?? '—'} amount=${data?.product?.amount ?? '—'}`, + ); + + let lastErr: unknown; + + for (let attempt = 0; attempt <= retries; attempt++) { + const attemptStr = `${attempt + 1}/${retries + 1}`; + + try { + const { data: invoice } = await firstValueFrom( + this.httpService.post(endpoint, data, { + timeout: timeoutMs, + headers: { + 'x-correlation-id': correlationId, + 'content-type': 'application/json', + + }, + }), + ); + + if (!invoice || typeof invoice !== 'object') { + throw new Error('Respuesta vacía o inválida de Odoo'); + } + + // { + // jsonrpc: "2.0", + // id: null, + // result: { + // invoiceId: "cmgiqfqhn0002wfpc11g7xdfj", + // base64Invoice: "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Pj4KZW5kb2JqCjI3IDAgb2JqCjw8IC9MZW5ndGggODMzID4+CnN0cmVhbQovQ0lESW5pdCAvUHJvY1NldCBmaW5kcmVzb3VyY2UgYmVnaW4KMTIgZGljdCBiZWdpbgpiZWdpbmNtYXAKL0NJRFN5c3RlbUluZm8gPDwgL1JlZ2lzdHJ5IChBZG9iZSkgL09yZGVyaW5nIChVQ1MpIC9TdXBwbGVtZW50IDAgPj4gZGVmCi9DTWFwTmFtZSAvQWRvYmUtSWRlbnRpdHktVUNTIGRlZgovQ01hcFR5cGUgMiBkZWYKMSBiZWdpbmNvZGVzcGFjZXJhbmdlCjwwMDAwPiA8RkZGRj4KZW5kY29kZXNwYWNlcmFuZ2UKMiBiZWdpbmJmcmFuZ2UKPDAwMDA+IDwwMDAwPiA8MDAwMD4KPDAwMDE+IDwwMDQzPiBbPDAwNDM+IDwwMDZDPiA8MDA2OT4gPDAwNjU+IDwwMDZFPiA8MDA3ND4gPDAwM0E+IDwwMDIwPiA8MDAzMj4gPDAwNkY+IDwwMDY0PiA8MDAyRT4gPDAwNDk+IDwwMDU2PiA8MDA0MT4gPDAwNzM+IDwwMDc1PiA8MDA2RD4gPDAwNzI+IDwwMDQ2PiA8MDA2MT4gPDAwNDQ+IDwwMDRFPiA8MDAzMT4gPDAwMzM+IDwwMDYzPiA8MDA2OD4gPDAwNzY+IDwwMDMwPiA8MDAzOT4gPDAwMkY+IDwwMDM1PiA8MDA1Mj4gPDAwNjY+IDwwMDY3PiA8MDA3MT4gPDAwNzc+IDwwMDcwPiA8MDAzNz4gPDAwNzg+IDwwMDZBPiA8MDA1MD4gPDAwNDU+IDwwMDUzPiA8MDBEMz4gPDAwNTQ+IDwwMDRGPiA8MDA1NT4gPDAwNEQ+IDwwMDQ3PiA8MDAyQz4gPDAwMjQ+IDwwMEU5PiA8MDAyOD4gPDAwNEM+IDwwMDc5PiA8MDAzND4gPDAwMjk+IDwwMDQyPiA8MDAzNj4gPDAwNjI+IDwwMDJEPiA8MDAyQj4gPDAwMzg+IDwwMDQwPiA8MDBGQT4gPDAwRTE+IF0KZW5kYmZyYW5nZQplbmRjbWFwCkNNYXBOYW1lIGN1cnJlbnRkaWN0IC9DTWFwIGRlZmluZXJlc291cmNlIHBvcAplbmQKZW5kCgplbmRzdHJlYW0KZW5kb2JqCjEwIDAgb2JqCjw8IC9UeXBlIC9Gb250Ci9TdWJ0eXBlIC9UeXBlMAovQmFzZUZvbnQgL09wZW5TYW5zLVJlZ3VsYXIKL0VuY29kaW5nIC9JZGVudGl0eS1ICi9EZXNjZW5kYW50Rm9udHMgWzI2IDAgUl0KL1RvVW5pY29kZSAyNyAwIFI+PgplbmRvYmoKMiAwIG9iago8PAovVHlwZSAvUGFnZXMKL0tpZHMgClsKNSAwIFIKXQovQ291bnQgMQovUHJvY1NldCBbL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUNdCj4+CmVuZG9iagp4cmVmCjAgMjkKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDA5IDAwMDAwIG4gCjAwMDAwNDY5MzggMDAwMDAgbiAKMDAwMDAwMDE2MSAwMDAwMCBuIAowMDAwMDAwMjU2IDAwMDAwIG4gCjAwMDAwMzQ5ODUgMDAwMDAgbiAKMDAwMDAwMDI5MyAwMDAwMCBuIAowMDAwMDAzNzQxIDAwMDAwIG4gCjAwMDAwMDM3NjEgMDAwMDAgbiAKMDAwMDAxMDM3OSAwMDAwMCBuIAowMDAwMDQ2Nzk1IDAwMDAwIG4gCjAwMDAwMTAzOTkgMDAwMDAgbiAKMDAwMDAxMDQ0NSAwMDAwMCBuIAowMDAwMDEwNTAxIDAwMDAwIG4gCjAwMDAwMTQ4MDYgMDAwMDAgbiAKMDAwMDAxNDgyNyAwMDAwMCBuIAowMDAwMDE4ODQyIDAwMDAwIG4gCjAwMDAwMTg4NjMgMDAwMDAgbiAKMDAwMDAzNDkxMyAwMDAwMCBuIAowMDAwMDM0OTM1IDAwMDAwIG4gCjAwMDAwMzUzNjUgMDAwMDAgbiAKMDAwMDAzOTM3OCAwMDAwMCBuIAowMDAwMDM1MTA2IDAwMDAwIG4gCjAwMDAwMzUzNDUgMDAwMDAgbiAKMDAwMDAzOTM5OSAwMDAwMCBuIAowMDAwMDM5NjY1IDAwMDAwIG4gCjAwMDAwNDU0MjIgMDAwMDAgbiAKMDAwMDA0NTkxMCAwMDAwMCBuIAowMDAwMDQ1NDAxIDAwMDAwIG4gCnRyYWlsZXIKPDwKL1NpemUgMjkKL0luZm8gMSAwIFIKL1Jvb3QgMTkgMCBSCj4+CnN0YXJ0eHJlZgo0NzAzNgolJUVPRgo=", + // linkPayment: "url_de_mercadopago_o_payu", + // }, + // } + if (!invoice.result.invoiceId) { + throw new Error('Odoo no devolvió id de factura'); + } + + const duration = Date.now() - startedAt; + this.logger.log( + `[${correlationId}] ✓ Invoice creada (attempt ${attemptStr}) en ${duration}ms | id=${invoice.result.invoiceId}`, + ); + return invoice; + } catch (error) { + lastErr = error; + const ax = error as AxiosError; + const status = ax?.response?.status; + const code = ax?.code; + const resp = ax?.response?.data; + const truncated = this.truncateSafe(resp); + + this.logger.error( + `[${correlationId}] ✗ Error creando invoice (attempt ${attemptStr}) code=${code ?? '—'} status=${status ?? '—'} msg=${ax?.message ?? error} resp=${truncated}`, + ); + + const shouldRetry = + attempt < retries && + ( + !ax?.isAxiosError || // error no-axios (posible red) + (status && status >= 500) || // 5xx + code === 'ECONNABORTED' || + code === 'ETIMEDOUT' || + code === 'ECONNREFUSED' || + code === 'ENOTFOUND' + ); + + if (shouldRetry) { + const backoffMs = 300 * (attempt + 1); + this.logger.warn(`[${correlationId}] Reintentando en ${backoffMs}ms…`); + await new Promise((r) => setTimeout(r, backoffMs)); + continue; + } + break; + } + } + + const duration = Date.now() - startedAt; + this.logger.error( + `[${correlationId}] ✗ Falló crear invoice tras ${retries + 1} intento(s) en ${duration}ms | últimoError=${this.truncateSafe((lastErr as any)?.message || String(lastErr))}`, + ); + throw new InternalServerErrorException('Error al crear la factura en Odoo'); + } + + /** Webhook desde Odoo → idempotente + validación de estado + logs */ + async webhook(data: OdooWebhook, headers?: Record) { + const correlationId = (headers?.['x-correlation-id'] || headers?.['X-Correlation-Id'] || randomUUID()).toString(); + const { invoiceId, status } = data ?? ({} as OdooWebhook); + + this.logger.log( + `[${correlationId}] 🔔 Webhook recibido invoiceId=${invoiceId ?? '—'} status=${status ?? '—'}`, + ); + + // Validación de payload + if (!invoiceId) { + this.logger.error(`[${correlationId}] Webhook inválido: falta invoiceId`); + throw new BadRequestException('invoiceId requerido'); + } + if (!this.isAllowedStatus(status)) { + this.logger.error(`[${correlationId}] Webhook inválido: status no permitido (${status})`); + throw new BadRequestException('status inválido'); + } + + // Buscar factura local + const invoice = await this.invoicesService.findById(invoiceId); + if (!invoice) { + this.logger.warn(`[${correlationId}] Invoice ${invoiceId} no encontrada`); + // Podrías devolver 200 para no reintento: return { message: 'ok' }; + throw new InternalServerErrorException('Factura no encontrada'); + } + + // Actualizar estado + await this.invoicesService.updateStatus(invoiceId, status); + this.logger.log(`[${correlationId}] ✓ Invoice ${invoiceId} actualizada a ${status}`); + + // TODO: notificar al usuario (WhatsApp, email, push) + return { message: 'Webhook processed' }; + } + + /** + * Actualiza el estado de una factura en Odoo (para PAID o CANCELED) + */ + async updateInvoiceStatus( + invoiceId: string, + status: 'PAID' | 'CANCELED', + opts?: { correlationId?: string; retries?: number; timeoutMs?: number } + ): Promise<{ success: boolean; message: string }> { + const correlationId = opts?.correlationId ?? randomUUID(); + const retries = Math.max(0, opts?.retries ?? 1); + const timeoutMs = opts?.timeoutMs ?? this.httpTimeoutMs; + + // Determinar el endpoint según el estado + const endpoint = status === 'PAID' + ? `${this.url}/account/move/paid` + : `${this.url}/account/move/cancel` + + const startedAt = Date.now(); + + this.logger.log( + `[${correlationId}] → POST ${endpoint} | status=${status}, invoiceId=${invoiceId}, retries=${retries}`, + ); + + let lastError: any = null; + + for (let attempt = 0; attempt <= retries; attempt++) { + try { + const { data } = await firstValueFrom( + this.httpService.post( + endpoint, + { invoiceId }, + { + timeout: timeoutMs, + headers: { + 'Content-Type': 'application/json', + 'X-Correlation-ID': correlationId, + }, + }, + ), + ); + + const elapsed = Date.now() - startedAt; + this.logger.log( + `[${correlationId}] ✓ Odoo responded OK in ${elapsed}ms | attempt=${attempt + 1}/${retries + 1}`, + ); + + return { success: true, message: data?.message || 'Status updated in Odoo' }; + } catch (err: any) { + lastError = err; + const elapsed = Date.now() - startedAt; + const isTimeout = err.code === 'ECONNABORTED' || err.code === 'ETIMEDOUT'; + const statusCode = (err as AxiosError)?.response?.status; + + this.logger.warn( + `[${correlationId}] ✗ Odoo error (attempt ${attempt + 1}/${retries + 1}) in ${elapsed}ms | ` + + `status=${statusCode}, code=${err.code}, isTimeout=${isTimeout}`, + ); + + // Si es el último intento, lanzar error + if (attempt === retries) { + this.logger.error( + `[${correlationId}] Failed to update invoice status in Odoo after ${retries + 1} attempts`, + ); + throw new InternalServerErrorException( + `Error al actualizar el estado en Odoo: ${err.message}`, + ); + } + + // Esperar antes del siguiente intento + await new Promise(resolve => setTimeout(resolve, 500 * (attempt + 1))); + } + } + + throw new InternalServerErrorException('Error al actualizar el estado en Odoo'); + } + + // ---------------- Helpers ---------------- + + private truncateSafe(payload: any, max = 800): string { + try { + const str = typeof payload === 'string' ? payload : JSON.stringify(payload); + return str.length > max ? `${str.slice(0, max)}…(+${str.length - max}b)` : str; + } catch { + return '[unserializable]'; + } + } + + private isAllowedStatus(s: unknown): s is OdooWebhook['status'] { + return s === 'PENDING' || s === 'PAID' || s === 'CANCELED'; + } +} diff --git a/bot-wsp/src/prisma/prisma.module.ts b/bot-wsp/src/prisma/prisma.module.ts new file mode 100644 index 0000000..970f7f5 --- /dev/null +++ b/bot-wsp/src/prisma/prisma.module.ts @@ -0,0 +1,10 @@ +// src/prisma/prisma.module.ts +import { Global, Module } from '@nestjs/common'; +import { PrismaService } from './prisma.service.js'; + +@Global() +@Module({ + providers: [PrismaService], + exports: [PrismaService], +}) +export class PrismaModule {} diff --git a/bot-wsp/src/prisma/prisma.service.ts b/bot-wsp/src/prisma/prisma.service.ts new file mode 100644 index 0000000..3939963 --- /dev/null +++ b/bot-wsp/src/prisma/prisma.service.ts @@ -0,0 +1,11 @@ +// src/prisma/prisma.service.ts +import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common'; +import { PrismaClient } from '@prisma/client'; + +@Injectable() +export class PrismaService + extends PrismaClient + implements OnModuleInit, OnModuleDestroy { + async onModuleInit() { await this.$connect(); } + async onModuleDestroy() { await this.$disconnect(); } +} diff --git a/bot-wsp/src/rfid/dto/create-rfid.dto.ts b/bot-wsp/src/rfid/dto/create-rfid.dto.ts new file mode 100644 index 0000000..ca4f224 --- /dev/null +++ b/bot-wsp/src/rfid/dto/create-rfid.dto.ts @@ -0,0 +1 @@ +export class CreateRfidDto {} diff --git a/bot-wsp/src/rfid/dto/update-rfid.dto.ts b/bot-wsp/src/rfid/dto/update-rfid.dto.ts new file mode 100644 index 0000000..c50f3f6 --- /dev/null +++ b/bot-wsp/src/rfid/dto/update-rfid.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateRfidDto } from './create-rfid.dto'; + +export class UpdateRfidDto extends PartialType(CreateRfidDto) {} diff --git a/bot-wsp/src/rfid/entities/rfid.entity.ts b/bot-wsp/src/rfid/entities/rfid.entity.ts new file mode 100644 index 0000000..79f5227 --- /dev/null +++ b/bot-wsp/src/rfid/entities/rfid.entity.ts @@ -0,0 +1 @@ +export class Rfid {} diff --git a/bot-wsp/src/rfid/rfid.controller.spec.ts b/bot-wsp/src/rfid/rfid.controller.spec.ts new file mode 100644 index 0000000..9f09b21 --- /dev/null +++ b/bot-wsp/src/rfid/rfid.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { RfidController } from './rfid.controller'; +import { RfidService } from './rfid.service'; + +describe('RfidController', () => { + let controller: RfidController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [RfidController], + providers: [RfidService], + }).compile(); + + controller = module.get(RfidController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/rfid/rfid.controller.ts b/bot-wsp/src/rfid/rfid.controller.ts new file mode 100644 index 0000000..38b94e1 --- /dev/null +++ b/bot-wsp/src/rfid/rfid.controller.ts @@ -0,0 +1,19 @@ +import { Body, Controller, Header, HttpCode, Post } from '@nestjs/common'; +import { RfidService } from './rfid.service'; + +@Controller('rfid') +// TODO ponerle un token estatico a los lectores RFID ? +// @UseGuards(AuthTokenGuard) +export class RfidController { + constructor(private readonly rfidService: RfidService) { } + + + @Post('ping') + @HttpCode(200) + @Header('Content-Type', 'text/plain') + async ping(@Body('id') uid: string): Promise { + console.log(`RFID ping recibido con id=${uid}`); + await this.rfidService.ping(uid); + return 'ok' + } +} diff --git a/bot-wsp/src/rfid/rfid.module.ts b/bot-wsp/src/rfid/rfid.module.ts new file mode 100644 index 0000000..1ca3e08 --- /dev/null +++ b/bot-wsp/src/rfid/rfid.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { InvoicesModule } from '../invoices/invoices.module'; +import { AttendanceModule } from '../attendance/attendance.module'; +import { UserModule } from '../user/user.module'; +import { WhatsappModule } from '../whatsapp/whatsapp.module'; +import { RfidController } from './rfid.controller'; +import { RfidService } from './rfid.service'; +import { AuthModule } from '~/auth/auth.module'; + +@Module({ + controllers: [RfidController], + providers: [RfidService], + imports: [UserModule,AttendanceModule,WhatsappModule,AttendanceModule,InvoicesModule,AuthModule] +}) +export class RfidModule { } diff --git a/bot-wsp/src/rfid/rfid.service.spec.ts b/bot-wsp/src/rfid/rfid.service.spec.ts new file mode 100644 index 0000000..b01fc34 --- /dev/null +++ b/bot-wsp/src/rfid/rfid.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { RfidService } from './rfid.service'; + +describe('RfidService', () => { + let service: RfidService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [RfidService], + }).compile(); + + service = module.get(RfidService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/rfid/rfid.service.ts b/bot-wsp/src/rfid/rfid.service.ts new file mode 100644 index 0000000..c505b9b --- /dev/null +++ b/bot-wsp/src/rfid/rfid.service.ts @@ -0,0 +1,96 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { LogDirection } from '@prisma/client'; +import dayjs from 'dayjs'; +import { AuthService, TokenRedirectURL } from '~/auth/auth.service'; +import { AttendanceService } from '../attendance/attendance.service'; +import { InvoicesService } from '../invoices/invoices.service'; +import { UserService } from '../user/user.service'; +import { WhatsappService } from '../whatsapp/whatsapp.service'; + +@Injectable() +export class RfidService { + private logger = new Logger(RfidService.name); + constructor( + private readonly userService: UserService, + private readonly whatsappService: WhatsappService, + private readonly attendanceService: AttendanceService, + private readonly invoicesService: InvoicesService, + private readonly authService: AuthService, + ) { } + + async ping(uid: string): Promise { + try { + const usuario = await this.userService.findByRfid(uid); + const admin = await this.userService.getUserAdmin(); + if (usuario) { + if (!usuario.phone) { + this.logger.debug(`El usuario ${usuario.name} no tiene un número de teléfono registrado.`); + const number = admin?.phone ? `549${admin.phone}` : '5493435077510' + this.logger.log({ + action: 'RFID ping', + message: `El usuario ${usuario.name} con ID ${usuario.id} no tiene un número de teléfono registrado.`, + uid: uid, + userId: usuario.id, + }) + await this.whatsappService.sendText( + number, + `El usuario ${usuario.name} con ID ${usuario.id} no tiene un número de teléfono registrado. Por favor, actualiza su información.`); + } else { + this.logger.log(`RFID ping recibido con id=${uid} del usuario ${usuario.name}`); + const log = await this.attendanceService.logAccess(usuario.id); + const tipo = log.direction === LogDirection.INGRESS ? 'ingreso' : 'egreso'; + const hora = dayjs(log.timestamp).format('HH:mm'); + + // ---- Construir un único mensaje ---- + let message = `Hola ${usuario.name} ! \n`; + + if (log.direction === LogDirection.INGRESS) { + this.logger.log(`Registro de ingreso para el usuario ${usuario.name} a las ${hora}`); + message += `Registramos tu ${tipo} a las ${hora}. \n`; + + // Verificar factura pagada + const unpaidInvoice = await this.invoicesService.hasUnpaidInvoiceThisMonth(usuario.id); + if (unpaidInvoice) { + this.logger.warn(`El usuario ${usuario.name} tiene facturas no pagadas este mes.`); + message += `⚠️ Notamos que tienes facturas no pagadas este mes. Por favor, regulariza tu situación.`; + } + } else { + // Si es egreso, solo avisamos el registro + message += `Registramos tu ${tipo} a las ${hora}.`; + } + // Enviar el mensaje único + await this.whatsappService.sendText('549' + usuario.phone, message); + } + return; + } else { + //NOTE mando al admin que se esta registrando un un nuevo usuario + this.logger.error({ + action: 'RFID ping', + message: `RFID ping recibido con id=${uid} pero no se encontró el usuario`, + uid: uid, + }) + const newUser = await this.userService.createUserTemporary(uid); + this.logger.debug(`Usuario temporal creado: ${newUser.name} con ID ${newUser.id}`); + if (!admin) { + this.logger.error(`No se encontró un usuario administrador para notificar sobre el nuevo usuario con RFID ${uid}.`); + return; + } + + const token = await this.authService.generarToken(admin.id, TokenRedirectURL.USER); + + await this.whatsappService.sendText('549' + admin?.phone, + `🆕 Se registro un *nuevo usuario* a travez de un nuevo *llavero*.\n + 🤔 Nombre: *${newUser.name}*\n + Porfavor actualiza su información ingresando al link 🙏\n + ${process.env.URL_FRONT}?t=${token} + `); + return; + } + } + catch (error: any) { + this.logger.error(`Error al procesar el ping RFID: ${error}`); + + + } + } +} diff --git a/bot-wsp/src/scheduling/scheduling.controller.spec.ts b/bot-wsp/src/scheduling/scheduling.controller.spec.ts new file mode 100644 index 0000000..2201572 --- /dev/null +++ b/bot-wsp/src/scheduling/scheduling.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SchedulingController } from './scheduling.controller'; +import { SchedulingService } from './scheduling.service'; + +describe('SchedulingController', () => { + let controller: SchedulingController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [SchedulingController], + providers: [SchedulingService], + }).compile(); + + controller = module.get(SchedulingController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/scheduling/scheduling.controller.ts b/bot-wsp/src/scheduling/scheduling.controller.ts new file mode 100644 index 0000000..1e12d12 --- /dev/null +++ b/bot-wsp/src/scheduling/scheduling.controller.ts @@ -0,0 +1,7 @@ +import { Controller } from '@nestjs/common'; +import { SchedulingService } from './scheduling.service'; + +@Controller('scheduling') +export class SchedulingController { + constructor(private readonly schedulingService: SchedulingService) {} +} diff --git a/bot-wsp/src/scheduling/scheduling.module.ts b/bot-wsp/src/scheduling/scheduling.module.ts new file mode 100644 index 0000000..fb2a1e3 --- /dev/null +++ b/bot-wsp/src/scheduling/scheduling.module.ts @@ -0,0 +1,24 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { SchedulingService } from './scheduling.service'; +import { SchedulingController } from './scheduling.controller'; +import { SessionsModule } from '~/sessions/sessions.module'; +import { ScheduleModule } from '@nestjs/schedule'; +import { InvoicesModule } from '~/invoices/invoices.module'; +import { SystemConfigService } from '~/common/system-config.service'; +import { PrismaModule } from '~/prisma/prisma.module'; +import { UserModule } from '~/user/user.module'; +import { AuthModule } from '~/auth/auth.module'; + +@Module({ + controllers: [SchedulingController], + providers: [SchedulingService, SystemConfigService], + imports: [ + ScheduleModule.forRoot(), + SessionsModule, + InvoicesModule, + PrismaModule, + forwardRef(() => UserModule), + forwardRef(() => AuthModule), +] +}) +export class SchedulingModule { } diff --git a/bot-wsp/src/scheduling/scheduling.service.spec.ts b/bot-wsp/src/scheduling/scheduling.service.spec.ts new file mode 100644 index 0000000..df20b02 --- /dev/null +++ b/bot-wsp/src/scheduling/scheduling.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SchedulingService } from './scheduling.service'; + +describe('SchedulingService', () => { + let service: SchedulingService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [SchedulingService], + }).compile(); + + service = module.get(SchedulingService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/scheduling/scheduling.service.ts b/bot-wsp/src/scheduling/scheduling.service.ts new file mode 100644 index 0000000..67cf0a3 --- /dev/null +++ b/bot-wsp/src/scheduling/scheduling.service.ts @@ -0,0 +1,155 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { Cron, CronExpression } from '@nestjs/schedule'; +import { InvoicesService } from '~/invoices/invoices.service'; +import { PrismaService } from '~/prisma/prisma.service'; +import { SessionsService } from '~/sessions/sessions.service'; +import { SystemConfigService } from '~/common/system-config.service'; + +@Injectable() +export class SchedulingService { + private readonly logger = new Logger(SchedulingService.name); + private lastSessionCleanup: number = 0; + private lastTokenCleanup: number = 0; + + constructor( + private readonly sessions: SessionsService, + private readonly invoices: InvoicesService, + private readonly prisma: PrismaService, + private readonly systemConfig: SystemConfigService, + ) { } + + // Desactiva sesiones vencidas cada 30 minutos (configurable) + @Cron(CronExpression.EVERY_MINUTE, { name: 'deactivateExpiredSessions' }) + async deactivateExpiredSessionsJob() { + // Verificar si debe ejecutarse según la configuración + const intervalMinutes = this.systemConfig.getSessionCleanupInterval(); + const now = Date.now(); + + if (now - this.lastSessionCleanup < intervalMinutes * 60 * 1000) { + return; // Aún no es tiempo de ejecutar + } + + this.lastSessionCleanup = now; + + try { + const count = await this.sessions.deactivateExpiredActives(); + if (count > 0) { + this.logger.log(`Desactivadas ${count} sesiones vencidas.`); + } else { + this.logger.verbose('No había sesiones vencidas para desactivar.'); + } + } catch (err: any) { + this.logger.error('Error desactivando sesiones vencidas', err?.stack || err); + } + } + + + // Todos los meses se deben de generar las facturas y enlaces de pagos + // para que el usuario pueda pagar la clase que este inscripto y activa. + // Se ejecuta diariamente y verifica si es el día configurado del mes + @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT, { name: 'generateMonthlyInvoices' }) + async generateMonthlyInvoicesAndPaymentLinksJob() { + const today = new Date().getDate(); + const configuredDay = this.systemConfig.getInvoiceGenerationDay(); + + // Solo ejecutar si es el día configurado del mes + if (today !== configuredDay) { + return; + } + + let totalProcessed = 0; + let totalSuccess = 0; + let totalFailed = 0; + const errors: Array<{ sessionId: string; assistantId: string; error: string }> = []; + + try { + const sessions = await this.sessions.findAllSessionInThisMonth(); + this.logger.log(`Iniciando generación de facturas para ${sessions.length} sesiones`); + + for (const session of sessions) { + const { id: sessionId, assistants } = session; + + for (const assistant of assistants) { + totalProcessed++; + + try { + await this.invoices.newInvoiceForSession( + assistant.id, + sessionId, + new Date() + ); + totalSuccess++; + this.logger.verbose( + `✓ Factura creada: session=${sessionId}, assistant=${assistant.id}` + ); + } catch (invoiceErr: any) { + totalFailed++; + const errorMsg = invoiceErr?.message || String(invoiceErr); + + errors.push({ + sessionId, + assistantId: assistant.id, + error: errorMsg + }); + + this.logger.warn( + `✗ Error creando factura: session=${sessionId}, assistant=${assistant.id}, error=${errorMsg}` + ); + } + } + } + + // Resumen final + this.logger.log( + `Generación de facturas completada: ` + + `Total=${totalProcessed}, Éxito=${totalSuccess}, Fallos=${totalFailed}` + ); + + if (errors.length > 0) { + this.logger.error( + `Se encontraron ${errors.length} errores durante la generación:`, + JSON.stringify(errors, null, 2) + ); + } + + } catch (err: any) { + this.logger.error( + 'Error crítico generando facturas mensuales y enlaces de pago', + err?.stack || err + ); + } + } + + // Limpia tokens expirados cada hora (configurable) + @Cron(CronExpression.EVERY_MINUTE, { name: 'cleanupExpiredTokens' }) + async cleanupExpiredTokensJob() { + // Verificar si debe ejecutarse según la configuración + const intervalMinutes = this.systemConfig.getTokenCleanupInterval(); + const now = Date.now(); + + if (now - this.lastTokenCleanup < intervalMinutes * 60 * 1000) { + return; // Aún no es tiempo de ejecutar + } + + this.lastTokenCleanup = now; + + try { + const result = await this.prisma.token.deleteMany({ + where: { + expiresAt: { + lt: new Date(), // Eliminar los expirados + }, + }, + }); + + if (result.count > 0) { + this.logger.log(`Eliminados ${result.count} tokens expirados`); + } else { + this.logger.verbose('No había tokens expirados para eliminar.'); + } + } catch (err: any) { + this.logger.error('Error limpiando tokens expirados', err?.stack || err); + } + } + +} diff --git a/bot-wsp/src/sessions/dto/create-session.dto.ts b/bot-wsp/src/sessions/dto/create-session.dto.ts new file mode 100644 index 0000000..2ae2888 --- /dev/null +++ b/bot-wsp/src/sessions/dto/create-session.dto.ts @@ -0,0 +1,98 @@ +import { + IsArray, + IsEnum, + IsOptional, + IsString, + IsDateString, + ValidateNested, + IsObject, + IsNotEmpty, + IsNumber, +} from 'class-validator'; +import { Type } from 'class-transformer'; +import { SessionType } from '@prisma/client'; + +export enum ClaseTipo { + RECURRING = 'RECURRING', + ONE_TIME = 'ONE_TIME', +} + +class ProfesorDto { + @IsString() + customId!: string; +} + +class DateRangeDto { + @IsDateString() + start!: string; + + @IsDateString() + end!: string; +} + +export class CreateClaseDto { + @IsString() + title!: string; + + @IsObject() + @ValidateNested() + @Type(() => ProfesorDto) + profesor!: ProfesorDto; + + @IsEnum(ClaseTipo) + type!: ClaseTipo; + + @IsOptional() + @IsArray() + @IsString({ each: true }) + days?: string[] | null; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => DateRangeDto) + dates!: DateRangeDto[]; + + @IsDateString() + startDate!: string; + + @IsDateString() + endDate!: string; +} + + +export class UpsertClaseDto { + @IsOptional() + @IsString() + id?: string; // si viene, edita; si no, crea + + @IsString() + @IsNotEmpty() + title!: string; + + @IsEnum(SessionType) + type!: SessionType; + + @IsDateString() + startDate!: string; + + @IsDateString() + endDate!: string; + + @ValidateNested() + @Type(() => ProfesorDto) + profesor!: ProfesorDto; + + @IsArray() + @ValidateNested({ each: true }) + @Type(() => DateRangeDto) + dates!: DateRangeDto[]; + + @IsNumber() + amount: number | undefined +} + +export class SetParticipantsDto { + @IsArray() + @IsString({ each: true }) + userIds!: string[]; // IDs finales seleccionados +} \ No newline at end of file diff --git a/bot-wsp/src/sessions/dto/invoices-by-month-query.dto.ts b/bot-wsp/src/sessions/dto/invoices-by-month-query.dto.ts new file mode 100644 index 0000000..58f944e --- /dev/null +++ b/bot-wsp/src/sessions/dto/invoices-by-month-query.dto.ts @@ -0,0 +1,15 @@ +import { IsNumberString, IsString, Matches } from 'class-validator'; + +export class InvoicesByMonthQueryDto { + @IsNumberString() + @Matches(/^(0[1-9]|1[0-2])$/, { + message: 'month debe ser un número entre 01 y 12' + }) + month!: string; + + @IsNumberString() + @Matches(/^\d{4}$/, { + message: 'year debe ser un año de 4 dígitos' + }) + year!: string; +} diff --git a/bot-wsp/src/sessions/dto/invoices-by-month-response.dto.ts b/bot-wsp/src/sessions/dto/invoices-by-month-response.dto.ts new file mode 100644 index 0000000..bccd6bf --- /dev/null +++ b/bot-wsp/src/sessions/dto/invoices-by-month-response.dto.ts @@ -0,0 +1,20 @@ +import { InvoiceStatus } from '@prisma/client'; + +export interface AssistantInvoiceDto { + id: string; + name: string; + hasInvoice: boolean; + invoiceStatus: InvoiceStatus | null; + invoiceId?: string | null; + amount?: number | null; +} + +export interface InvoicesByMonthResponseDto { + sessionId: string; + sessionCustomId: string; + sessionDescription: string; + sessionType: string; + month: string; + year: string; + assistants: AssistantInvoiceDto[]; +} diff --git a/bot-wsp/src/sessions/entities/session.entity.ts b/bot-wsp/src/sessions/entities/session.entity.ts new file mode 100644 index 0000000..02adc44 --- /dev/null +++ b/bot-wsp/src/sessions/entities/session.entity.ts @@ -0,0 +1 @@ +export type DeactivateBody = { modelId: string, model: 'session' | 'snapshot' } \ No newline at end of file diff --git a/bot-wsp/src/sessions/sessions.controller.ts b/bot-wsp/src/sessions/sessions.controller.ts new file mode 100644 index 0000000..ac6daec --- /dev/null +++ b/bot-wsp/src/sessions/sessions.controller.ts @@ -0,0 +1,131 @@ +import { Body, Controller, ForbiddenException, Get, Param, Post, Put, Query, UseGuards } from '@nestjs/common'; +import { UserRole } from '@prisma/client'; +import { User } from '../common/decoratos/user.decorator'; +import { AuthTokenGuard } from '../common/guards/auth-token.guard'; +import { AuthUser } from '../common/types'; +import { SetParticipantsDto } from './dto/create-session.dto'; +import { InvoicesByMonthQueryDto } from './dto/invoices-by-month-query.dto'; +import { InvoicesByMonthResponseDto } from './dto/invoices-by-month-response.dto'; +import { DeactivateBody } from './entities/session.entity'; +import { ResponseAttendeesSnapshot, SessionsService } from './sessions.service'; + +@Controller('sessions') +@UseGuards(AuthTokenGuard) +export class SessionsController { + constructor(private readonly sessionsService: SessionsService) { } + + @Get() + async findAll( + @User() user: AuthUser, + @Query('status') status?: 'active' | 'inactive' | 'all', + ) { + return await this.sessionsService.findAll(user, status); + } + + @Post('/upsert') + async upsert( + @Body() body: any, //UpsertClaseDto, + @User() user: AuthUser, + ) { + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para crear o actualizar clases'); + } + + const { session, created } = await this.sessionsService.upsertSession(body, user?.id); + return { + message: created ? 'Clase creada correctamente' : 'Clase actualizada correctamente', + data: session, + }; + } + + @Get(':id/participants') + async getParticipants( + @Param('id') id: string, + @User() user: AuthUser, + ) { + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR; + if (!allowed) { + return { message: 'No tienes permisos para actualizar participantes', data: null }; + } + return this.sessionsService.getParticipantsLists(id); + } + + @Put(':id/participants') + async setParticipants( + @Param('id') id: string, + @Body() body: SetParticipantsDto, + @User() user: AuthUser, + ) { + // Permisos: ADMIN o INSTRUCTOR de la sesión + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR; + if (!allowed) { + return { message: 'No tienes permisos para actualizar participantes', data: null }; + } + const session = await this.sessionsService.setParticipants(id, body.userIds, user); + return { message: 'Participantes actualizados', data: session }; + } + + @Put(':id/snapshot') + async setSubstituteInstructor( + @Param('id') idSnapshot: string, + @Body('substituteInstructorId') substituteInstructorId: string[], + @User() user: AuthUser, + ) { + const allowed = user?.role === UserRole.ADMIN + + if (!allowed) { + return { message: 'No tienes permisos para actualizar el instructor suplente', data: null }; + } + + const session = await this.sessionsService.setSubstituteInstructor( + idSnapshot, substituteInstructorId); + return { message: 'Instructor suplente actualizado', data: session }; + } + + @Get(':id/attendees') + async getAttendeesSnapshot( + @Param('id') id: string, + @User() user: AuthUser, + ): Promise { + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para ver los asistentes'); + } + return this.sessionsService.getAttendeesSnapshot(id); + } + + @Post('/deactivate') + async deactivate( + @Body() body: DeactivateBody, + @User() user: AuthUser, + ) { + const allowed = user?.role === UserRole.ADMIN + if (!allowed) { + throw new ForbiddenException('No tienes permisos para desactivar'); + } + return await this.sessionsService.deactivate(body, user); + } + + @Get(':sessionId/invoices-by-month') + async getInvoicesByMonth( + @Param('sessionId') sessionId: string, + @Query() query: InvoicesByMonthQueryDto, + @User() user: AuthUser, + ): Promise { + // Permitir acceso a ADMIN e INSTRUCTOR + const allowed = user?.role === UserRole.ADMIN || user?.role === UserRole.INSTRUCTOR; + if (!allowed) { + throw new ForbiddenException('No tienes permisos para ver las facturas'); + } + + return await this.sessionsService.getInvoicesByMonth( + sessionId, + query.month, + query.year + ); + } + +} + + diff --git a/bot-wsp/src/sessions/sessions.module.ts b/bot-wsp/src/sessions/sessions.module.ts new file mode 100644 index 0000000..c9899e5 --- /dev/null +++ b/bot-wsp/src/sessions/sessions.module.ts @@ -0,0 +1,15 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { SessionsService } from './sessions.service'; +import { SessionsController } from './sessions.controller'; +import { PrismaModule } from '../prisma/prisma.module'; +import { CustomIdModule } from '../custom-id/custom-id.module'; +import { InvoicesModule } from '~/invoices/invoices.module'; + +@Module({ + controllers: [SessionsController], + providers: [SessionsService], + imports: [PrismaModule, CustomIdModule, forwardRef(() => InvoicesModule)], + exports: [SessionsService], + +}) +export class SessionsModule { } diff --git a/bot-wsp/src/sessions/sessions.service.spec.ts b/bot-wsp/src/sessions/sessions.service.spec.ts new file mode 100644 index 0000000..923df18 --- /dev/null +++ b/bot-wsp/src/sessions/sessions.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SessionsService } from './sessions.service'; + +describe('SessionsService', () => { + let service: SessionsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [SessionsService], + }).compile(); + + service = module.get(SessionsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/sessions/sessions.service.ts b/bot-wsp/src/sessions/sessions.service.ts new file mode 100644 index 0000000..b696a56 --- /dev/null +++ b/bot-wsp/src/sessions/sessions.service.ts @@ -0,0 +1,1164 @@ +import { BadRequestException, ForbiddenException, forwardRef, Inject, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; +import { $Enums, Session, SessionType, UserRole } from '@prisma/client'; +import dayjs from 'dayjs'; +import timezone from 'dayjs/plugin/timezone'; +import utc from 'dayjs/plugin/utc'; +import { AuthUser } from '~/common/types'; +import { CustomIdService } from '../custom-id/custom-id.service'; +import { InvoicesService } from '../invoices/invoices.service'; +import { PrismaService } from '../prisma/prisma.service'; +import { DeactivateBody } from './entities/session.entity'; +dayjs.extend(utc); +dayjs.extend(timezone); + +const TZ = 'America/Argentina/Buenos_Aires'; + +type RecurrencePayload = { + startDate: string; // 'YYYY-MM-DD' + endDate: string; // 'YYYY-MM-DD' + days: number[]; // 0..6 (dom..sáb) + startTime?: string; // 'HH:mm' (opcional si hay dayTimes) + endTime?: string; // 'HH:mm' (opcional si hay dayTimes) + dayTimes?: Record< + string, // "0".."6" + { startTime: string; endTime: string } + >; +}; + +type UpsertPayload = { + id?: string; + title: string; + type: $Enums.SessionType | 'RECURRING' | 'ONE_TIME'; + instructorId: string; + amount?: number; + recurrence?: RecurrencePayload; + dates?: Array<{ start: string | Date; end: string | Date }>; + startDate?: string | Date | null; + endDate?: string | Date | null; +}; + + +export type SessionFilter = { + modo?: string + descripcion?: string; + instructor?: string; + assistant?: string; + temporalReference?: string; + daysOfWeek?: string[]; +}; + + +@Injectable() +export class SessionsService { + private logger = new Logger(SessionsService.name); + + constructor( + private prisma: PrismaService, + private customIdService: CustomIdService, + @Inject(forwardRef(() => InvoicesService)) + private readonly invoicesService: InvoicesService + ) { } + + async findById(id: string) { + try { + return await this.prisma.session.findUnique({ where: { id }, include: { instructors: true, assistants: true } }); + } catch (error: any) { + this.logger.error('Error al buscar session por id', error?.message); + throw new NotFoundException('Sesión no encontrada'); + } + } + + async findAll(user: AuthUser, status?: 'active' | 'inactive' | 'all'): Promise { + try { + // Determinar el filtro de isActive basado en el parámetro status + const isActiveFilter = status === 'active' + ? true + : status === 'inactive' + ? false + : undefined; // 'all' o sin especificar = no filtrar por isActive + + const response = await this.prisma.session.findMany({ + where: { + ...(isActiveFilter !== undefined ? { isActive: isActiveFilter } : {}), + ...(user.role === UserRole.INSTRUCTOR ? { instructors: { some: { id: user.id } } } : {}), + }, + include: { + instructors: true, + SessionDateSnapshot: { include: { dateRange: true, substituteInstructors: true } }, + } + }) + return response + } + catch (error: any) { + this.logger.error('Error al buscar todas las sessions', error?.message); + throw error; + } + } + + //NOTE se va a usar en el crone job para generar las facturas mensuales + // sesiones activas que tengan fechas en el mes actual + // con la relacion de assistants (id, dni) + async findAllSessionInThisMonth(): Promise<(Session & { + assistants: { id: string; dni: string | null }[] + })[]> { + try { + + const startOfMonth = dayjs().startOf('month').toDate(); + const endOfMonth = dayjs().endOf('month').toDate(); + const response = await this.prisma.session.findMany({ + where: { + isActive: true, + startDate: { lte: endOfMonth }, + endDate: { gte: startOfMonth }, + }, + include: { + assistants: { + select: { id: true, dni: true }, + where: { role: UserRole.USER } + }, + } + }); + + return response; + } + catch (error: any) { + this.logger.error('Error al buscar todas las sessions del mes', error?.message); + throw error; + } + } + + + async findAllsSessionByProfessorId(professorId: string): Promise { + try { + const sessions = await this.prisma.session.findMany({ + where: { + isActive: true, // solo sesiones activas + instructors: { // profesor debe estar en la relación + some: { id: professorId } + } + }, + include: { // opcional: traer los profesores y asistentes + instructors: true, + assistants: true, + }, + }); + + return sessions; + } catch (error: any) { + this.logger.error( + `Error al buscar sesiones por professorId (${professorId})`, + error?.message + ); + throw error; + } + } + + + + async findAllByUserId(userId: string , onlyAssistants: boolean): Promise { + try { + const sessions = await this.prisma.session.findMany({ + where: { + isActive: true, + OR: [ + { assistants: { some: { id: userId } } }, + onlyAssistants ? {} : { instructors: { some: { id: userId } } } + ], + }, + include: { + instructors: true, + assistants: true, + dates: true, + priceHistories: true, + }, + }); + + return sessions; + } catch (error: any) { + this.logger.error('Error al buscar sessions por userId', error?.message); + throw error; + } + } + + //Necesito buscar todas a las que no este inscripto como assistants + async findAllNotAssistantByUserId(userId: string, now: boolean = false) { + try { + const currentDate = new Date(); + + const sessions = await this.prisma.session.findMany({ + where: { + isActive: true, + assistants: { none: { id: userId }, }, + ...(now && { + dates: { + some: { + end: { gte: currentDate } + } + } + }) + }, + include: { + instructors: true, + assistants: true, + dates: true, // ✅ Incluir las fechas para sesiones RECURRING + priceHistories: true, + }, + }); + + return sessions; + } catch (error: any) { + this.logger.error('Error al buscar sessions por userId', error?.message); + throw error; + } + } + + async transactionAddAssistantAndCreateInvoice( + sessionId: string, + userId: string, + ) { + try { + this.logger.log(`Iniciando transacción: agregar asistente ${userId} a sesión ${sessionId} y crear factura`); + + return await this.prisma.$transaction(async (tx) => { + // 1) Verificar que la sesión existe y traer sus fechas + const session = await tx.session.findUnique({ + where: { id: sessionId }, + include: { + assistants: true, + dates: true // Necesitamos las fechas para saber cuándo inicia + } + }); + if (!session) { + throw new Error('Session not found'); + } + + // 2) Verificar que el usuario exists + const user = await tx.user.findUnique({ where: { id: userId } }); + if (!user) { + throw new Error('User not found'); + } + + // 3) Verificar que el usuario no esté ya inscrito + const isAlreadyAssistant = session.assistants.some(assistant => assistant.id === userId); + if (isAlreadyAssistant) { + throw new Error('User is already an assistant in this session'); + } + + // 4) Agregar asistente a la sesión + const updatedSession = await tx.session.update({ + where: { id: sessionId }, + data: { + assistants: { + connect: { id: userId } + } + }, + include: { assistants: true } + }); + + // 5) Determinar el mes de facturación según cuándo inicia la clase + let invoiceMonth: Date; + + this.logger.log(`Determinando mes de factura - sessionType: ${session.type}, startDate: ${session.startDate}, datesCount: ${session.dates?.length || 0}`); + + if (session.type === 'ONE_TIME' && session.startDate) { + // Para clases ONE_TIME, usar el mes de la startDate + invoiceMonth = dayjs(session.startDate).startOf('month').toDate(); + this.logger.log(`ONE_TIME detectada - usando startDate: ${session.startDate}, invoiceMonth: ${dayjs(invoiceMonth).format('YYYY-MM-DD')}`); + } else if (session.dates && session.dates.length > 0) { + // Para clases RECURRING, usar el mes de la primera fecha + const sortedDates = session.dates.sort((a, b) => + new Date(a.start).getTime() - new Date(b.start).getTime() + ); + invoiceMonth = dayjs(sortedDates[0].start).startOf('month').toDate(); + this.logger.log(`RECURRING detectada - primera fecha: ${sortedDates[0].start}, invoiceMonth: ${dayjs(invoiceMonth).format('YYYY-MM-DD')}`); + } else if (session.startDate) { + // Fallback: usar startDate de la sesión + invoiceMonth = dayjs(session.startDate).startOf('month').toDate(); + this.logger.log(`Fallback usando startDate: ${session.startDate}, invoiceMonth: ${dayjs(invoiceMonth).format('YYYY-MM-DD')}`); + } else { + // Último fallback: mes actual + invoiceMonth = dayjs().startOf('month').toDate(); + this.logger.log(`Último fallback - usando mes actual: ${dayjs(invoiceMonth).format('YYYY-MM-DD')}`); + } + + this.logger.log(`Generando factura para el mes: ${dayjs(invoiceMonth).format('YYYY-MM-DD')}`); + + // 6) Crear factura para el mes correcto + const invoice = await this.invoicesService.newInvoiceForSession( + userId, + sessionId, + invoiceMonth, + tx + ); + + this.logger.log(`Transacción completada exitosamente: sesión ${sessionId}, usuario ${userId}, factura ${invoice.id}`); + + return { + session: updatedSession, + invoice: invoice + }; + }, { + timeout: 15000 // 15 segundos para permitir llamadas a Odoo + }); + + } catch (error: any) { + this.logger.error('Error en transacción addAssistantAndCreateInvoice:', error.message); + throw new InternalServerErrorException(`Error en la transacción: ${error.message}`); + } + } + + + async addAssistantToSession(sessionId: string, userId: string): Promise { + try { + const session = await this.prisma.session.findUnique({ where: { id: sessionId } }); + if (!session) throw new Error('Session not found'); + + const user = await this.prisma.user.findUnique({ where: { id: userId } }); + if (!user) throw new Error('User not found'); + + // Opción: evitar agregar duplicados manualmente (o Prisma lo controla si usás clave única) + await this.prisma.session.update({ + where: { id: sessionId }, + data: { + assistants: { + connect: { id: userId } + } + }, + include: { assistants: true } + }); + return true; + } + catch (error: any) { + this.logger.error('Error al agregar asistente a la sesión', error?.message); + throw new InternalServerErrorException('Error al agregar asistente a la sesión'); + } + + } + + async addInstructorToSession(sessionId: string, userId: string) { + // Verificar que la sesión exista + const session = await this.prisma.session.findUnique({ + where: { id: sessionId }, + }); + if (!session) throw new Error('Session not found'); + + // Verificar que el usuario exista + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + }); + if (!user) throw new Error('User not found'); + + // Actualizar la sesión agregando el instructor + const updatedSession = await this.prisma.session.update({ + where: { id: sessionId }, + data: { + instructors: { + connect: { id: userId }, + }, + }, + include: { + instructors: true, + assistants: true, + + }, + }); + + return updatedSession; + } + + async removeUserFromSession(sessionId: string, userId: string) { + // Verificar que la sesión exista + const session = await this.prisma.session.findUnique({ + where: { id: sessionId }, + include: { + instructors: { select: { id: true } }, + assistants: { select: { id: true } }, + }, + }); + + if (!session) throw new Error('Session not found'); + + const isInstructor = session.instructors.some((user) => user.id == userId); + const isAssistant = session.assistants.some((user) => user.id == userId); + + if (!isInstructor && !isAssistant) { + throw new Error('User is not assigned to this session'); + } + + const updates: any = {}; + + if (isInstructor) { + updates.instructors = { disconnect: { id: userId } }; + } + + if (isAssistant) { + updates.assistants = { disconnect: { id: userId } }; + } + + const updatedSession = await this.prisma.session.update({ + where: { id: sessionId }, + data: updates, + include: { + instructors: true, + assistants: true, + }, + }); + + return updatedSession; + } + + /** + * Actualiza una sesión. + * + * @param sessionId ID de la sesión a modificar. + * @param updateData Un objeto parcial con los campos que se quieren + * actualizar (tipo `Partial`). + * @param currentUserId ID del usuario que está realizando la mutación. + * + * Si el usuario que ejecuta la operación es un `INSTRUCTOR`, se comprueba + * que esté incluido en la relación `instructors` de la sesión. En caso + * contrario se lanza `ForbiddenException`. + */ + async updateSession( + sessionId: string, + updateData: Partial, + currentUserId: string, + ): Promise { + try { + // 1️⃣ Obtener el usuario que está haciendo la mutación + const currentUser = await this.prisma.user.findUnique({ + where: { id: currentUserId }, + }); + + if (!currentUser) { + throw new InternalServerErrorException( + `Usuario con id ${currentUserId} no encontrado`, + ); + } + + // 2️⃣ Obtener la sesión que se va a actualizar + const session = await this.prisma.session.findUnique({ + where: { id: sessionId }, + include: { instructors: true }, // traer la relación para la validación + }); + + if (!session) { + throw new InternalServerErrorException( + `Sesión con id ${sessionId} no encontrada`, + ); + } + + // 3️⃣ Si el usuario es profesor, verificar que esté incluido en la relación + if (currentUser.role === UserRole.INSTRUCTOR) { + const isInstructorInSession = session.instructors.some( + (inst) => inst.id === currentUserId, + ); + + if (!isInstructorInSession) { + throw new ForbiddenException( + 'no tienes permisos para actualizar esta sesión', + ); + } + } + + // 4️⃣ Actualizar la sesión con los datos parciales + const updatedSession = await this.prisma.session.update({ + where: { id: sessionId }, + data: updateData, + }); + + return updatedSession; + } catch (err) { + throw new InternalServerErrorException( + 'No se pudo actualizar la sesión', + ); + } + + } + + /** + * Crea o actualiza una sesión. + * - Si dto.id existe: update (reemplaza dates y snapshots). + * - Si dto.id no existe: create (genera customId y snapshots). + * Valida que el profesor exista por customId. + * Si quien edita es INSTRUCTOR, valida que pertenezca a la sesión. + */ + async upsertSession(payload: UpsertPayload, currentUserId?: string) { + const { + id, + title, + type, + instructorId, + amount, + recurrence, + dates, + startDate, + endDate, + } = payload; + + const typeStr = String(type); // evita TS2367 + const isUpdate = !!id; + const now = new Date(); + + // 1) Cargar sesión si es update + permisos + const sessionOld = isUpdate + ? await this.prisma.session.findUnique({ + where: { id: id! }, + include: { instructors: true, dates: true }, + }) + : null; + + if (isUpdate && !sessionOld) { + throw new NotFoundException(`Sesión ${id} no encontrada`); + } + + if (currentUserId && isUpdate) { + const currentUser = await this.prisma.user.findUnique({ where: { id: currentUserId } }); + if (!currentUser) throw new ForbiddenException('Usuario inválido'); + // si tenés role como string, podés comparar con 'INSTRUCTOR' + if (currentUser.role === ($Enums.UserRole?.INSTRUCTOR ?? 'INSTRUCTOR')) { + const allowed = sessionOld!.instructors.some((i) => i.id === currentUserId); + if (!allowed) throw new ForbiddenException('No tienes permisos para actualizar esta sesión'); + } + } + + // 2) Construir desiredRanges a partir de recurrence/dayTimes o dates + const desiredRanges: { start: Date; end: Date }[] = []; + + if (recurrence && typeStr === SessionType.RECURRING) { + const { startDate: sd, endDate: ed, days, startTime, endTime, dayTimes } = recurrence; + const dStart = dayjs(sd, 'YYYY-MM-DD'); + const dEnd = dayjs(ed, 'YYYY-MM-DD'); + if (!dStart.isValid() || !dEnd.isValid() || dEnd.isBefore(dStart) || !days?.length) { + throw new BadRequestException('Recurrence inválido'); + } + + const perDay = dayTimes && Object.keys(dayTimes).length > 0; + + for ( + let d = dStart.clone(); + d.isSame(dEnd, 'day') || d.isBefore(dEnd, 'day'); + d = d.add(1, 'day') + ) { + const idx = d.day(); // 0..6 + if (!days.includes(idx)) continue; + + let sHHmm: string, eHHmm: string; + if (perDay) { + const conf = dayTimes[String(idx)]; + if (!conf?.startTime || !conf?.endTime) { + throw new BadRequestException(`Falta horario para el día ${idx}`); + } + sHHmm = conf.startTime; + eHHmm = conf.endTime; + } else { + if (!startTime || !endTime) { + throw new BadRequestException('Faltan startTime/endTime en recurrence'); + } + sHHmm = startTime; + eHHmm = endTime; + } + + const dateStr = d.format('YYYY-MM-DD'); + desiredRanges.push({ + start: dayjs.tz(`${dateStr} ${sHHmm}`, 'YYYY-MM-DD HH:mm', TZ).toDate(), + end: dayjs.tz(`${dateStr} ${eHHmm}`, 'YYYY-MM-DD HH:mm', TZ).toDate() + }); + } + + if (desiredRanges.length === 0) { + throw new BadRequestException( + 'El rango (startDate..endDate) no contiene ninguno de los días seleccionados.' + ); + } + } else if (Array.isArray(dates) && dates.length) { + for (const r of dates) { + const s = new Date(r.start); + const e = new Date(r.end); + if (isNaN(s.getTime()) || isNaN(e.getTime())) { + throw new BadRequestException('Alguna fecha enviada en "dates" es inválida'); + } + desiredRanges.push({ start: s, end: e }); + } + } else { + throw new BadRequestException('Debe enviar recurrence o dates'); + } + + // 3) Transacción: upsert Session + diff rangos + snapshots + price history + const result = await this.prisma.$transaction(async (tx) => { + // Para el campo Session.startDate/endDate, si vino recurrence, usamos esas fechas + const dStartForSession = + recurrence && typeStr === SessionType.RECURRING + ? dayjs(recurrence.startDate, 'YYYY-MM-DD').toDate() + : desiredRanges[0]?.start ?? sessionOld?.startDate ?? null; + + const dEndForSession = + recurrence && typeStr === SessionType.RECURRING + ? dayjs(recurrence.endDate, 'YYYY-MM-DD').toDate() + : desiredRanges.at(-1)?.end ?? sessionOld?.endDate ?? null; + + // 3.1) Crear/actualizar Session base + const session = isUpdate + ? await tx.session.update({ + where: { id: id! }, + data: { + description: title, + type: type as any, + ...(amount !== undefined ? { amount } : {}), + startDate: startDate != null ? new Date(startDate as any) : dStartForSession, + endDate: endDate != null ? new Date(endDate as any) : dEndForSession, + instructors: { set: [{ id: instructorId }] }, + }, + }) + : await tx.session.create({ + data: { + description: title, + type: type as any, + customId: await this.customIdService.generateCustomId('session', 'S'), + amount: amount ?? null, + startDate: startDate ? new Date(startDate as any) : dStartForSession, + endDate: endDate ? new Date(endDate as any) : dEndForSession, + instructors: { connect: [{ id: instructorId }] }, + }, + }); + + // 3.2) Ranges actuales + const currentRanges = await tx.sessionDateRange.findMany({ + where: { sessionId: session.id }, + select: { id: true, start: true, end: true }, + }); + + // 3.3) Diff por clave (startISO__endISO) + const key = (d: { start: Date; end: Date }) => + `${d.start.toISOString()}__${d.end.toISOString()}`; + + const desiredMap = new Map(desiredRanges.map((d) => [key(d), d])); + const currentMap = new Map(currentRanges.map((d) => [key(d), d])); + + // Crear faltantes (+ snapshot) + for (const [k, d] of desiredMap) { + if (!currentMap.has(k)) { + const created = await tx.sessionDateRange.create({ + data: { sessionId: session.id, start: d.start, end: d.end }, + }); + await tx.sessionDateSnapshot.create({ + data: { + sessionId: session.id, + dateRangeId: created.id, + }, + }); + } + } + + // Eliminar sobrantes (y sus snapshots) + const toDelete = currentRanges.filter((cr) => !desiredMap.has(key(cr))).map((cr) => cr.id); + if (toDelete.length) { + await tx.sessionDateSnapshot.deleteMany({ where: { dateRangeId: { in: toDelete } } }); + await tx.sessionDateRange.deleteMany({ where: { id: { in: toDelete } } }); + } + + // 3.4) Si cambia el precio: cerrar vigente y crear uno nuevo en PriceHistory + if (isUpdate && amount !== undefined && amount !== sessionOld!.amount) { + await tx.sessionPriceHistory.updateMany({ + where: { sessionId: session.id, effectiveTo: null }, + data: { effectiveTo: now }, + }); + await tx.sessionPriceHistory.create({ + data: { sessionId: session.id, amount, effectiveFrom: now, effectiveTo: null }, + }); + } + + // 3.5) devolver todo lo que el front usa + return tx.session.findUnique({ + where: { id: session.id }, + include: { + dates: true, + instructors: true, + SessionDateSnapshot: { include: { dateRange: true } }, + priceHistories: true, + }, + }); + }); + + return { session: result, created: !isUpdate }; + } + + + + + async getParticipantsLists(sessionId: string) + : Promise<{ selected: UserSession[], available: UserSession[] }> { + const session = await this.prisma.session.findUnique({ + where: { id: sessionId }, + include: { assistants: true }, + }); + if (!session) throw new NotFoundException('Sesión no encontrada'); + + const selected = session.assistants.map(u => ({ + id: u.id, customId: u.customId, name: u.name, role: u.role, + })); + + // Disponibles: todos menos los ya seleccionados (podés filtrar roles si querés) + const selectedIds = selected.map(u => u.id); + const availableUsers = await this.prisma.user.findMany({ + where: { + id: { notIn: selectedIds.length ? selectedIds : [''] }, + // opcional: limitar a ciertos roles como “alumnos” + // role: { in: [UserRole.USER, UserRole.GUEST] }, + deleted: null, + }, + select: { id: true, customId: true, name: true, role: true }, + orderBy: { name: 'asc' }, + }); + + const available = availableUsers.map(u => ({ + id: u.id, customId: u.customId, name: u.name, role: u.role, + })); + + return { selected, available }; + } + + async setParticipants(sessionId: string, userIds: string[], currentUser?: { id: string; role: UserRole }) { + const session = await this.prisma.session.findUnique({ + where: { id: sessionId }, + include: { instructors: true }, + }); + if (!session) throw new NotFoundException('Clase no encontrada'); + + // Si el que modifica es INSTRUCTOR, debe pertenecer a la sesión + if (currentUser?.role === UserRole.INSTRUCTOR) { + const allowed = session.instructors.some(i => i.id === currentUser.id); + if (!allowed) throw new ForbiddenException('No tienes permisos para esta clase'); + } + + // Reemplazar toda la lista de asistentes + const updated = await this.prisma.session.update({ + where: { id: sessionId }, + data: { + assistants: { + set: userIds.map(id => ({ id })), + }, + }, + include: { assistants: true }, + }); + + return { + id: updated.id, + assistants: updated.assistants.map(u => ({ id: u.id, customId: u.customId, name: u.name })), + }; + } + + async setSubstituteInstructor(idSnapshot: string, substituteInstructorId: string[]) { + + const snapshot = await this.prisma.sessionDateSnapshot.findUnique({ + where: { + id: idSnapshot + } + }) + + if (!snapshot) throw new NotFoundException('Snapshot no encontrado'); + + const updated = await this.prisma.sessionDateSnapshot.update({ + where: { id: idSnapshot }, + data: { + substituteInstructors: { + set: substituteInstructorId.map(id => ({ id })), + }, + }, + include: { + substituteInstructors: true, + }, + }); + + return !!updated + } + + async getAttendeesSnapshot(snapshotId: string): Promise { + try { + const snapshot = await this.prisma.sessionDateSnapshot.findUnique({ + where: { + id: snapshotId + }, + select: { + presentAssistants: { select: { id: true, name: true } }, + presentInstructors: { select: { id: true, name: true } }, + dateRange: { select: { start: true, end: true } }, + session: { include: { instructors: { select: { id: true, name: true } }, assistants: { select: { id: true, name: true } } } } + } + }) + + if (!snapshot) { + throw new NotFoundException('Snapshot no encontrado'); + } + + const response: ResponseAttendeesSnapshot = { + dateRange: snapshot.dateRange, + instructors: snapshot.session.instructors, + assistants: snapshot.session.assistants, + attendance: [...snapshot.presentAssistants.map(a => ({ id: a.id, name: a.name })), ...snapshot.presentInstructors.map(a => ({ id: a.id, name: a.name }))] + }; + + return response + } + catch (error: any) { + + this.logger.error('Error al obtener asistentes del snapshot', error?.message); + throw new InternalServerErrorException('Error al obtener asistentes del snapshot'); + } + + } + + + async findByCustomId(customId: string): Promise { + try { + this.logger.log(`Buscando sesión con customId: ${customId}`); + return await this.prisma.session.findUnique({ + where: { customId }, + }); + + } + catch (error: any) { + this.logger.error('Error al buscar sesión por customId', error?.message); + throw new InternalServerErrorException('Error al buscar sesión por customId'); + } + } + + + async deactivate(data: DeactivateBody, actionBy?: AuthUser) { + const actionByInfo = actionBy ? `${actionBy.name || actionBy.id} (${actionBy.role})` : 'Unknown'; + this.logger.log(`Deactivate request - model: ${data.model}, modelId: ${data.modelId}, actionBy: ${actionByInfo}`); + + try { + const { model, modelId } = data + + if (model === 'session') { + this.logger.log(`Deactivating session - id: ${modelId}, actionBy: ${actionByInfo}`); + + const session = await this.prisma.session.findUnique({ where: { id: modelId } }); + if (!session) { + this.logger.warn(`Session not found for deactivation - id: ${modelId}, attemptedBy: ${actionByInfo}`); + throw new BadRequestException('Sesión no encontrada'); + } + + const desactivate = await this.prisma.session.update({ + where: { id: modelId }, + data: { isActive: false } + }); + + this.logger.log(`Session deactivated successfully - id: ${modelId}, by: ${actionByInfo}`); + return !!desactivate + } + + if (model === 'snapshot') { + this.logger.log(`Deactivating snapshot - id: ${modelId}, actionBy: ${actionByInfo}`); + + const snapshot = await this.prisma.sessionDateSnapshot.findUnique({ where: { id: modelId } }); + if (!snapshot) { + this.logger.warn(`Snapshot not found for deactivation - id: ${modelId}, attemptedBy: ${actionByInfo}`); + throw new BadRequestException('Snapshot no encontrado'); + } + + const desactivate = await this.prisma.sessionDateSnapshot.update({ + where: { id: modelId }, + data: { isActive: false } + }); + + this.logger.log(`Snapshot deactivated successfully - id: ${modelId}, by: ${actionByInfo}`); + return !!desactivate + } + + this.logger.warn(`Invalid model for deactivation - model: ${model}, attemptedBy: ${actionByInfo}`); + throw new BadRequestException('No se encontro el modelo') + } catch (error: any) { + this.logger.error(`Error in deactivate by ${actionByInfo} - model: ${data.model}, modelId: ${data.modelId}, error: ${error.message}`, error.stack); + throw new InternalServerErrorException('No se pudo desactivar') + } + } + + /** + * Programa un cambio de precio futuro para una sesión + * @param sessionId ID de la sesión + * @param newAmount Nuevo monto a aplicar + * @param effectiveFrom Fecha desde cuando será efectivo el nuevo precio + */ + async scheduleSessionPriceChange( + sessionId: string, + newAmount: number, + effectiveFrom: Date + ): Promise { + this.logger.log(`Scheduling price change for session ${sessionId}: ${newAmount} from ${effectiveFrom}`); + + await this.prisma.$transaction(async (tx) => { + // Verificar que la sesión existe + const session = await tx.session.findUnique({ where: { id: sessionId } }); + if (!session) { + throw new NotFoundException('Sesión no encontrada'); + } + + // Verificar que la fecha sea futura + if (effectiveFrom <= new Date()) { + throw new BadRequestException('La fecha efectiva debe ser futura'); + } + + // Buscar precios que puedan conflictuar + const conflictingPrices = await tx.sessionPriceHistory.findMany({ + where: { + sessionId, + OR: [ + { + // Precios que inician antes pero no tienen fecha de fin (vigentes) + effectiveFrom: { lte: effectiveFrom }, + effectiveTo: null + }, + { + // Precios que se solapan con la nueva fecha + effectiveFrom: { lte: effectiveFrom }, + effectiveTo: { gt: effectiveFrom } + } + ] + } + }); + + // Ajustar precios conflictivos + if (conflictingPrices.length > 0) { + // Cerrar el precio vigente actual para que termine justo antes del nuevo + await tx.sessionPriceHistory.updateMany({ + where: { + sessionId, + effectiveTo: null, + effectiveFrom: { lt: effectiveFrom } + }, + data: { effectiveTo: effectiveFrom } + }); + + // Si hay otros precios programados que se solapan, eliminarlos + await tx.sessionPriceHistory.deleteMany({ + where: { + sessionId, + effectiveFrom: { gte: effectiveFrom }, + effectiveTo: { not: null } + } + }); + } + + // Crear el nuevo precio programado + await tx.sessionPriceHistory.create({ + data: { + sessionId, + amount: newAmount, + effectiveFrom, + effectiveTo: null + } + }); + + this.logger.log(`Price change scheduled successfully for session ${sessionId}`); + }); + } + + /** + * Obtiene el cronograma completo de precios de una sesión + * @param sessionId ID de la sesión + * @returns Cronograma de precios con precio actual y historial + */ + async getSessionPriceSchedule(sessionId: string) { + this.logger.log(`Getting price schedule for session ${sessionId}`); + + const session = await this.prisma.session.findUnique({ + where: { id: sessionId }, + include: { + priceHistories: { + orderBy: { effectiveFrom: 'asc' } + } + } + }); + + if (!session) { + throw new NotFoundException('Sesión no encontrada'); + } + + const now = new Date(); + const currentPriceHistory = session.priceHistories.find(ph => + ph.effectiveFrom <= now && (!ph.effectiveTo || ph.effectiveTo > now) + ); + + return { + sessionId: session.id, + currentPrice: currentPriceHistory?.amount || session.amount || 0, + fallbackPrice: session.amount, + priceHistory: session.priceHistories.map(ph => ({ + id: ph.id, + amount: ph.amount, + effectiveFrom: ph.effectiveFrom, + effectiveTo: ph.effectiveTo, + isCurrent: ph.effectiveFrom <= now && (!ph.effectiveTo || ph.effectiveTo > now), + isPending: ph.effectiveFrom > now + })) + }; + } + + /** + * Actualiza inmediatamente el precio de una sesión + * @param sessionId ID de la sesión + * @param newAmount Nuevo monto + */ + async updateSessionPriceImmediate(sessionId: string, newAmount: number) { + this.logger.log(`Updating immediate price for session ${sessionId}: ${newAmount}`); + + const now = new Date(); + + await this.prisma.$transaction(async (tx) => { + // Verificar que la sesión existe + const session = await tx.session.findUnique({ where: { id: sessionId } }); + if (!session) { + throw new NotFoundException('Sesión no encontrada'); + } + + // Cerrar el precio anterior (si existe) + await tx.sessionPriceHistory.updateMany({ + where: { + sessionId, + effectiveTo: null, // solo el registro "vigente" + }, + data: { effectiveTo: now }, + }); + + // Crear el nuevo registro de precio + await tx.sessionPriceHistory.create({ + data: { + sessionId, + amount: newAmount, + effectiveFrom: now, + effectiveTo: null, + }, + }); + + // Actualizar el campo Session.amount como fallback + await tx.session.update({ + where: { id: sessionId }, + data: { amount: newAmount }, + }); + + this.logger.log(`Price updated immediately for session ${sessionId}`); + }); + } + + async deactivateExpiredActives(): Promise { + const now = new Date(); + const { count } = await this.prisma.session.updateMany({ + where: { + isActive: true, + endDate: { lt: now, not: null }, + }, + data: { isActive: false }, + }); + return count; + } + + /** + * Obtiene las facturas de todos los asistentes de una sesión para un mes/año específico + * @param sessionId ID de la sesión + * @param month Mes (01-12) + * @param year Año (YYYY) + * @returns Información de la sesión y estado de facturas de cada asistente + */ + async getInvoicesByMonth(sessionId: string, month: string, year: string) { + this.logger.log(`Getting invoices for session ${sessionId}, month: ${month}, year: ${year}`); + + // 1. Verificar que la sesión existe y obtener sus datos básicos + const session = await this.prisma.session.findUnique({ + where: { id: sessionId }, + include: { + assistants: { + select: { + id: true, + name: true, + }, + }, + }, + }); + + if (!session) { + throw new NotFoundException('Sesión no encontrada'); + } + + // 2. Construir el rango de fechas para el mes solicitado + const startOfMonth = dayjs(`${year}-${month}-01`, 'YYYY-MM-DD') + .startOf('month') + .toDate(); + const endOfMonth = dayjs(`${year}-${month}-01`, 'YYYY-MM-DD') + .endOf('month') + .toDate(); + + // 3. Buscar todas las facturas de esta sesión en ese mes + const invoices = await this.prisma.invoice.findMany({ + where: { + sessionId, + dateInvoice: { + gte: startOfMonth, + lte: endOfMonth, + }, + }, + select: { + id: true, + userId: true, + status: true, + amount: true, + }, + }); + + // 4. Crear un mapa de userId -> invoice para búsqueda rápida + const invoiceMap = new Map( + invoices.map((inv) => [ + inv.userId, + { + id: inv.id, + status: inv.status, + amount: inv.amount, + }, + ]) + ); + + // 5. Construir el array de asistentes con su información de factura + const assistants = session.assistants.map((assistant) => { + const invoice = invoiceMap.get(assistant.id); + + return { + id: assistant.id, + name: assistant.name, + hasInvoice: !!invoice, + invoiceStatus: invoice?.status ?? null, + invoiceId: invoice?.id ?? null, + amount: invoice?.amount ?? null, + }; + }); + + // 6. Construir la respuesta + return { + sessionId: session.id, + sessionCustomId: session.customId, + sessionDescription: session.description, + sessionType: session.type, + month, + year, + assistants, + }; + } +} + +export type ResponseAttendeesSnapshot = { + dateRange: { + start: Date; + end: Date; + }; + instructors: { id: string; name: string; }[]; + assistants: { id: string; name: string; }[]; + attendance: { id: string; name: string; }[]; +} + +type UserSession = { + id: string; + customId: string | null; + name: string; + role: $Enums.UserRole; +} + diff --git a/bot-wsp/src/subscriptions/dto/create-subscription.dto.ts b/bot-wsp/src/subscriptions/dto/create-subscription.dto.ts new file mode 100644 index 0000000..ad39120 --- /dev/null +++ b/bot-wsp/src/subscriptions/dto/create-subscription.dto.ts @@ -0,0 +1 @@ +export class CreateSubscriptionDto {} diff --git a/bot-wsp/src/subscriptions/dto/update-subscription.dto.ts b/bot-wsp/src/subscriptions/dto/update-subscription.dto.ts new file mode 100644 index 0000000..afa2989 --- /dev/null +++ b/bot-wsp/src/subscriptions/dto/update-subscription.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateSubscriptionDto } from './create-subscription.dto'; + +export class UpdateSubscriptionDto extends PartialType(CreateSubscriptionDto) {} diff --git a/bot-wsp/src/subscriptions/entities/subscription.entity.ts b/bot-wsp/src/subscriptions/entities/subscription.entity.ts new file mode 100644 index 0000000..c440a76 --- /dev/null +++ b/bot-wsp/src/subscriptions/entities/subscription.entity.ts @@ -0,0 +1 @@ +export class Subscription {} diff --git a/bot-wsp/src/subscriptions/subscriptions.controller.spec.ts b/bot-wsp/src/subscriptions/subscriptions.controller.spec.ts new file mode 100644 index 0000000..458113d --- /dev/null +++ b/bot-wsp/src/subscriptions/subscriptions.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SubscriptionsController } from './subscriptions.controller'; +import { SubscriptionsService } from './subscriptions.service'; + +describe('SubscriptionsController', () => { + let controller: SubscriptionsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [SubscriptionsController], + providers: [SubscriptionsService], + }).compile(); + + controller = module.get(SubscriptionsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/subscriptions/subscriptions.controller.ts b/bot-wsp/src/subscriptions/subscriptions.controller.ts new file mode 100644 index 0000000..94ab409 --- /dev/null +++ b/bot-wsp/src/subscriptions/subscriptions.controller.ts @@ -0,0 +1,34 @@ +import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; +import { SubscriptionsService } from './subscriptions.service'; +import { CreateSubscriptionDto } from './dto/create-subscription.dto'; +import { UpdateSubscriptionDto } from './dto/update-subscription.dto'; + +@Controller('subscriptions') +export class SubscriptionsController { + constructor(private readonly subscriptionsService: SubscriptionsService) {} + + // @Post() + // create(@Body() createSubscriptionDto: CreateSubscriptionDto) { + // return this.subscriptionsService.create(createSubscriptionDto); + // } + + // @Get() + // findAll() { + // return this.subscriptionsService.findAll(); + // } + + // @Get(':id') + // findOne(@Param('id') id: string) { + // return this.subscriptionsService.findOne(+id); + // } + + // @Patch(':id') + // update(@Param('id') id: string, @Body() updateSubscriptionDto: UpdateSubscriptionDto) { + // return this.subscriptionsService.update(+id, updateSubscriptionDto); + // } + + // @Delete(':id') + // remove(@Param('id') id: string) { + // return this.subscriptionsService.remove(+id); + // } +} diff --git a/bot-wsp/src/subscriptions/subscriptions.module.ts b/bot-wsp/src/subscriptions/subscriptions.module.ts new file mode 100644 index 0000000..80274e4 --- /dev/null +++ b/bot-wsp/src/subscriptions/subscriptions.module.ts @@ -0,0 +1,18 @@ +import { Module } from '@nestjs/common'; +import { SubscriptionsService } from './subscriptions.service'; +import { SubscriptionsController } from './subscriptions.controller'; +import { SessionsModule } from '../sessions/sessions.module'; +import { UserModule } from '../user/user.module'; +import { PrismaModule } from '../prisma/prisma.module'; + +@Module({ + controllers: [SubscriptionsController], + providers: [SubscriptionsService], + imports: [ + SessionsModule, + UserModule, + PrismaModule + ], + exports: [SubscriptionsService], +}) +export class SubscriptionsModule { } diff --git a/bot-wsp/src/subscriptions/subscriptions.service.spec.ts b/bot-wsp/src/subscriptions/subscriptions.service.spec.ts new file mode 100644 index 0000000..176f847 --- /dev/null +++ b/bot-wsp/src/subscriptions/subscriptions.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { SubscriptionsService } from './subscriptions.service'; + +describe('SubscriptionsService', () => { + let service: SubscriptionsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [SubscriptionsService], + }).compile(); + + service = module.get(SubscriptionsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/bot-wsp/src/subscriptions/subscriptions.service.ts b/bot-wsp/src/subscriptions/subscriptions.service.ts new file mode 100644 index 0000000..7be5b63 --- /dev/null +++ b/bot-wsp/src/subscriptions/subscriptions.service.ts @@ -0,0 +1,155 @@ +import { BadRequestException, Injectable, InternalServerErrorException, Logger } from '@nestjs/common'; +import { PrismaService } from '../prisma/prisma.service'; +import { SessionsService } from '../sessions/sessions.service'; +import { UserService } from '~/user/user.service'; + +@Injectable() +export class SubscriptionsService { + private logger = new Logger(SubscriptionsService.name); + constructor( + private prismaService: PrismaService, + private sessionsService: SessionsService, + private userService: UserService, + ) { } + + /** + * Suscribe un usuario a una sesión como asistente + * @param userId ID del usuario + * @param sessionId ID de la sesión + * @returns información de la inscripción + */ + async subscribeUserToSession(userId: string, sessionId: string) { + try { + this.logger.log(`Subscribing user ${userId} to session ${sessionId}`); + + const session = await this.sessionsService.findById(sessionId); + const user = await this.userService.findById(userId); + + if (!session || !user) { + this.logger.warn(`Session or user not found (userId: ${userId}, sessionId: ${sessionId})`); + throw new BadRequestException('Usuario o sesión no encontrados'); + } + + // Verificar si el usuario ya es asistente de esta sesión + const isAlreadyAssistant = session?.assistants.some(assistant => assistant.id === userId); + + if (isAlreadyAssistant) { + this.logger.warn(`User ${userId} is already an assistant in session ${sessionId}`); + throw new BadRequestException('El usuario ya es asistente en esta sesión'); + } + + // Agregar el usuario como asistente a la sesión + const updatedSession = await this.prismaService.session.update({ + where: { id: sessionId }, + data: { + assistants: { + connect: { id: userId } + } + }, + include: { + assistants: true + } + }); + + return { + message: 'Usuario suscrito exitosamente', + sessionId: sessionId, + userId: userId, + sessionDescription: session?.description + }; + + } catch (error: any) { + // Si es una excepción HTTP específica, no la transformamos + if (error instanceof BadRequestException || error instanceof InternalServerErrorException) { + this.logger.error(`Error subscribing user ${userId} to session ${sessionId}: ${error.message}`); + throw error; + } + + // Solo para errores no controlados + this.logger.error(`Unexpected error subscribing user ${userId} to session ${sessionId}: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error al suscribir al usuario'); + } + } + + /** + * Desuscribe un usuario de una sesión + * @param userId ID del usuario + * @param sessionId ID de la sesión + */ + async unsubscribeUserFromSession(userId: string, sessionId: string) { + try { + this.logger.log(`Unsubscribing user ${userId} from session ${sessionId}`); + + const session = await this.sessionsService.findById(sessionId); + + if (!session) { + this.logger.warn(`Session not found: ${sessionId}`); + throw new BadRequestException('Sesión no encontrada'); + } + + // Verificar si el usuario es asistente de esta sesión + const isAssistant = session.assistants.some(assistant => assistant.id === userId); + + if (!isAssistant) { + this.logger.warn(`User ${userId} is not an assistant in session ${sessionId}`); + throw new BadRequestException('El usuario no es asistente en esta sesión'); + } + + // Remover el usuario como asistente de la sesión + await this.prismaService.session.update({ + where: { id: sessionId }, + data: { + assistants: { + disconnect: { id: userId } + } + } + }); + + return { + message: 'Usuario desuscrito exitosamente', + sessionId: sessionId, + userId: userId + }; + + } catch (error: any) { + if (error instanceof BadRequestException || error instanceof InternalServerErrorException) { + this.logger.error(`Error unsubscribing user ${userId} from session ${sessionId}: ${error.message}`); + throw error; + } + + this.logger.error(`Unexpected error unsubscribing user ${userId} from session ${sessionId}: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error al desuscribir al usuario'); + } + } + + /** + * Obtiene todas las sesiones en las que un usuario es asistente + * @param userId ID del usuario + */ + async getUserSessions(userId: string) { + try { + this.logger.log(`Getting sessions for user ${userId}`); + + const user = await this.prismaService.user.findUnique({ + where: { id: userId }, + include: { + assistantSessions: { + include: { + instructors: true, + dates: true + } + } + } + }); + + if (!user) { + throw new BadRequestException('Usuario no encontrado'); + } + + return user.assistantSessions; + } catch (error: any) { + this.logger.error(`Error getting sessions for user ${userId}: ${error.message}`); + throw new InternalServerErrorException('Error al obtener las sesiones del usuario'); + } + } +} diff --git a/bot-wsp/src/user/user.controller.ts b/bot-wsp/src/user/user.controller.ts new file mode 100644 index 0000000..4dd0ad9 --- /dev/null +++ b/bot-wsp/src/user/user.controller.ts @@ -0,0 +1,67 @@ +import { Body, Controller, Get, Param, Post, Put, Query, UseGuards, ForbiddenException, NotFoundException } from '@nestjs/common'; +import { UserService } from './user.service.js'; +import { User as UserModel, UserRole } from '@prisma/client'; +import { UpsertUserDto } from './user.dto.js'; +import { AuthTokenGuard } from '~/common/guards/auth-token.guard'; +import { User } from '~/common/decoratos/user.decorator'; +import { AuthUser } from '~/common/types'; + + +@Controller('users') +export class UserController { + constructor(private readonly userService: UserService) { } + + @Get() + async getUsers(): Promise { + console.log('=== GET /users endpoint called ==='); + const users = await this.userService.findAll(); + console.log(`Found ${users.length} users`); + return users; + } + + @Get('instructor') + async getProfesors(): Promise { + return await this.userService.findAllProfesors(); + } + + @UseGuards(AuthTokenGuard) + @Get(':userId/profile-picture') + async getProfilePicture( + @Param('userId') userId: string, + @User() user: AuthUser + ): Promise<{ profilePicture: string | null; updatedAt: Date | null }> { + // Verificar permisos - debe ser admin, instructor o el mismo usuario + const allowed = user?.role === UserRole.ADMIN || + user?.role === UserRole.INSTRUCTOR || + user?.id === userId; + + if (!allowed) { + throw new ForbiddenException('No tienes permisos para ver esta foto de perfil'); + } + + const foundUser = await this.userService.findById(userId); + + if (!foundUser) { + throw new NotFoundException('Usuario no encontrado'); + } + + return { + profilePicture: foundUser.profilePicture || null, + updatedAt: foundUser.profilePictureUpdatedAt || null + }; + } + + @Post() + async upsertUser(@Body() body: UpsertUserDto) { + return this.userService.upsert(body); + } + + @Put(':userId/active') + async toogleActivateUser( + @Body() body: { deleted: Date | null }, + @Param('userId') userId: string + ) { + return this.userService.toogleActivateUser(userId, body); + } + +} \ No newline at end of file diff --git a/bot-wsp/src/user/user.dto.ts b/bot-wsp/src/user/user.dto.ts new file mode 100644 index 0000000..eda4b38 --- /dev/null +++ b/bot-wsp/src/user/user.dto.ts @@ -0,0 +1,48 @@ +import { User, UserRole } from "@prisma/client"; +import { IsDateString, IsEnum, IsOptional, IsString } from "class-validator"; + +// Define the UserFilter type +export type UserFilter = { + nombre?: string; + birthdayMonth?: number; +}; + +export type UserDataUpdate = Pick + +export class UpsertUserDto { + @IsOptional() + @IsString() + id?: string; // si viene, actualizamos + + @IsString() + customId!: string; + + @IsString() + name!: string; + + @IsOptional() + @IsString() + dni?: string; + + @IsOptional() + @IsString() + phone?: string; + + @IsOptional() + @IsDateString() + birth?: string; + + @IsOptional() + @IsString() + rfid?: string; + + @IsOptional() + @IsDateString() + deleted?: string; + + @IsOptional() + @IsEnum(UserRole) + role?: UserRole; +} + + diff --git a/bot-wsp/src/user/user.module.ts b/bot-wsp/src/user/user.module.ts new file mode 100644 index 0000000..28a3a6e --- /dev/null +++ b/bot-wsp/src/user/user.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { UserController } from './user.controller.js'; +import { UserService } from './user.service.js'; +import { PrismaModule } from '../prisma/prisma.module.js'; +import { CustomIdService } from '../custom-id/custom-id.service.js'; +import { CustomIdModule } from '../custom-id/custom-id.module.js'; + + +@Module({ + controllers: [UserController], + providers: [UserService], + imports: [PrismaModule , CustomIdModule], + exports: [UserService], +}) +export class UserModule {} diff --git a/bot-wsp/src/user/user.service.ts b/bot-wsp/src/user/user.service.ts new file mode 100644 index 0000000..820cec7 --- /dev/null +++ b/bot-wsp/src/user/user.service.ts @@ -0,0 +1,446 @@ +import { ConflictException, ForbiddenException, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common'; +import { Prisma, User, UserRole } from '@prisma/client'; +import { CustomIdService } from '../custom-id/custom-id.service.js'; +import { PrismaService } from '../prisma/prisma.service.js'; +import { UpsertUserDto, UserDataUpdate, UserFilter } from './user.dto.js'; +import { NotFoundError } from 'rxjs'; + + +@Injectable() +export class UserService { + + constructor( + private readonly prisma: PrismaService, + private readonly customIdService: CustomIdService + ) { } + private readonly logger = new Logger(UserService.name); + + async findById(id: string): Promise { + try { + return await this.prisma.user.findUnique({ where: { id } }); + } catch (error: any) { + this.logger.error(`Error al buscar usuario por id: ${id}`, error); + throw new NotFoundException('Usuario no encontrado'); + } + } + + async upsert(dto: UpsertUserDto) { + this.logger.log(`Iniciando upsert de usuario: ${JSON.stringify(dto)}`); + const id = dto.id ?? undefined; + const customId = dto.customId?.trim() || undefined; + + const where = id ? { id } : null; + + const base = { + name: dto.name, + dni: dto.dni ?? '', + phone: dto.phone ?? '', + rfid: dto.rfid ?? '', + birth: dto.birth ? new Date(dto.birth) : null, + deleted: dto.deleted ? new Date(dto.deleted) : null, + role: dto.role ?? UserRole.USER, + } as const; + + try { + if (!where) { + return await this.prisma.user.create({ + data: { + ...base, + customId: customId ?? '', + }, + }); + } + + const exists = await this.prisma.user.findUnique({ where }); + if (exists) { + return await this.prisma.user.update({ + where, + data: { + ...base, + ...(customId !== undefined ? { customId } : {}), + }, + }); + } else { + return await this.prisma.user.create({ + data: { + ...base, + customId: customId ?? '', + }, + }); + } + } catch (error: any) { + if (error instanceof Prisma.PrismaClientKnownRequestError) { + if ( + error.code === 'P2002' && + String(error.meta?.target).includes('phone') + ) { + throw new ConflictException('El teléfono ya está registrado, debe ser único.'); + } + } + + this.logger.error(`Error al realizar upsert del usuario: ${error.message}`, error.stack); + throw new InternalServerErrorException('Error interno al guardar el usuario'); + } + } + + + async findAllProfesors(): Promise { + + try { + const profesors = await this.prisma.user.findMany({ + where: { + role: UserRole.INSTRUCTOR, + } + }) + + return profesors + } + catch (error: any) { + this.logger.error('No pude listar los profesores', error); + throw new InternalServerErrorException('No pude listar los profesores'); + + } + } + async findByPhone(phone: string): Promise { + try { + if (!phone) return null; + + // Debe empezar con 549 (Argentina) + if (!phone.startsWith('549')) { + this.logger.error(`El número no empieza con 549 (Argentina): ${phone}`); + return null; + } + + const normalized = phone.replace(/^549/, ''); + + return await this.prisma.user.findFirst({ + where: { phone: { equals: normalized, mode: 'insensitive' } }, + }); + } catch (err) { + this.logger.error(`No pude encontrar usuario con teléfono ${phone}`, err); + return null; + } + } + + async findByRfid(rfid: string): Promise { + try { + // Primero intentar encontrar usuarios con teléfono + const userWithPhone = await this.prisma.user.findFirst({ + where: { + rfid: { equals: rfid }, + phone: { not: '' } // Que tengan teléfono (no vacío) + }, + orderBy: { createdAt: 'desc' } + }); + + if (userWithPhone) { + return userWithPhone; + } + this.logger.log({ + action: 'findByRfid', + message: `No se encontró usuario con RFID ${rfid} que tenga teléfono registrado.` + }); + // Si no hay ninguno con teléfono, devolver cualquiera con ese RFID + return await this.prisma.user.findFirst({ + where: { rfid: { equals: rfid } }, + orderBy: { createdAt: 'desc' } + }); + } catch (err) { + this.logger.error(`No pude encontro usuario con RFID ${rfid}`, err); + return null + } + } + + async getUserAdmin(): Promise { + try { + this.logger.log('Buscando usuario administrador...'); + return await this.prisma.user.findFirst({ + where: { + role: { equals: UserRole.ADMIN }, + phone: { not: { in: [''] } } + }, + }); + } catch (err) { + this.logger.error('No pude encontrar el usuario administrador', err); + return null + //throw new InternalServerErrorException('No pude encontrar el usuario administrador'); + } + } + + //NOTE Crea un usuario temporal con RFID + async createUserTemporary(rfid: string): Promise { + try { + const customId = await this.customIdService.generateCustomId('user', 'U') + const name = `Desconocido ${customId}` + + return await this.prisma.user.create({ + data: { + rfid, + customId, + name, + role: UserRole.GUEST, + }, + }); + } + catch (err: any) { + throw new InternalServerErrorException(`No pude crear el usuario temporal: ${err.message}`); + } + } + + async findByCustomId(customId: string): Promise { + try { + this.logger.log(`Buscando usuario por customId: ${customId}`); + return await this.prisma.user.findFirst({ + where: { + customId: { equals: customId, mode: 'insensitive' } // Buscar por customId + } + }); + } catch (err) { + this.logger.error(`No pude encontrar usuario con customId ${customId}`, err); + return null; + } + } + + async deleteUser(customId: string): Promise { + try { + const targetUser = await this.prisma.user.findFirst({ + where: { + customId, + }, + }); + if (!targetUser) { + throw new InternalServerErrorException(`No se encontró un usuario con el customId: ${customId}`); + } + const updatedUser = await this.prisma.user.update({ + where: { + id: targetUser.id, + }, + data: { + deleted: new Date(), // Marcar como eliminado + }, + }) + return updatedUser + } + catch (error: any) { + this.logger.error(`No pude eliminar el usuario con customId ${customId}`, error); + throw new InternalServerErrorException(`No pude eliminar el usuario con customId ${customId}`); + } + } + + //Necesito buscar el usuario que esta haciendo la accion , con el currentUserId , cuando el usuario sea instructor , solo puede modificar el nombre y el teléfono + + async updateUserByCustomId( + userData: UserDataUpdate, + currentUserId?: string + ): Promise { + try { + /* 1️⃣ Obtener el usuario que está realizando la acción */ + const currentUser = await this.prisma.user.findUnique({ + where: { id: currentUserId }, + }); + + if (!currentUser) { + throw new InternalServerErrorException( + `No se encontró el usuario que está realizando la acción (id: ${currentUserId})` + ); + } + + /* 2️⃣ Buscar el usuario objetivo por customId */ + const targetUser = await this.prisma.user.findFirst({ + where: { + customId: userData.customId, + }, + }); + + this.logger.log( + `Actualizando usuario: ${targetUser?.name} por hash: ${userData.customId}` + ); + + if (!targetUser) { + throw new InternalServerErrorException( + `No se encontró un usuario con el hash: ${userData.customId}` + ); + } + + /* 3️⃣ Definir los campos que el usuario actual puede modificar */ + const isInstructor = + currentUser.role === UserRole.INSTRUCTOR; + + // Campos que cualquier usuario puede cambiar + const instructorAllowed = ['name', 'phone']; + + // Si el que ejecuta la acción es instructor, restringimos a los + // campos permitidos; de lo contrario, dejamos que modifique todo + const allowedKeys: readonly string[] = isInstructor + ? instructorAllowed + : Object.keys(userData); + + /* 4️⃣ Validar que no se estén intentando actualizar campos no + permitidos (solo para instructors) */ + const disallowed = Object.keys(userData).filter( + (k) => !allowedKeys.includes(k as keyof UserDataUpdate) + ); + + if (disallowed.length > 0) { + // Se lanza una excepción indicando falta de permisos + throw new ForbiddenException( + 'no tienes permisos para actualizar estos campos' + ); + } + + /* 5️⃣ Construir el objeto de datos a actualizar */ + const data: any = {}; + for (const key of allowedKeys) { + const value = (userData as any)[key]; + if (value !== undefined) { + data[key] = value; + } + } + + if (Object.keys(data).length === 0) { + throw new InternalServerErrorException( + 'No se proporcionaron campos válidos para actualizar' + ); + } + + /* 6️⃣ Ejecutar la actualización */ + return await this.prisma.user.update({ + where: { id: targetUser.id }, + data, + }); + } catch (err) { + this.logger.error('No pude actualizar el usuario por hash', err); + throw new InternalServerErrorException( + 'No pude actualizar el usuario por hash' + ); + } + } + + async findAll(): Promise { + try { + return await this.prisma.user.findMany(); + } catch (err) { + // loggear o transformar el error + throw new InternalServerErrorException('No pude listar usuarios'); + } + } + + //TODO: implementar cuando se use IA + async findUserWithNaturalFilters(filters: UserFilter) { + const { nombre, birthdayMonth } = filters; + + let query = `SELECT * FROM "User" WHERE 1=1`; + + const params: any[] = []; + + if (nombre) { + query += ` AND LOWER("name") LIKE LOWER($${params.length + 1})`; + params.push(`%${nombre}%`); + } + + if (birthdayMonth) { + query += ` AND EXTRACT(MONTH FROM "birth") = $${params.length + 1}`; + params.push(birthdayMonth); + } + + const users = await this.prisma.$queryRawUnsafe(query, ...params); + + + return users; + } + + + + + + //getInfoForProfessor + async getInfoForProfessor(professorId: string): Promise { + + } + + async toogleActivateUser(id: string, body: { deleted: Date | null }): Promise { + try { + const user = await this.prisma.user.update({ + where: { id }, + data: { + deleted: body.deleted, + }, + }); + return user; + } catch (error: any) { + this.logger.error(`No pude ${body.deleted ? 'activar' : 'desactivar'} el usuario con id ${id}`, error); + throw new InternalServerErrorException(`No se pudo ${body.deleted ? 'activar' : 'desactivar'} el usuario`); + } + } + + /** + * Actualiza la foto de perfil de un usuario si es necesario + * @param userId ID del usuario + * @param profilePictureBase64 Foto en base64 + * @param intervalDays Intervalo de días para actualizar (por defecto obtiene de config) + * @returns true si se actualizó, false si no era necesario + */ + async updateProfilePictureIfNeeded( + userId: string, + profilePictureBase64: string, + intervalDays?: number + ): Promise { + try { + const user = await this.prisma.user.findUnique({ + where: { id: userId }, + select: { profilePictureUpdatedAt: true } + }); + + if (!user) { + this.logger.warn(`Usuario no encontrado para actualizar foto: ${userId}`); + return false; + } + + const now = new Date(); + const lastUpdate = user.profilePictureUpdatedAt; + + // Si nunca se actualizó, actualizar + if (!lastUpdate) { + this.logger.log(`Primera vez actualizando foto de perfil para usuario: ${userId}`); + await this.prisma.user.update({ + where: { id: userId }, + data: { + profilePicture: profilePictureBase64, + profilePictureUpdatedAt: now + } + }); + return true; + } + + // Calcular días desde la última actualización + const daysSinceUpdate = Math.floor((now.getTime() - lastUpdate.getTime()) / (1000 * 60 * 60 * 24)); + const daysInterval = intervalDays ?? 2; // Por defecto 2 días + + // Si pasó el intervalo, actualizar + if (daysSinceUpdate >= daysInterval) { + this.logger.log(`Actualizando foto de perfil para usuario ${userId} (${daysSinceUpdate} días desde última actualización)`); + await this.prisma.user.update({ + where: { id: userId }, + data: { + profilePicture: profilePictureBase64, + profilePictureUpdatedAt: now + } + }); + return true; + } + + this.logger.debug(`No es necesario actualizar foto de perfil para usuario ${userId} (solo ${daysSinceUpdate} días desde última actualización)`); + return false; + } catch (error: any) { + this.logger.error(`Error actualizando foto de perfil para usuario ${userId}:`, error); + return false; + } + } +} + +type ResponseInfoProfessor = { + //clases donde esta inscripto como profesor => Session[] + //horas trabajadas de este mes => number + //usuarios que asisten a sus clases => User[] + +} \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/flows/admin/adminFlows.ts b/bot-wsp/src/whatsapp/flows/admin/adminFlows.ts new file mode 100644 index 0000000..ae00126 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/adminFlows.ts @@ -0,0 +1,50 @@ +// src/whatsapp/flows/admin/adminFlows.ts +import { registerCreateSessionFlow } from './session/createSessionFlow'; +import { SessionsService } from '../../../sessions/sessions.service'; +import { UserService } from '../../../user/user.service'; +// import { IaService } from '../../../ia/ia.service'; +import { registerListSessionFlow } from './session/listSessionFlow'; +import { registerListUserFlow } from './user/listUserFlow'; +import { registerUserFlow } from './user/userFlow'; +import { registerAdminMenu } from './menu/adminMenu'; +import { registerSessionFlow } from './session/sessionFlow'; +import { registerCreateSubscriptionFlow } from '../subscription/createSubscriptionFlow'; +import { IaSubscriptionService } from '../../../ia/services/ia.subscription.service'; +import { registerUpdateUserFlow } from './user/updateUserFlow'; +import { registeDeleteUserFlow } from './user/deleteUser'; +import { registerModifyUser } from './user/modifyUser'; +import { AuthService } from '../../../auth/auth.service'; + +export const getAdminFlows = ({ + userService, + sessionService, + iaService, + iaSubscription, + authService, +}: { + userService: UserService; + sessionService: SessionsService; + iaService: any; + iaSubscription: IaSubscriptionService; + authService: AuthService +}) => { + const subscriptionFlow = registerCreateSubscriptionFlow({ iaService: iaSubscription }); + //Session + const createSession = registerCreateSessionFlow({ iaService, sessionService }); + const listSession = registerListSessionFlow({ sessionService, iaService }); + //user + const updateUser = registerUpdateUserFlow({ userService, iaService }); + const deleteUser = registeDeleteUserFlow({ userService, iaService }); + const listUser = registerListUserFlow({ iaService, userService }); + const modifyUser = registerModifyUser({ deleteUser, updateUser }); + + //flows + const sessionFlow = registerSessionFlow({ sessionService, createSessionFlow: createSession, listSession, }); + const userFlow = registerUserFlow({ listUser, modifyUser }); + //main menu + const adminMenu = registerAdminMenu({ authService, userService }) + return { + flows: [userFlow, modifyUser, createSession, deleteUser, updateUser, sessionFlow, listSession, listUser, adminMenu, subscriptionFlow], + references: { userFlow, modifyUser, createSession, sessionFlow, listSession, listUser, adminMenu, subscriptionFlow, deleteUser } + }; +}; diff --git a/bot-wsp/src/whatsapp/flows/admin/menu/adminMenu.ts b/bot-wsp/src/whatsapp/flows/admin/menu/adminMenu.ts new file mode 100644 index 0000000..4795c7a --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/menu/adminMenu.ts @@ -0,0 +1,67 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { exitFlow, validateOption } from "~/whatsapp/utils/exitFlow"; +import { UserService } from "~/user/user.service"; +import { AuthService, TokenRedirectURL } from "~/auth/auth.service"; + +type PropsRegisterAdminMenu = { + authService: AuthService; + userService: UserService; +} + +export const registerAdminMenu = ({ + authService, + userService, +}: PropsRegisterAdminMenu) => { + return addKeyword(EVENTS.ACTION) + /* ────────────────────────────────────────────────────── + * 1️⃣ Primer mensaje: saludo + lista de opciones + * ────────────────────────────────────────────────────── */ + .addAction(async (ctx, { flowDynamic, endFlow, state }) => { + const user = await userService.findByPhone(ctx.from); + await flowDynamic(`👋 Hola admin ${user?.name}!`, { delay: 300 }); + + if (!user) { return endFlow(); } + await state.update({ user }); + + await flowDynamic( + `📚 ¿Qué quieres hacer?\n\n` + + `1️⃣ Ingresar a la web\n` + + `2️⃣ Modificar Clases\n` + + `3️⃣ Modificar Usuarios\n` + + `4️⃣ Configuración\n` + + `Escribe *1*, *2*, *3*, *4*, o *cancelar* para salir.`, + { delay: 300 }, + ); + }) + /* ────────────────────────────────────────────────────── + * 2️⃣ Captura de la respuesta del usuario + * ────────────────────────────────────────────────────── */ + .addAction({ capture: true }, async ({ body }, { endFlow, fallBack, state }) => { + const input = body.trim().toLowerCase(); + + // Verificar si el usuario quiere cancelar + if (await exitFlow(input, endFlow, state)) { + return; // exitFlow ya manejó el endFlow + } + + // Validar que la opción sea válida + if (!validateOption(input, ['1', '2', '3', '4'], fallBack)) { + return; // validateOption ya ejecutó el fallBack + } + + const user = state.get("user"); + const optionRedirect: Record = { + "1": TokenRedirectURL.FRONT, + "2": TokenRedirectURL.SESSION, + "3": TokenRedirectURL.USER, + "4": TokenRedirectURL.CONFIG + }; + + const token = await authService.generarToken(user.id, optionRedirect[input]); + + return endFlow(`🔗 Ingresá a la web con este link: ${process.env.URL_FRONT}?t=${token}`); + }); +} diff --git a/bot-wsp/src/whatsapp/flows/admin/session/createSessionFlow.ts b/bot-wsp/src/whatsapp/flows/admin/session/createSessionFlow.ts new file mode 100644 index 0000000..067ede2 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/session/createSessionFlow.ts @@ -0,0 +1,113 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import dayjs from "dayjs"; +import 'dayjs/locale/es'; +// import { IaService } from "../../../../ia/ia.service"; +import { SessionsService, } from "../../../../sessions/sessions.service"; +dayjs.locale('es'); + +export const registerCreateSessionFlow = ({ iaService, sessionService }: { iaService: any, sessionService: SessionsService }) => { + return addKeyword(EVENTS.ACTION) + + // Primer paso: solicitar descripción + .addAction(async (_, { flowDynamic, state }) => { + await flowDynamic('🆕 Crear nueva sesión:\nPor favor, ingresa la descripción de la sesión:'); + await flowDynamic('ℹ️ Ejemplos:\n*Recurrentes*: Clase "Zumba" los lunes a las 10:00AM - 11:00AM \n*Ocasionales*: Clase "Yoga" 30/6/2025 a las 10:00AM - 11:00AM'); + }) + +// // Segundo paso: procesar mensaje del usuario con IA +// .addAction({ capture: true }, async (ctx, { state, flowDynamic, fallBack }) => { +// try { +// const input = ctx.body.trim().toLocaleLowerCase(); + +// if (input.length > 100) { +// return fallBack('El mensaje es demasiado largo. Intenta con una descripción más corta.'); +// } + +// if (input.includes('cancelar')) { +// state.clear(); +// return flowDynamic('❌ Creacion cancelada.'); +// } + +// await flowDynamic('⏳ Procesando...'); + +// const response = await iaService.createSession(input); + +// if (!response || !response.schedules || response.schedules.length === 0) { +// state.clear(); +// return fallBack('❌ No se pudo generar la sesión. Intenta de nuevo.'); +// } + +// await state.update({ dataCreate: response }); + +// await flowDynamic(`🔍 Se creará una nueva clase: +// 📄 *Descripción*: ${response.description} +// 📅 *Tipo*: ${response.type} +// 🕒 *Horarios*: +// ${response.schedules.map((s) => { +// const diaSemana = s.dayOfWeek ? s.dayOfWeek + ' ' : ''; +// const fecha = s.specificDate ? dayjs(s.specificDate).format('DD/MM/YYYY') + ' ' : ''; +// const horaInicio = dayjs(s.startTime).format('HH:mm'); +// const horaFin = dayjs(s.endTime).format('HH:mm'); +// return `- ${diaSemana}${fecha}${horaInicio} - ${horaFin}`; +// }).join('\n')} +// *¿Es correcto?* Responde *si* o *no*.`); +// } catch (error) { +// console.error('Error al procesar el mensaje:', error); +// await state.clear(); +// return fallBack('❌ Ocurrió un error inesperado. Intenta de nuevo.'); +// } +// }) + + // // Tercer paso: confirmar creación de la sesión + // .addAction({ capture: true }, async (ctx, { state, flowDynamic, fallBack }) => { + // try { + // const input = ctx.body.trim().toLowerCase(); + + // if (input !== 'si' && input !== 'no') { + // return fallBack('❗ Responde exactamente *si* o *no*.'); + // } + + // // Si el usuario cancela + // if (input === 'no') { + // await state.clear(); + // return flowDynamic('❌ Creacion cancelada.'); + // } + + // // Si el usuario confirma + // const sessionData: SessionWithSchedules = state.get('dataCreate'); + + // const upsertData: SessionWithSchedulesInput = { + // id: sessionData?.id, + // description: sessionData.description!, + // type: sessionData.type!, + // startDate: sessionData.startDate!, + // endDate: sessionData.endDate!, + // isActive: sessionData.isActive ?? true, + // schedules: sessionData.schedules?.map((schedule) => ({ + // dayOfWeek: schedule.dayOfWeek ?? null, + // specificDate: schedule.specificDate ? new Date(schedule.specificDate) : null, + // startTime: new Date(schedule.startTime), + // endTime: new Date(schedule.endTime), + // isException: schedule.isException ?? false, + // })), + // }; + + // const session = await sessionService.upsertSession(upsertData); + + // if (!session) { + // await state.clear(); + // return fallBack('❌ No se pudo crear la sesión. Intenta de nuevo.'); + // } + + // await flowDynamic('✅ Clase creada exitosamente.\nPuedes verla en el menú de sesiones.'); + // await state.clear(); + // } catch (error) { + // console.error('Error al crear la sesión:', error); + // await state.clear(); + // return fallBack('❌ Ocurrió un error al crear la clase. Intenta de nuevo.'); + // } + // }); +}; diff --git a/bot-wsp/src/whatsapp/flows/admin/session/listSessionFlow copy.txt b/bot-wsp/src/whatsapp/flows/admin/session/listSessionFlow copy.txt new file mode 100644 index 0000000..2e78349 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/session/listSessionFlow copy.txt @@ -0,0 +1,48 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +import { BaileysProvider } from "@builderbot/provider-baileys"; +import dayjs from "dayjs"; +import 'dayjs/locale/es'; +import { IaService } from "../../../../ia/ia.service"; +import { SessionsService } from "../../../../sessions/sessions.service"; +import { generateTimer } from "../../../utils/generateTimer"; +dayjs.locale('es'); + +export const registerListSessionFlow = ({ iaService, sessionService }: { iaService: IaService, sessionService: SessionsService }) => { + return addKeyword(EVENTS.ACTION).addAnswer(`Buscando todas las clases:`) + .addAction(async (_, { flowDynamic }) => { + const clases = await sessionService.findAll(); + if (!clases || clases.length === 0) { + await flowDynamic('❗ No hay clases registradas.'); + return; + } + // Mapeamos cada sesión a una línea de salida + const lines = clases.map((clase) => { + // ID + const id = clase.customId; + + // Descripción (hasta 40 chars) + let desc = clase.description!; + if (desc.length > 40) { + desc = desc.slice(0, 40) + '…'; + } + + // Horarios + const horarios = clase.schedules?.map((i) => { + const dia = i.dayOfWeek + ? i.dayOfWeek + : dayjs(i.specificDate!).format('DD-MM'); + const horaInicio = dayjs(i.startTime).format('HH:mm'); + const horaFin = dayjs(i.endTime).format('HH:mm'); + return `${dia} ${horaInicio}-${horaFin}`; + }).join(', '); + + return `${id} | ${desc} | ${horarios}`; + }); + + // Enviamos todo en un solo mensaje + await flowDynamic( 'Estas son las clases registradas:' ); + for (const line of lines) { + await flowDynamic([{ body: line.trim(), delay: generateTimer(150, 250) }]); + } + }) +}; diff --git a/bot-wsp/src/whatsapp/flows/admin/session/listSessionFlow.ts b/bot-wsp/src/whatsapp/flows/admin/session/listSessionFlow.ts new file mode 100644 index 0000000..c80e579 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/session/listSessionFlow.ts @@ -0,0 +1,110 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; +import dayjs from "dayjs"; +import 'dayjs/locale/es'; +// import { IaService } from "../../../../ia/ia.service"; +import { SessionFilter, SessionsService } from "../../../../sessions/sessions.service"; +import { generateTimer } from "../../../utils/generateTimer"; +import { buildPromptGetSession } from "../../../../ia/prompts/promptGetSession"; +dayjs.locale('es'); + +export const registerListSessionFlow = ({ iaService, sessionService }: { iaService: any, sessionService: SessionsService }) => { + return addKeyword(EVENTS.ACTION) + .addAction(async (_, { flowDynamic }) => { + await flowDynamic(`🤔 ¿Que clases te ayudo a buscar?.\n`, { delay: 300 }); + }) + .addAction({ capture: true }, async ({ body }, { flowDynamic, fallBack }) => { + const input = body.trim().toLocaleLowerCase(); + const prompt = buildPromptGetSession(input); + try { + const where = await iaService.executePrompt(prompt); + + if (!where) { + await flowDynamic('❗ No se pudo interpretar la solicitud.'); + return; + } + + const inputWhere: SessionFilter = { + ...where + } + + await flowDynamic(`🔍 Buscando clases con los siguientes filtros:\n${JSON.stringify(inputWhere, null, 2)}`, { delay: 300 }); + // const clases = await sessionService.findSessionWithNaturalFilters(where); + + // if (!clases || clases.length === 0) { + // return fallBack('❗ No encontramos ninguna clase con esos valores, intenta denuevo'); + // } + // // Mapeamos cada sesión a una línea de salida + // const lines = clases.map((clase) => { + // // ID + // const id = clase.customId; + + // // Descripción (hasta 40 chars) + // let desc = clase.description!; + // if (desc.length > 40) { + // desc = desc.slice(0, 40) + '…'; + // } + + // // Horarios + // const horarios = clase.schedules?.map((i) => { + // const dia = i.dayOfWeek + // ? i.dayOfWeek + // : dayjs(i.specificDate!).format('DD-MM'); + // const horaInicio = dayjs(i.startTime).format('HH:mm'); + // const horaFin = dayjs(i.endTime).format('HH:mm'); + // return `${dia} ${horaInicio}-${horaFin}`; + // }).join(', '); + + // return `${id} | ${desc} | ${horarios}`; + // }); + + // // Enviamos todo en un solo mensaje + // await flowDynamic('Estas son las clases registradas:'); + // for (const line of lines) { + // await flowDynamic([{ body: line.trim(), delay: generateTimer(150, 250) }]); + // } + + + } + catch (error) { + return fallBack('❗ Error al procesar la solicitud. Por favor, intenta de nuevo.'); + } + }) + // .addAction(async (_, { flowDynamic }) => { + // const clases = await sessionService.findAll(); + // if (!clases || clases.length === 0) { + // await flowDynamic('❗ No hay clases registradas.'); + // return; + // } + // // Mapeamos cada sesión a una línea de salida + // const lines = clases.map((clase) => { + // // ID + // const id = clase.customId; + + // // Descripción (hasta 40 chars) + // let desc = clase.description!; + // if (desc.length > 40) { + // desc = desc.slice(0, 40) + '…'; + // } + + // // Horarios + // const horarios = clase.schedules?.map((i) => { + // const dia = i.dayOfWeek + // ? i.dayOfWeek + // : dayjs(i.specificDate!).format('DD-MM'); + // const horaInicio = dayjs(i.startTime).format('HH:mm'); + // const horaFin = dayjs(i.endTime).format('HH:mm'); + // return `${dia} ${horaInicio}-${horaFin}`; + // }).join(', '); + + // return `${id} | ${desc} | ${horarios}`; + // }); + + // // Enviamos todo en un solo mensaje + // await flowDynamic('Estas son las clases registradas:'); + // for (const line of lines) { + // await flowDynamic([{ body: line.trim(), delay: generateTimer(150, 250) }]); + // } + // }) +}; diff --git a/bot-wsp/src/whatsapp/flows/admin/session/sessionFlow.ts b/bot-wsp/src/whatsapp/flows/admin/session/sessionFlow.ts new file mode 100644 index 0000000..203cadd --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/session/sessionFlow.ts @@ -0,0 +1,32 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { TFlow } from "@builderbot/bot/dist/types"; +import { SessionsService } from "../../../../sessions/sessions.service"; +import { exitFlow } from "~/whatsapp/utils/exitFlow"; + +export const registerSessionFlow = ({ sessionService, createSessionFlow, listSession }: { + sessionService: SessionsService, + createSessionFlow: TFlow, + listSession: TFlow, +}) => { + return addKeyword(EVENTS.ACTION) + .addAction(async (_, { flowDynamic }) => { + await flowDynamic('📚 *Gestión de Clases*'); + await flowDynamic('1️⃣ Crear nueva clase\n2️⃣ Ver clases\n3️⃣ Agregar asistente\n4️⃣ Agregar profesor\n'); + await flowDynamic('Escribe el número de la opción que deseas realizar:'); + }) + .addAction({ capture: true }, async (ctx, { gotoFlow, fallBack, endFlow, flowDynamic, state }) => { + const input = ctx.body.trim(); + exitFlow(input, endFlow, state); + + if (input === '1') return gotoFlow(createSessionFlow); + if (input === '2') return gotoFlow(listSession); + //if (option === '2') return gotoFlow(modifySessionFlow({ sessionService })); + // if (option === '3') return gotoFlow(addAssistantFlow({ sessionService })); + // if (option === '4') return gotoFlow(addInstructorFlow({ sessionService })); + + return fallBack('❌ Opción no válida. Escribe 1, 2, 3 o 4.'); + }); +}; diff --git a/bot-wsp/src/whatsapp/flows/admin/user/deleteUser.ts b/bot-wsp/src/whatsapp/flows/admin/user/deleteUser.ts new file mode 100644 index 0000000..7da74c9 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/user/deleteUser.ts @@ -0,0 +1,67 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { exitFlow } from "~/whatsapp/utils/exitFlow"; +import { validateCustomId } from "~/whatsapp/utils/validations/validateCustomId"; +// import { IaService } from "../../../../ia/ia.service"; +import { UserService } from "../../../../user/user.service"; + +export const registeDeleteUserFlow = ({ userService, iaService }: { userService: UserService, iaService: any }) => { + return addKeyword(EVENTS.ACTION) + .addAction(async ({ body }, { flowDynamic, endFlow, state }) => { + await flowDynamic('🤔 ¿A que usuario daremos de baja?'); + await flowDynamic('ℹ Ejemplo: U-001'); + const input = body.trim(); + exitFlow(input, endFlow, state); + }) + .addAction({ capture: true }, async ({ body }, { state, flowDynamic, endFlow, fallBack }) => { + const input = body.trim(); + exitFlow(input, endFlow, state); + + const { customId, error } = validateCustomId(input, 'U') + + await flowDynamic(`Procesando`, { delay: 500 }) + + //NOTE validacion del input del usuario + if (error) { + await flowDynamic(`❌${error}`); + return fallBack('Por favor, intenta de nuevo.'); + } + + if (!customId) { + return fallBack('❌ No se pudo procesar la información del usuario. Intenta de nuevo.'); + } + + const user = await userService.findByCustomId(customId); + + if (!user) { + await flowDynamic(`🔍 No se encontró un usuario con el ID: ${customId}`) + return fallBack('❌ Usuario no encontrado. Asegúrate de que el ID sea correcto.'); + } + await state.update({ hash: user.customId }); + await flowDynamic(`⚠️ El usuario ${user.name} (${user.customId}) será dado de baja.`); + + await flowDynamic(`¿Queres dar de baja al usuario ${user.name} (${user.customId})? Responde *si* o *no* para confirmar la baja.`); + }) + .addAction({ capture: true }, async (ctx, { state, flowDynamic, fallBack, endFlow }) => { + const input = ctx.body.trim().toLowerCase(); + exitFlow(input, endFlow, state); + + if (input.toLowerCase().includes('no') || input.toLowerCase().includes('cancelar')) { + return endFlow('Cancelando modificacion de usuario. Nos vemos pronto!'); + } + const customId = state.get('hash') as string + try { + const updateUser = await userService.deleteUser(customId); + + if (!updateUser) { + return endFlow('❌ Hubo un error al actualizar el usuario. Intenta de nuevo.'); + } + return endFlow(`✅ Usuario ${updateUser.name} dado de baja correctamente.`); + + } catch (error) { + return endFlow('❌ Error en el servidor. Intenta de nuevo más tarde.'); + } + }) +} \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/flows/admin/user/listUserFlow.ts b/bot-wsp/src/whatsapp/flows/admin/user/listUserFlow.ts new file mode 100644 index 0000000..1d92cd5 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/user/listUserFlow.ts @@ -0,0 +1,53 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; +import dayjs from "dayjs"; +import 'dayjs/locale/es'; +import { chunkArray } from "~/whatsapp/utils/chunkArray"; +import { exitFlow } from "~/whatsapp/utils/exitFlow"; +// import { IaService } from "../../../../ia/ia.service"; +import { UserService } from "../../../../user/user.service"; +import { generateTimer } from "../../../utils/generateTimer"; +dayjs.locale('es'); + +export const registerListUserFlow = ({ iaService, userService }: { iaService: any, userService: UserService }) => { + return addKeyword(EVENTS.ACTION).addAnswer(`🔍 Buscando todos los usuarios:`) + .addAction(async ({ body }, { flowDynamic, endFlow, state }) => { + const input = body.trim().toLowerCase(); + exitFlow(input, endFlow, state); + + const users = await userService.findAll(); + if (!users || users.length === 0) { + await flowDynamic('❗ No hay usuarios registradas.'); + return; + } + + // Mapeamos cada sesión a una línea de salida + const lines = users.map((user) => { + // ID + const id = user.customId; + + // Descripción (hasta 40 chars) + let desc = user.name!; + if (desc.length > 40) { + desc = desc.slice(0, 40) + '…'; + } + + + return `${id} | ${desc} `; + }); + + // Agrupar de a 50 + const batches = chunkArray(lines, 50); + + await flowDynamic('Estos son los usuarios registrados:'); + + for (const batch of batches) { + // Unimos el batch en un bloque + const body = batch.join('\n'); + await flowDynamic([{ body, delay: generateTimer(200, 300) }]); + } + + return endFlow('✅ Listado de usuarios finalizado.'); + }); +}; diff --git a/bot-wsp/src/whatsapp/flows/admin/user/modifyUser.ts b/bot-wsp/src/whatsapp/flows/admin/user/modifyUser.ts new file mode 100644 index 0000000..3cd56a3 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/user/modifyUser.ts @@ -0,0 +1,30 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +import { TFlow } from "@builderbot/bot/dist/types"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { exitFlow } from "~/whatsapp/utils/exitFlow"; + +export const registerModifyUser = ({ deleteUser, updateUser }: { + deleteUser: TFlow, + updateUser: TFlow, +}) => { + return addKeyword(EVENTS.ACTION) + .addAction(async (_, { flowDynamic }) => { + await flowDynamic('⚙ *Modificar Usuarios*'); + await flowDynamic('⌨ *Escribe el número de la opción que deseas realizar*'); + await flowDynamic('1️⃣ Alta \n2️⃣ Modificar\n 3️⃣Baja'); + }) + .addAction({ capture: true }, async (ctx, { gotoFlow, fallBack, state }) => { + const input = ctx.body.trim(); + //NOTE Salir del flujo + exitFlow(input, fallBack, state); + + if (input === '1') return gotoFlow(updateUser); + if (input === '2') return gotoFlow(updateUser); + if (input === '3') return gotoFlow(deleteUser); + + + return fallBack('❌ Opción no válida. Escribe *1*, *2*, *3* o cancelar para salir.'); + }); +}; diff --git a/bot-wsp/src/whatsapp/flows/admin/user/updateUserFlow.ts b/bot-wsp/src/whatsapp/flows/admin/user/updateUserFlow.ts new file mode 100644 index 0000000..e991895 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/user/updateUserFlow.ts @@ -0,0 +1,70 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { UserService } from "../../../../user/user.service"; +// import { IaService } from "../../../../ia/ia.service"; +import { validateUserInput } from "../../../utils/validateUserInput"; +import { UserDataUpdate } from "~/user/user.dto"; +import { exitFlow } from "~/whatsapp/utils/exitFlow"; +import dayjs from "dayjs"; + +export const registerUpdateUserFlow = ({ userService, iaService }: { userService: UserService, iaService: any }) => { + return addKeyword(EVENTS.ACTION) + .addAction(async ({ body }, { flowDynamic, endFlow, state }) => { + await flowDynamic('🙏 Voy a pedirte unos datos para modificar el usuario.'); + await flowDynamic('Ejemplo: U-001 Juan Perez 3435077510 18/12/1995'); + const input = body.trim(); + exitFlow(input, endFlow, state); + }) + .addAction({ capture: true }, async ({ body }, { state, flowDynamic, endFlow, fallBack }) => { + const input = body.trim(); + exitFlow(input, endFlow, state); + + await flowDynamic(`Procesando`, { delay: 500 }) + const { errors, data } = validateUserInput(input); + + //NOTE validacion del input del usuario + if (errors.length) { + for (const error of errors) { + await flowDynamic(`❌${error}`); + } + return fallBack('Por favor, intenta de nuevo.'); + } + //TODO para hacer con IA + //const response = await iaService.getUserUpdatePayload(input); + + if (!data) { + return fallBack('❌ No se pudo procesar la información del usuario. Intenta de nuevo.'); + } + + const user = await userService.findByCustomId(data.customId); + + if (!user) { + await flowDynamic(`🔍 No se encontró un usuario con el ID: ${data.customId}`) + return fallBack('❌ Usuario no encontrado. Asegúrate de que el ID sea correcto.'); + } + + await flowDynamic(`⚠️ ¿Queres modificar el usuario nombre: ${user.name} (${user.customId})? \n*Nombre:* ${data.name} \n*Teléfono:* ${data.phone} \n*Fecha de nacimiento:* ${dayjs(data.birth).format('DD/MM/YYYY')}\n\nResponde *si* o *no* para confirmar la actualización.`); + await state.update({ userData: data, hash: user.customId }); + }) + .addAction({ capture: true }, async (ctx, { state, flowDynamic, fallBack, endFlow }) => { + const input = ctx.body.trim().toLowerCase(); + exitFlow(input, endFlow, state); + if (input.toLowerCase().includes('no') || input.toLowerCase().includes('cancelar')) { + return endFlow('Cancelando modificacion de usuario. Nos vemos pronto!'); + } + const userData = state.get('userData') as UserDataUpdate + try { + const updateUser = await userService.updateUserByCustomId(userData); + + if (!updateUser) { + return endFlow('❌ Hubo un error al actualizar el usuario. Intenta de nuevo.'); + } + return endFlow(`✅ Usuario ${updateUser.name} actualizado correctamente.`); + + } catch (error) { + return endFlow('❌ Error en el servidor. Intenta de nuevo más tarde.'); + } + }) +} \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/flows/admin/user/userFlow.ts b/bot-wsp/src/whatsapp/flows/admin/user/userFlow.ts new file mode 100644 index 0000000..ab1c51d --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/admin/user/userFlow.ts @@ -0,0 +1,28 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +import { TFlow } from "@builderbot/bot/dist/types"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { exitFlow } from "~/whatsapp/utils/exitFlow"; + +export const registerUserFlow = ({ modifyUser, listUser }: { + modifyUser: TFlow, + listUser: TFlow, +}) => { + return addKeyword(EVENTS.ACTION) + .addAction(async (_, { flowDynamic }) => { + await flowDynamic('🚻 *Gestión de Usuarios*'); + await flowDynamic('⌨ *Escribe el número de la opción que deseas realizar*'); + await flowDynamic('1️⃣ Modificar \n2️⃣ Ver usuarios\n\n:'); + }) + .addAction({ capture: true }, async (ctx, { gotoFlow, fallBack,endFlow, state }) => { + const input = ctx.body.trim(); + //NOTE Salir del flujo + exitFlow(input, endFlow, state); + + if (input === '1') return gotoFlow(modifyUser); + if (input === '2') return gotoFlow(listUser); + + return fallBack('❌ Opción no válida. Escribe 1, 2'); + }); +}; diff --git a/bot-wsp/src/whatsapp/flows/professor/info/viewInfoFlow.ts b/bot-wsp/src/whatsapp/flows/professor/info/viewInfoFlow.ts new file mode 100644 index 0000000..e69de29 diff --git a/bot-wsp/src/whatsapp/flows/professor/menu/professorMenu.ts b/bot-wsp/src/whatsapp/flows/professor/menu/professorMenu.ts new file mode 100644 index 0000000..5b40197 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/professor/menu/professorMenu.ts @@ -0,0 +1,69 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { UserService } from "~/user/user.service"; +import { AuthService, TokenRedirectURL } from "../../../../auth/auth.service"; +import { exitFlow, validateOption } from "../../../../whatsapp/utils/exitFlow"; + +type PropsProfessorMenu = { + authService: AuthService; + userService: UserService +}; + +/** + * Registra el menú de opciones que verá un profesor cuando envíe + * el evento `EVENTS.ACTION` (el “botón” de acción del flujo). + */ +export const registerProfessorMenu = ({ + authService, + userService, +}: PropsProfessorMenu) => { + return addKeyword(EVENTS.ACTION) + /* ────────────────────────────────────────────────────── + * 1️⃣ Primer mensaje: saludo + lista de opciones + * ────────────────────────────────────────────────────── */ + .addAction(async (ctx, { flowDynamic, endFlow, state }) => { + const user = await userService.findByPhone(ctx.from); + await flowDynamic(`👋 Hola profe ${user?.name}!`, { delay: 300 }); + + if (!user) { return endFlow(); } + await state.update({ user }); + + await flowDynamic( + `📚 ¿Qué quieres hacer?\n\n` + + `1️⃣ Ingresar a la web\n` + + `2️⃣ Modificar Clases\n` + + `3️⃣ Modificar Usuarios\n` + + `Escribe *1*, *2*, *3*, o *cancelar* para salir.`, + { delay: 300 }, + ); + }) + /* ────────────────────────────────────────────────────── + * 2️⃣ Captura de la respuesta del usuario + * ────────────────────────────────────────────────────── */ + .addAction({ capture: true }, async ({ body }, { gotoFlow, endFlow, fallBack, flowDynamic, state }) => { + const input = body.trim().toLowerCase(); + + // Verificar si el usuario quiere cancelar + if (await exitFlow(input, endFlow, state)) { + return; // exitFlow ya manejó el endFlow + } + + // Validar que la opción sea válida + if (!validateOption(input, ['1', '2', '3'], fallBack)) { + return; // validateOption ya ejecutó el fallBack + } + + const user = state.get("user"); + const optionRedirect: Record = { + "1": TokenRedirectURL.FRONT, + "2": TokenRedirectURL.SESSION, + "3": TokenRedirectURL.USER + }; + + const token = await authService.generarToken(user.id, optionRedirect[input]); + + return endFlow(`🔗 Ingresá a la web con este link: ${process.env.URL_FRONT}?t=${token}`); + }); +}; \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/flows/professor/professorFlows.ts b/bot-wsp/src/whatsapp/flows/professor/professorFlows.ts new file mode 100644 index 0000000..14d3bbb --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/professor/professorFlows.ts @@ -0,0 +1,26 @@ + +import { AuthService } from '../../../auth/auth.service'; +import { UserService } from '../../../user/user.service'; +import { registerProfessorMenu } from './menu/professorMenu'; + + +//NOTE Flujo de conversacion para profesores + +export const getProfessorFlows = ({ + userService, + authService, +}: { + userService: UserService; + authService: AuthService; +}) => { + + const professorMenu = registerProfessorMenu({ + authService: authService, + userService: userService, + }) + + return { + flows: [professorMenu], + references: { professorMenu } + }; +}; diff --git a/bot-wsp/src/whatsapp/flows/professor/session/updateSessionFlowProfessor.ts b/bot-wsp/src/whatsapp/flows/professor/session/updateSessionFlowProfessor.ts new file mode 100644 index 0000000..e69de29 diff --git a/bot-wsp/src/whatsapp/flows/subscription/createSubscriptionFlow.ts b/bot-wsp/src/whatsapp/flows/subscription/createSubscriptionFlow.ts new file mode 100644 index 0000000..9f6f3df --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/subscription/createSubscriptionFlow.ts @@ -0,0 +1,104 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import dayjs from "dayjs"; +import 'dayjs/locale/es'; +import { IaSubscriptionService } from "~/ia/services/ia.subscription.service"; +dayjs.locale('es'); + +export const registerCreateSubscriptionFlow = ({ iaService }: { iaService: IaSubscriptionService }) => { + return addKeyword(EVENTS.ACTION) + // Primer paso: solicitar descripción + .addAction(async (ctx, { flowDynamic, state }) => { + await flowDynamic('ℹ️ Ejemplos:\n Vincular a Lea leones a la clase de latino con un 40% de descuento'); + // const input = ctx.body.trim().toLocaleLowerCase(); + }) + // Segundo paso: procesar mensaje del usuario con IA + .addAction({ capture: true }, async (ctx, { state, flowDynamic, fallBack }) => { + try { + // ver si es admin + if (ctx.from !== '5493436453348' || !ctx.body) { + return + } + const esAdmin: boolean = true + const input = ctx.body.trim().toLocaleLowerCase(); + + if (input.length > 100) { + return fallBack('El mensaje es demasiado largo. Intenta con una descripción más corta.'); + } + + if (input.includes('cancelar')) { + state.clear(); + return await flowDynamic('❌ Creacion cancelada.'); + } + + await flowDynamic('⏳ Procesando...'); + + const response = await iaService.subscribeFromNaturalMessage(input, esAdmin); + + if (!response) { + state.clear(); + return fallBack('❌ No se pudo vincular. Intenta de nuevo.'); + } + + await state.update({ base64: response.invoice64 }); + + await flowDynamic(response.message); + await flowDynamic(`Link de pago: ${response.linkPayment}`); + await flowDynamic(`Quieres que te nevie la factura? si / no`); + + } catch (error) { + console.error('Error al procesar el mensaje:', error); + return fallBack('❌ Ocurrió un error inesperado. Intenta de nuevo.'); + } + }) + + // Tercer paso: confirmar creación de la sesión + .addAction({ capture: true }, async (ctx, { state, flowDynamic, fallBack, endFlow, }) => { + try { + const input = ctx.body.trim().toLowerCase(); + + if (input !== 'si' && input !== 'no') { + return fallBack('❗ Responde exactamente *si* o *no*.'); + } + + // Si el usuario cancela + if (input === 'no') { + state.clear(); + return endFlow('Nos vemos pronto!'); + } + + const urlGetPdf = state.get('base64').replace('http://', 'https://'); + + //const path = await saveBase64AsPdf(pdfBase64); + + await flowDynamic([{ media: urlGetPdf, body: 'Factura generada' }]); + + + state.clear(); + return endFlow('Aqui esta la factura, nos vemos pronto!'); + } catch (error) { + console.error('Error al crear la sesión:', error); + await state.clear(); + return fallBack('❌ Ocurrió un error al crear la clase. Intenta de nuevo.'); + } + }) +}; + + +import * as fs from 'fs'; +import * as path from 'path'; +import { v4 as uuidv4 } from 'uuid'; + +const saveBase64AsPdf = (base64: string): Promise => { + const buffer = Buffer.from(base64, 'base64'); + const fileName = `${uuidv4()}.pdf`; + const filePath = path.join(__dirname, '..', 'public', 'pdfs', fileName); + + // Asegurate de tener creada la carpeta 'public/pdfs' + fs.writeFileSync(filePath, buffer); + + // Devolver la URL pública + return Promise.resolve(`https://tuservidor.com/pdfs/${fileName}`); +} diff --git a/bot-wsp/src/whatsapp/flows/user/flows/enrolledNewClassesFlow.ts b/bot-wsp/src/whatsapp/flows/user/flows/enrolledNewClassesFlow.ts new file mode 100644 index 0000000..933e253 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/user/flows/enrolledNewClassesFlow.ts @@ -0,0 +1,161 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { SessionsService } from "../../../../sessions/sessions.service"; +import { SubscriptionsService } from "../../../../subscriptions/subscriptions.service"; +import { exitFlow } from "../../../../whatsapp/utils/exitFlow"; + +// Helpers +const normalize = (s: string) => + (s || "") + .toLowerCase() + .normalize("NFD") + .replace(/\p{Diacritic}/gu, "") + .trim(); + +const isCancel = (s: string) => { + const n = normalize(s); + return ["cancelar", "salir", "cancel", "bye", "chau"].includes(n); +}; +const isYes = (s: string) => { + const n = normalize(s); + return n === "si" || n === "sí" || n === "ok" || n === "dale"; +}; +const isNo = (s: string) => normalize(s) === "no"; + +// NOTE: PARA INSCRIBIRSE +export const registerEnrolledNewClassesFlow = ({ + sessionService, + subscriptionsService, +}: { + sessionService: SessionsService; + subscriptionsService: SubscriptionsService; +}) => { + return addKeyword(EVENTS.ACTION) + + // Paso 1: pedir ID de clase + .addAction({ capture: false }, async (ctx, { flowDynamic, endFlow, state }) => { + const user = state.get("user"); + if (!user?.id) { + await flowDynamic("⚠️ No pudimos validar tu usuario."); + return; + } + await flowDynamic(`📚 *¿A qué clase querés inscribirte ${user.name}?*`); + await flowDynamic("✍️ Escribí el *ID* (customId) de la clase o mandá *cancelar* para salir."); + const input = (ctx.body || "").trim(); + if (await exitFlow(input, endFlow, state)) { return } + }) + + // Paso 2: recibir ID, validar y confirmar + .addAction({ capture: true }, async (ctx, { flowDynamic, endFlow, state }) => { + const inputRaw = (ctx.body || "").trim(); + if (await exitFlow(inputRaw, endFlow, state)) { return } + + const user = state.get("user"); + if (!user?.id) { + await flowDynamic("⚠️ No pudimos validar tu usuario."); + return endFlow(); + } + + const customId = inputRaw.toUpperCase(); + if (customId.length > 10) { + await flowDynamic( + "❗ *No encontramos la clase.* Verificá el ID e intentá de nuevo." + ); + return endFlow(); + } + + try { + const session = await sessionService.findByCustomId(customId); + if (!session) { + await flowDynamic( + "❗ *No encontramos la clase.* Verificá el ID e intentá de nuevo." + ); + return endFlow(); + } + + // Mini resumen de la clase + await flowDynamic([ + "📝 *Resumen de la clase:*", + `• *ID:* ${session.customId}`, + `• *Nombre:* ${session.description}`, + ].join("\n")); + + await flowDynamic("✅ ¿Confirmás la *inscripción* a esta clase? Responé *Sí* o *No*."); + state.update({ session }); + } catch (error) { + console.error('Error al buscar la clase:', error); + await flowDynamic("❗ No pudimos buscar la clase. Intentá más tarde, por favor."); + return endFlow(); + } + }) + + // Paso 3: confirmar y procesar inscripción + suscripción + .addAction({ capture: true }, async (ctx, { fallBack, flowDynamic, endFlow, state }) => { + const confirmRaw = (ctx.body || "").trim(); + exitFlow(confirmRaw, endFlow, state); + + if (isCancel(confirmRaw) || isNo(confirmRaw)) { + await flowDynamic("❌ *Inscripción cancelada.* Si querés, podés elegir otra clase más tarde 🙌"); + return endFlow(); + } + if (!isYes(confirmRaw)) { + fallBack("🤔 No entendí. Por favor respondé *Sí* para inscribirte o *No* para cancelar.") + } + + const user = state.get("user"); + const session = state.get("session"); + if (!user?.id || !session?.id) { + await flowDynamic("⚠️ Ocurrió un problema con tus datos."); + return endFlow(); + } + + // Agregar como asistente a la clase Y crear suscripción en una sola transacción + try { + // Usar la función transaccional que maneja ambas operaciones atómicamente + const result = await sessionService.transactionAddAssistantAndCreateInvoice( + session.id, + user.id + ); + + await flowDynamic(`✅ *¡Listo!* Te inscribiste a *${session.customId}. ${session.description}* 🎉`); + await flowDynamic("🧾 *En breve te enviaremos el link de pago online.*"); + + // Generar link de pago (esto no es parte de la transacción porque involucra APIs externas) + try { + const invoiceId = result.invoice.id; + + // La factura ya tiene link de pago creado en el servicio + if (!result.invoice.linkPayment) { + await flowDynamic("❗ Se completó la inscripción pero no pudimos generar el link de pago. Te contactaremos pronto."); + return endFlow(); + } + + await flowDynamic(`💳 *Link de pago:* ${result.invoice.linkPayment}`); + await flowDynamic("🙏 ¡Gracias por elegirnos! Cualquier duda, estamos acá para ayudarte. ❤️"); + + return endFlow(); + } catch (paymentLinkError) { + console.error('Error obteniendo datos de pago:', paymentLinkError); + await flowDynamic("✅ Tu inscripción fue exitosa. Te enviaremos el link de pago por separado."); + return endFlow(); + } + + } catch (transactionError: any) { + console.error('Error en transacción de inscripción:', transactionError); + + // Como es una transacción, si falla, todo se revierte automáticamente + const errorMessage = transactionError?.message || ''; + + if (errorMessage.includes('already an assistant')) { + await flowDynamic("❗ Ya estás inscripto en esta clase."); + } else if (errorMessage.includes('not found')) { + await flowDynamic("❗ La clase o tu usuario no se encontraron. Intentá más tarde."); + } else { + await flowDynamic("❗ No pudimos completar la inscripción. Intentá más tarde, por favor."); + } + return endFlow(); + } + }); +}; diff --git a/bot-wsp/src/whatsapp/flows/user/flows/viewEnrolledClassesFlow.ts b/bot-wsp/src/whatsapp/flows/user/flows/viewEnrolledClassesFlow.ts new file mode 100644 index 0000000..91b96a9 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/user/flows/viewEnrolledClassesFlow.ts @@ -0,0 +1,47 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { UserService } from "~/user/user.service"; +import { exitFlow } from "~/whatsapp/utils/exitFlow"; +import { SessionsService } from "../../../../sessions/sessions.service"; +import { buildClaseMessage } from "~/whatsapp/utils/buildClaseMessage"; + +// PARA LISTAR LAS CLASES EN LAS QUE STOY INSCRITP +export const registerViewEnrolledClassesFlow = ({ + sessionService, + userService, +}: { + sessionService: SessionsService; + userService: UserService; +}) => { + return addKeyword(EVENTS.ACTION).addAction( + { capture: false }, + async (ctx, { gotoFlow, fallBack, endFlow, flowDynamic, state }) => { + await flowDynamic("📚 *Estas son tus clases*"); + + const input = ctx.body.trim(); + exitFlow(input, endFlow, state); + + const user = await userService.findByPhone(ctx.from); + if (!user) { + await flowDynamic("❗ No estás registrado."); + return; + } + + // Trae TODAS las clases donde el usuario NO es asistente (según tu servicio) + const clases = await sessionService.findAllByUserId(user.id , true); + + if (!Array.isArray(clases) || clases.length === 0) { + await flowDynamic("No encontramos clases para mostrar."); + return; + } + + // Construimos un mensaje por clase + const lines = clases.map((clase: any) => buildClaseMessage(clase)); + + // Enviamos en bloques (flowDynamic acepta array y los va mandando) + await flowDynamic(lines); + } + ); +}; diff --git a/bot-wsp/src/whatsapp/flows/user/flows/viewNewKeysFlowFlow.ts b/bot-wsp/src/whatsapp/flows/user/flows/viewNewKeysFlowFlow.ts new file mode 100644 index 0000000..9a6b019 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/user/flows/viewNewKeysFlowFlow.ts @@ -0,0 +1,64 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { UserService } from "~/user/user.service"; +import { exitFlow } from "~/whatsapp/utils/exitFlow"; +import { SessionsService } from "../../../../sessions/sessions.service"; +import { buildClaseMessage } from "~/whatsapp/utils/buildClaseMessage"; +import { TFlow } from "@builderbot/bot/dist/types"; + + +export const registerViewNewKeysFlow = ({ + sessionService, + userService, + enrollNewClassesFlow +}: { + sessionService: SessionsService; + userService: UserService; + enrollNewClassesFlow: TFlow +}) => { + return addKeyword(EVENTS.ACTION).addAction( + { capture: false }, + async (ctx, { gotoFlow, fallBack, endFlow, flowDynamic, state }) => { + await flowDynamic("📚 *Listado de Clases*"); + + const input = ctx.body.trim(); + if (await exitFlow(input, endFlow, state)) { return } + + + const user = await userService.findByPhone(ctx.from); + if (!user) { + await flowDynamic("❗ No estás registrado."); + return; + } + + // Trae TODAS las clases donde el usuario NO es asistente (según tu servicio) + const clases = await sessionService.findAllNotAssistantByUserId(user.id, true); + + if (!Array.isArray(clases) || clases.length === 0) { + await flowDynamic("😪 No encontramos clases para mostrar. "); + return endFlow(); + } + + // Construimos un mensaje por clase + const lines = clases.map((clase: any) => buildClaseMessage(clase)); + + // Enviamos en bloques (flowDynamic acepta array y los va mandando) + await flowDynamic(lines); + await flowDynamic('Quieres aprovechar e inscribirte en alguna de estas clases? Escribe *Si* o *No*'); + } + ).addAction( + { capture: true }, + async (ctx, { gotoFlow, fallBack, endFlow, flowDynamic, state }) => { + const input = ctx.body.trim(); + if (await exitFlow(input, endFlow, state)) { return } + + if (input.toLowerCase() === 'si') { + return gotoFlow(enrollNewClassesFlow) + } + + await flowDynamic('Perfecto, si necesitas algo más, solo escríbeme. ¡Nos vemos!'); + return endFlow(); + }) +}; diff --git a/bot-wsp/src/whatsapp/flows/user/flows/viewPaymentStatusFlow.ts b/bot-wsp/src/whatsapp/flows/user/flows/viewPaymentStatusFlow.ts new file mode 100644 index 0000000..9248f53 --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/user/flows/viewPaymentStatusFlow.ts @@ -0,0 +1,49 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { UserService } from "~/user/user.service"; +import { exitFlow } from "~/whatsapp/utils/exitFlow"; +import { SessionsService } from "../../../../sessions/sessions.service"; +import { InvoicesService } from "~/invoices/invoices.service"; +import { InvoiceStatus } from "@prisma/client"; + + +export const registerViewPaymentStatusFlow = ({ + sessionService, + userService, + invoicesService, +}: { + sessionService: SessionsService; + userService: UserService; + invoicesService: InvoicesService; +}) => { + return addKeyword(EVENTS.ACTION).addAction( + { capture: false }, + async (ctx, { gotoFlow, fallBack, endFlow, flowDynamic, state }) => { + + const input = ctx.body.trim(); + if (await exitFlow(input, endFlow, state)) { return } + + const user = await userService.findByPhone(ctx.from); + + if (!user) { return endFlow() } + + state.update({ user }); + + const invoices = await invoicesService.findInvoiceThisMonthByUserId(user.id); + if (!invoices || invoices.length === 0) { + await flowDynamic("❗ No tenés facturas este mes."); + return endFlow(); + } else { + let mensaje = "🧾 *Tus facturas de este mes:*\n\n" + invoices.forEach((invoice) => { + mensaje += (invoice.status !== InvoiceStatus.PENDING ? '🟢' : '🔴🐀') + `- Clase: ${invoice.description}, Estado: ${invoice.status}, Monto: ${invoice.amount} ` + (invoice.status !== InvoiceStatus.PENDING ? '' : `link: ${invoice.linkPayment}`) + `\n`; + }); + await flowDynamic(mensaje); + await flowDynamic('Para más información contactarse con el administrador.'); + return endFlow(); + } + } + ) +}; diff --git a/bot-wsp/src/whatsapp/flows/user/menu/userMenu copy.txt b/bot-wsp/src/whatsapp/flows/user/menu/userMenu copy.txt new file mode 100644 index 0000000..f5666da --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/user/menu/userMenu copy.txt @@ -0,0 +1,119 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +import { TFlow } from "@builderbot/bot/dist/types"; +import { BaileysProvider } from "@builderbot/provider-baileys"; +import { InvoicesService } from "~/invoices/invoices.service"; +import { UserService } from "~/user/user.service"; +import { AuthService } from "../../../../auth/auth.service"; +import { IaService } from "../../../../ia/ia.service"; +import { exitFlow } from "../../../../whatsapp/utils/exitFlow"; + +/** + * Props que el flujo de menú necesita. + * Cada una de las propiedades es un *TFlow* que ya está definido en el + * árbol de flujos de la aplicación (por ejemplo `paymentStatusFlow`, + * `enrollClassFlow`, …). Si algún flujo aún no está implementado, + * basta con pasar un flujo “placeholder” que solo envíe un mensaje de + * “en construcción”. + */ +type PropsUserMenu = { + /** Flujo que devuelve el estado de pago del usuario */ + viewPaymentStatusFlow: TFlow; + + /** Flujo que lista las clases a las que el usuario ya está inscrito */ + viewEnrolledClassesFlow: TFlow; + + /** Flujo que muestra las claves (códigos de acceso) nuevas que el usuario puede usar */ + viewNewKeysFlow: TFlow; + + /** Flujo que permite inscribirse a una clase nueva */ + enrollNewClassesFlow: TFlow; + + /** Servicio de IA (opcional, para “inteligente” interpretación de la respuesta) */ + iaService: IaService; + + /** Servicio de autenticación (para validar al usuario) */ + authService: AuthService; + + invoicesService: InvoicesService; + userService: UserService +}; + +/** + * Registra el menú de opciones que verá un usuario cuando envíe + * el evento `EVENTS.ACTION` (el “botón” de acción del flujo). + */ +export const registerUserMenu = ({ + viewPaymentStatusFlow, + viewEnrolledClassesFlow, + viewNewKeysFlow, + enrollNewClassesFlow, + iaService, + authService, + invoicesService, + userService +}: PropsUserMenu) => { + return addKeyword(EVENTS.ACTION) + /* ──────────────────────────────────────────────────────── + * 1️⃣ Primer mensaje: saludo + lista de opciones + * ──────────────────────────────────────────────────────── */ + .addAction(async (ctx, { flowDynamic }) => { + await flowDynamic(`👋 Hola ${ctx.name}!`, { delay: 300 }); + await flowDynamic( + `💳 ¿Qué quieres hacer?\n\n` + + `1️⃣ Consultar estado de pago\n` + + `2️⃣ Consultar clases inscrito\n` + + `3️⃣ Consultar nuevas claves\n` + + `4️⃣ Inscribirse a nuevas clases\n\n` + + `Escribe *1*, *2*, *3*, *4* o *cancelar* para salir.`, + { delay: 300 }, + ); + }) + /* ──────────────────────────────────────────────────────── + * 2️⃣ Captura de la respuesta del usuario + * ──────────────────────────────────────────────────────── */ + .addAction({ capture: true }, async ({ body, from, host }, { gotoFlow, endFlow, fallBack, flowDynamic, state }) => { + const input = body.trim().toLowerCase(); + + /* 2.1. Salir del flujo */ + exitFlow(input, flowDynamic, endFlow, state); + + /* 2.2. Enrutamiento por número */ + if (input === "1") { + await flowDynamic(`🔄 Consultando estado de pago...`, { delay: 300 }); + + // buscar usuario + const usuario = await userService.findByPhone(from); + if (!usuario) { + await flowDynamic(`❌Ocurrio un error, no pudimos encontrarte en nuestro sistema.`, { delay: 300 }); + return endFlow(); + } + + const tieneFacturaPagada = await invoicesService.hasPaidInvoiceThisMonth(usuario.id); + + if (tieneFacturaPagada) { + await flowDynamic(`✅ Tu estado de pago está al día. ¡Muchas Gracias!`, { delay: 300 }); + return endFlow(); + } else { + + // const linkPayment + await flowDynamic(`❌ Tu estado de pago está *pendiente*. Por favor, realiza el pago a la brevedad.`, { delay: 300 }); + } + + await flowDynamic(`✅ Estado de pago consultado con éxito.`, { delay: 300 }); + + return gotoFlow(viewPaymentStatusFlow); // este se resuelve con un flowDynamic + + } + + + + if (input === "2") return gotoFlow(viewEnrolledClassesFlow); + if (input === "3") return gotoFlow(viewNewKeysFlow); + if (input === "4") return gotoFlow(enrollNewClassesFlow); + + /* 2.3. Respuesta inválida */ + return fallBack( + `❌ Opción no válida. Escribe *1*, *2*, *3*, *4* o *cancelar*`, + ); + }); +}; \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/flows/user/menu/userMenu.ts b/bot-wsp/src/whatsapp/flows/user/menu/userMenu.ts new file mode 100644 index 0000000..f9adb3b --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/user/menu/userMenu.ts @@ -0,0 +1,107 @@ +import { addKeyword, EVENTS, MemoryDB } from "@builderbot/bot"; +import { TFlow } from "@builderbot/bot/dist/types"; +// import { BaileysProvider } from "@builderbot/provider-baileys"; +import { BaileysProvider as Provider } from 'aurik3-builderbot-baileys-custom'; + +import { InvoicesService } from "~/invoices/invoices.service"; +import { UserService } from "~/user/user.service"; +import { AuthService } from "../../../../auth/auth.service"; +import { exitFlow } from "../../../../whatsapp/utils/exitFlow"; + +type PropsUserMenu = { + viewPaymentStatusFlow: TFlow; + viewEnrolledClassesFlow: TFlow; + viewNewKeysFlow: TFlow; + enrollNewClassesFlow: TFlow; + authService: AuthService; + invoicesService: InvoicesService; + userService: UserService; +}; + +const userMenuText = + `💳 Este es tu menu:\n\n` + + `1️⃣ Consultar estado de pago\n` + + `2️⃣ Ver inscripcion a clases\n` + + `3️⃣ Consultar nuevas clases\n` + + `4️⃣ Inscribirse a nuevas clases\n\n` + + `Escribe *1*, *2*, *3*, *4* o *cancelar* para salir.`; + +const renderMenu = async (flowDynamic: any) => { + await flowDynamic(userMenuText, { delay: 300 }); +}; + +export const registerUserMenu = ({ + viewPaymentStatusFlow, + viewEnrolledClassesFlow, + viewNewKeysFlow, + enrollNewClassesFlow, + invoicesService, + userService, +}: PropsUserMenu) => { + return addKeyword(EVENTS.ACTION) + // 1) Mensaje inicial + .addAction(async ({ from, body }, { flowDynamic, state, endFlow }) => { + const input = (body ?? "").trim().toLowerCase(); + const user = await userService.findByPhone(from); + + if (await exitFlow(input, endFlow, state)) return; // 👈 cortar + // console.log("USER MENU - USUARIO: ", ctx); + + if (!user) { + await flowDynamic("❗ No estás registrado."); + return; + } + state.update({ user }); + + await flowDynamic(`👋 ¡Hola ${user.name}! ¿en qué te puedo ayudar?`, { delay: 250 }); + await renderMenu(flowDynamic) + }) + // 3) Respónde el menu usuario (resolver por números) + .addAction( + { capture: true }, + async ({ body, from }, { gotoFlow, endFlow, fallBack, flowDynamic, state }) => { + const input = (body ?? "").trim().toLowerCase(); + + + if (await exitFlow(input, endFlow, state)) return; // 👈 cortar + if (input === "1") { + // const res = await handleOption1SideEffects(from, userService, invoicesService, flowDynamic); + // if (res.end) return endFlow(); + return gotoFlow(viewPaymentStatusFlow); + } + if (input === "2") return gotoFlow(viewEnrolledClassesFlow); + if (input === "3") return gotoFlow(viewNewKeysFlow); + if (input === "4") return gotoFlow(enrollNewClassesFlow); + + return fallBack(`❌ Opción no válida. Escribe *1*, *2*, *3*, *4* o *cancelar*`); + //NOTE - QUE HACEMOS ACA ? + await renderMenu(flowDynamic); + } + ); +}; + + + +const handleOption1SideEffects = async ( + from: string, + userService: UserService, + invoicesService: InvoicesService, + flowDynamic: any +) => { + await flowDynamic(`🔄 Consultando estado de pago...`, { delay: 250 }); + + const usuario = await userService.findByPhone(from); + if (!usuario) { + await flowDynamic(`❌ No pudimos encontrarte en nuestro sistema.`, { delay: 250 }); + return { end: true }; + } + + const tieneFacturaPagada = await invoicesService.hasUnpaidInvoiceThisMonth(usuario.id); + if (tieneFacturaPagada) { + await flowDynamic(`✅ Tu estado de pago está al día. ¡Gracias!`, { delay: 250 }); + } else { + await flowDynamic(`❌ Tu estado de pago está *pendiente*.`, { delay: 250 }); + } + await flowDynamic(`✅ Consulta realizada.`, { delay: 200 }); + return { end: false }; +}; \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/flows/user/userFlows.ts b/bot-wsp/src/whatsapp/flows/user/userFlows.ts new file mode 100644 index 0000000..24b5f3e --- /dev/null +++ b/bot-wsp/src/whatsapp/flows/user/userFlows.ts @@ -0,0 +1,50 @@ + +import { AuthService } from '../../../auth/auth.service'; +import { registerUserMenu } from './menu/userMenu'; +import { UserService } from '../../../user/user.service'; +import { SessionsService } from '../../../sessions/sessions.service'; +import { InvoicesService } from '../../../invoices/invoices.service'; +import { registerViewNewKeysFlow } from './flows/viewNewKeysFlowFlow'; + +import { registerViewPaymentStatusFlow } from './flows/viewPaymentStatusFlow'; +import { registerEnrolledNewClassesFlow } from './flows/enrolledNewClassesFlow'; +import { registerViewEnrolledClassesFlow } from './flows/viewEnrolledClassesFlow'; +import { SubscriptionsService } from '../../../subscriptions/subscriptions.service'; + + +//NOTE Flujo de conversacion para usuarios + +export const getUserFlows = ({ + userService, + authService, + invoicesService, + sessionService, + subscriptionsService +}: { + userService: UserService; + invoicesService: InvoicesService; + sessionService: SessionsService; + authService: AuthService; + subscriptionsService: SubscriptionsService; +}) => { + const enrollNewClassesFlow = registerEnrolledNewClassesFlow({ sessionService: sessionService, subscriptionsService: subscriptionsService }); + const viewNewKeysFlow = registerViewNewKeysFlow({ sessionService: sessionService, userService: userService , enrollNewClassesFlow: enrollNewClassesFlow }); + const viewEnrolledClassesFlow = registerViewEnrolledClassesFlow({ sessionService: sessionService, userService: userService }); + const viewPaymentStatusFlow = registerViewPaymentStatusFlow({ sessionService: sessionService, userService: userService , invoicesService: invoicesService }); + + + const userMenu = registerUserMenu({ + authService: authService, + userService: userService, + invoicesService: invoicesService, + viewPaymentStatusFlow: viewPaymentStatusFlow, + viewEnrolledClassesFlow: viewEnrolledClassesFlow, + viewNewKeysFlow: viewNewKeysFlow, + enrollNewClassesFlow: enrollNewClassesFlow, + }) + + return { + flows: [viewNewKeysFlow, viewPaymentStatusFlow, viewEnrolledClassesFlow, enrollNewClassesFlow, userMenu], + references: { userMenu } + }; +}; diff --git a/bot-wsp/src/whatsapp/provider.factory.ts b/bot-wsp/src/whatsapp/provider.factory.ts new file mode 100644 index 0000000..19b7782 --- /dev/null +++ b/bot-wsp/src/whatsapp/provider.factory.ts @@ -0,0 +1,113 @@ +// src/whatsapp/provider.factory.ts +import { createProvider } from '@builderbot/bot'; +import { BaileysProvider } from '@builderbot/provider-baileys'; +import { BaileyGlobalVendorArgs } from '@builderbot/provider-baileys/dist/type.js'; +import { SherpaProvider } from '@builderbot/provider-sherpa'; +import { Logger } from '@nestjs/common'; +import { BaileysProvider as AurikProvider } from 'aurik3-builderbot-baileys-custom'; +import { fetchLatestBaileysVersion } from 'baileys'; + +// ─── Provider type union ────────────────────────────────────────────────────── +export type AnyProvider = BaileysProvider | SherpaProvider | AurikProvider; + +/** + * Versión hardcodeada como fallback (fix para el error 405 de WA – issue #2370). + * WhatsApp rechaza Platform.WEB con versiones antiguas; esta es la última conocida + * que funciona correctamente. + */ +const FALLBACK_WA_VERSION: [number, number, number] = [2, 3000, 1_033_893_291]; + +// ─── Async version resolver ─────────────────────────────────────────────────── +/** + * Obtiene la última versión de WA Web usando fetchLatestBaileysVersion (baileys). + * Si la petición falla usa FALLBACK_WA_VERSION para no bloquear el arranque. + * + * Ref: https://github.com/WhiskeySockets/Baileys/issues/2370 + */ +async function resolveWaVersion(logger: Logger): Promise<[number, number, number]> { + try { + const { version } = await fetchLatestBaileysVersion(); + logger.log(`📱 WA version obtenida remotamente: ${version.join('.')}`); + return version as [number, number, number]; + } catch (err: any) { + logger.warn( + `⚠️ fetchLatestBaileysVersion falló (${err?.message}), usando fallback: ${FALLBACK_WA_VERSION.join('.')}`, + ); + return FALLBACK_WA_VERSION; + } +} + +// ─── Baileys optimised config ───────────────────────────────────────────────── +/** + * Construye la configuración optimizada para Baileys/Aurik. + * @param version - Versión de WA Web resuelta de forma asíncrona. + * + * Fixes aplicados (ref: https://github.com/WhiskeySockets/Baileys/issues/2370): + * - `browser`: simula Chrome en Windows para evitar bloqueos de WA. + * - `version`: usa la versión más reciente de WA Web en lugar de la embebida en + * la librería (que puede estar desactualizada y causar error 405). + */ +export function buildSafeBaileysConfig( + version: [number, number, number] = FALLBACK_WA_VERSION, +): Partial { + return { + // ── WA version + browser fingerprint ─────────────────────────────────── + version, + browser: ['Chrome', 'Windows', '110.0.5481.177'], + + // ── Performance / resource optimisation ──────────────────────────────── + groupsIgnore: true, + readStatus: false, + writeMyself: 'none' as const, + experimentalStore: true, + timeRelease: 10_800_000, // liberar caché cada 3 h + + // ── Connection tuning ─────────────────────────────────────────────────── + markOnlineOnConnect: false, + syncFullHistory: false, + fireInitQueries: false, + shouldSyncHistoryMessage: () => false, + shouldIgnoreJid: (jid: string) => + jid.endsWith('@g.us') || + !jid.includes('@') || + jid.endsWith('@broadcast') || + jid.endsWith('@newsletter'), + retryRequestDelayMs: 250, + maxMsgRetryCount: 5, + msgRetryCounterCache: new Map(), + connectTimeoutMs: 60_000, + defaultQueryTimeoutMs: 60_000, + keepAliveIntervalMs: 20_000, + }; +} + +// ─── Provider factory ───────────────────────────────────────────────────────── +/** + * Instancia el provider de BuilderBot según la variable de entorno PROVIDER. + * + * Valores soportados: + * - "baileys" → @builderbot/provider-baileys + * - "aurik" → aurik3-builderbot-baileys-custom + * - "sherpa" → @builderbot/provider-sherpa (default) + */ +export async function createAdapterProvider(logger: Logger): Promise { + const providerEnv = (process.env.PROVIDER ?? 'sherpa').toLowerCase(); + logger.log(`🔌 Provider seleccionado: "${providerEnv}"`); + + if (providerEnv === 'baileys' || providerEnv === 'aurik') { + const version = await resolveWaVersion(logger); + const config = buildSafeBaileysConfig(version); + + if (providerEnv === 'baileys') { + logger.log('Usando @builderbot/provider-baileys'); + return createProvider(BaileysProvider, config) as AnyProvider; + } + + logger.log('Usando aurik3-builderbot-baileys-custom'); + return createProvider(AurikProvider, config as any) as AnyProvider; + } + + // default: sherpa + logger.log('Usando @builderbot/provider-sherpa'); + return createProvider(SherpaProvider) as AnyProvider; +} diff --git a/bot-wsp/src/whatsapp/provider.factory.txt b/bot-wsp/src/whatsapp/provider.factory.txt new file mode 100644 index 0000000..6bd4679 --- /dev/null +++ b/bot-wsp/src/whatsapp/provider.factory.txt @@ -0,0 +1,113 @@ +// src/whatsapp/provider.factory.ts +import { createProvider } from '@builderbot/bot'; +import { BaileysProvider } from '@builderbot/provider-baileys'; +import { BaileyGlobalVendorArgs } from '@builderbot/provider-baileys/dist/type.js'; +import { SherpaProvider } from '@builderbot/provider-sherpa'; +import { Logger } from '@nestjs/common'; +import { BaileysProvider as AurikProvider } from 'aurik3-builderbot-baileys-custom'; +import { fetchLatestBaileysVersion } from 'baileys'; + +// ─── Provider type union ────────────────────────────────────────────────────── +export type AnyProvider = BaileysProvider | SherpaProvider | AurikProvider; + +/** + * Versión hardcodeada como fallback (fix para el error 405 de WA – issue #2370). + * WhatsApp rechaza Platform.WEB con versiones antiguas; esta es la última conocida + * que funciona correctamente. + */ +const FALLBACK_WA_VERSION: [number, number, number] = [2, 3000, 1_033_893_291]; + +// ─── Async version resolver ─────────────────────────────────────────────────── +/** + * Obtiene la última versión de WA Web usando fetchLatestBaileysVersion (baileys). + * Si la petición falla usa FALLBACK_WA_VERSION para no bloquear el arranque. + * + * Ref: https://github.com/WhiskeySockets/Baileys/issues/2370 + */ +async function resolveWaVersion(logger: Logger): Promise<[number, number, number]> { + try { + const { version } = await fetchLatestBaileysVersion(); + logger.log(`📱 WA version obtenida remotamente: ${version.join('.')}`); + return version as [number, number, number]; + } catch (err: any) { + logger.warn( + `⚠️ fetchLatestBaileysVersion falló (${err?.message}), usando fallback: ${FALLBACK_WA_VERSION.join('.')}`, + ); + return FALLBACK_WA_VERSION; + } +} + +// ─── Baileys optimised config ───────────────────────────────────────────────── +/** + * Construye la configuración optimizada para Baileys/Aurik. + * @param version - Versión de WA Web resuelta de forma asíncrona. + * + * Fixes aplicados (ref: https://github.com/WhiskeySockets/Baileys/issues/2370): + * - `browser`: simula Chrome en Windows para evitar bloqueos de WA. + * - `version`: usa la versión más reciente de WA Web en lugar de la embebida en + * la librería (que puede estar desactualizada y causar error 405). + */ +export function buildSafeBaileysConfig( + version: [number, number, number] = FALLBACK_WA_VERSION, +): Partial { + return { + // ── WA version + browser fingerprint ─────────────────────────────────── + version, + browser: ['Chrome', 'Windows', '110.0.5481.177'], + + // ── Performance / resource optimisation ──────────────────────────────── + groupsIgnore: true, + readStatus: false, + writeMyself: 'both' as const, + experimentalStore: true, + timeRelease: 10_800_000, // liberar caché cada 3 h + + // ── Connection tuning ─────────────────────────────────────────────────── + markOnlineOnConnect: false, + syncFullHistory: false, + fireInitQueries: false, + shouldSyncHistoryMessage: () => false, + shouldIgnoreJid: (jid: string) => + jid.endsWith('@g.us') || + !jid.includes('@') || + jid.endsWith('@broadcast') || + jid.endsWith('@newsletter'), + retryRequestDelayMs: 250, + maxMsgRetryCount: 5, + msgRetryCounterCache: new Map(), + connectTimeoutMs: 60_000, + defaultQueryTimeoutMs: 60_000, + keepAliveIntervalMs: 20_000, + }; +} + +// ─── Provider factory ───────────────────────────────────────────────────────── +/** + * Instancia el provider de BuilderBot según la variable de entorno PROVIDER. + * + * Valores soportados: + * - "baileys" → @builderbot/provider-baileys + * - "aurik" → aurik3-builderbot-baileys-custom + * - "sherpa" → @builderbot/provider-sherpa (default) + */ +export async function createAdapterProvider(logger: Logger): Promise { + const providerEnv = (process.env.PROVIDER ?? 'sherpa').toLowerCase(); + logger.log(`🔌 Provider seleccionado: "${providerEnv}"`); + + if (providerEnv === 'baileys' || providerEnv === 'aurik') { + const version = await resolveWaVersion(logger); + const config = buildSafeBaileysConfig(version); + + if (providerEnv === 'baileys') { + logger.log('Usando @builderbot/provider-baileys'); + return createProvider(BaileysProvider, config) as AnyProvider; + } + + logger.log('Usando aurik3-builderbot-baileys-custom'); + return createProvider(AurikProvider, config as any) as AnyProvider; + } + + // default: sherpa + logger.log('Usando @builderbot/provider-sherpa'); + return createProvider(SherpaProvider) as AnyProvider; +} diff --git a/bot-wsp/src/whatsapp/queue.service.ts b/bot-wsp/src/whatsapp/queue.service.ts new file mode 100644 index 0000000..5a30919 --- /dev/null +++ b/bot-wsp/src/whatsapp/queue.service.ts @@ -0,0 +1,59 @@ +// src/whatsapp/queue.service.ts +import { Injectable, Logger } from '@nestjs/common'; + +interface QueueJob { + /** Función que contiene la lógica concreta a ejecutar para este mensaje */ + handler: () => Promise; +} + +@Injectable() +export class QueueService { + private readonly logger = new Logger(QueueService.name); + + /** Map de userId → lista de jobs pendientes */ + private queues = new Map(); + + /** Map de userId → flag de lock (true mientras procesa) */ + private locks = new Map(); + + /** + * Encola un Job para el userId dado, y si no hay procesamiento en curso lo dispara. + * @param userId Identificador único del usuario (ctx.from) + * @param job Un objeto con un método handler() que retorna una promesa + */ + enqueue(userId: string, job: QueueJob) { + if (!this.queues.has(userId)) { + this.queues.set(userId, []); + } + this.queues.get(userId)!.push(job); + // Si no está bloqueado, arranca el procesamiento + if (!this.locks.get(userId)) { + this.processQueue(userId); + } + } + + /** + * Procesa en orden todos los jobs de la cola de un usuario, + * asegurándose de no correr dos a la vez. + */ + private async processQueue(userId: string) { + const queue = this.queues.get(userId); + if (!queue || queue.length === 0) return; + + while (queue.length > 0) { + this.locks.set(userId, true); + const { handler } = queue.shift()!; + try { + await handler(); + } catch (err) { + this.logger.error(`Error ejecutando job de ${userId}`, err as any); + } finally { + this.locks.set(userId, false); + } + } + + // Una vez vacía, limpiamos + this.queues.delete(userId); + this.locks.delete(userId); + } +} diff --git a/bot-wsp/src/whatsapp/utils/buildClaseMessage.ts b/bot-wsp/src/whatsapp/utils/buildClaseMessage.ts new file mode 100644 index 0000000..f50b72b --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/buildClaseMessage.ts @@ -0,0 +1,17 @@ +import { getInstructorName } from "./getInstructorName"; +import { buildSchedule } from "./buildSchedule"; +import { getCurrentAmount } from "./getCurrentAmount"; +import { formatCurrency } from "./formatCurrency"; + +export const buildClaseMessage = (clase: any): string => { + const profe = getInstructorName(clase); + const horarios = buildSchedule(clase); + const montoStr = formatCurrency(getCurrentAmount(clase)); + + return [ + `*${clase.customId}. ${clase.description}*`, + `👨‍🏫 *Profesor:* ${profe}`, + `🗓️ *Días/horarios:* ${horarios}`, + `💵 *Monto:* ${montoStr}`, + ].join("\n"); +}; diff --git a/bot-wsp/src/whatsapp/utils/buildSchedule.ts b/bot-wsp/src/whatsapp/utils/buildSchedule.ts new file mode 100644 index 0000000..c2c388e --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/buildSchedule.ts @@ -0,0 +1,138 @@ +const TZ = "America/Argentina/Cordoba"; +const dayNames = ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"]; +const monthNames = ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"]; + +type Slot = { dow: number; month: number; year: number; date: Date; timeRange: string; dateLabel: string }; + +/** Cuenta cuántas veces aparece un día de semana (dow) en un mes/año dado */ +function countDowInMonth(year: number, month: number, dow: number): number { + const daysInMonth = new Date(year, month + 1, 0).getDate(); + let count = 0; + for (let d = 1; d <= daysInMonth; d++) { + if (new Date(year, month, d).getDay() === dow) count++; + } + return count; +} + +function parseSlots(ranges: any[]): Slot[] { + const slots: Slot[] = []; + for (const r of ranges) { + if (!r?.start || !r?.end) continue; + const start = new Date(r.start); + const end = new Date(r.end); + if (isNaN(start.getTime()) || isNaN(end.getTime())) continue; + const hStart = start.toLocaleTimeString("es-AR", { hour: "2-digit", minute: "2-digit", hour12: false, timeZone: TZ }); + const hEnd = end.toLocaleTimeString("es-AR", { hour: "2-digit", minute: "2-digit", hour12: false, timeZone: TZ }); + slots.push({ + dow: start.getDay(), + month: start.getMonth(), + year: start.getFullYear(), + date: start, + timeRange: `${hStart}–${hEnd}`, + dateLabel: `${start.getDate()}/${monthNames[start.getMonth()]}`, + }); + } + // ordenar por fecha + return slots.sort((a, b) => a.date.getTime() - b.date.getTime()); +} + +/** + * Agrupa slots por (día de semana + rango horario). + * Dentro de cada grupo, sub-agrupa por mes: + * - Mes regular: sus slots cubren TODOS los días `dow` de ese mes + * - Si hay ≥2 meses regulares → se resumen como "Todos los X de los meses A, B..." + * - El resto (meses incompletos o <2 meses regulares) → fechas individuales + * Todo el output se ordena cronológicamente por la primera fecha de cada ítem. + */ +function buildRecurringSchedule(slots: Slot[]): string { + if (!slots.length) return "—"; + + type OutputItem = { sortKey: Date; text: string }; + + // Agrupar por dow+timeRange + const groups = new Map(); + for (const s of slots) { + const key = `${s.dow}|${s.timeRange}`; + const arr = groups.get(key) ?? []; + arr.push(s); + groups.set(key, arr); + } + + const items: OutputItem[] = []; + + for (const [key, group] of groups) { + const dow = Number(key.split("|")[0]); + const timeRange = group[0].timeRange; + const dayName = dayNames[dow]; + + // Sub-agrupar por año+mes + const byMonth = new Map(); + for (const s of group) { + const k = `${s.year}|${s.month}`; + const arr = byMonth.get(k) ?? []; + arr.push(s); + byMonth.set(k, arr); + } + + const regularMonths: { year: number; month: number; firstDate: Date }[] = []; + const isolatedSlots: Slot[] = []; + + for (const [monthKey, monthSlots] of byMonth) { + const [year, month] = monthKey.split("|").map(Number); + const expected = countDowInMonth(year, month, dow); + const sorted = [...monthSlots].sort((a, b) => a.date.getTime() - b.date.getTime()); + if (monthSlots.length === expected) { + regularMonths.push({ year, month, firstDate: sorted[0].date }); + } else { + isolatedSlots.push(...sorted); + } + } + + // Fechas aisladas → un ítem por fecha + for (const s of isolatedSlots) { + items.push({ sortKey: s.date, text: `${dayName} ${s.dateLabel} ${timeRange}` }); + } + + // Meses regulares + if (regularMonths.length >= 2) { + regularMonths.sort((a, b) => a.year !== b.year ? a.year - b.year : a.month - b.month); + const monthsStr = regularMonths.map(({ month }) => monthNames[month]).join(", "); + items.push({ + sortKey: regularMonths[0].firstDate, + text: `Todos los ${dayName} de los meses ${monthsStr} ${timeRange}`, + }); + } else { + // < 2 meses regulares → también listar sus fechas individualmente + for (const { year, month } of regularMonths) { + for (const s of byMonth.get(`${year}|${month}`) ?? []) { + items.push({ sortKey: s.date, text: `${dayName} ${s.dateLabel} ${timeRange}` }); + } + } + } + } + + // Ordenar todo cronológicamente por la primera fecha de cada ítem + items.sort((a, b) => a.sortKey.getTime() - b.sortKey.getTime()); + return items.map(i => i.text).join(", "); +} + +export const buildSchedule = (clase: any): string => { + // ONE_TIME: viene startDate / endDate (no dates[]) + if (clase?.type === 'ONE_TIME') { + const s = clase?.startDate ? new Date(clase.startDate) : null; + const e = clase?.endDate ? new Date(clase.endDate) : null; + if (!s || !e || isNaN(s.getTime()) || isNaN(e.getTime())) return "—"; + + const dow = s.getDay(); + const dateStr = `${s.getDate()}/${monthNames[s.getMonth()]}`; + const hStart = s.toLocaleTimeString("es-AR", { hour: "2-digit", minute: "2-digit", hour12: false, timeZone: TZ }); + const hEnd = e.toLocaleTimeString("es-AR", { hour: "2-digit", minute: "2-digit", hour12: false, timeZone: TZ }); + return `${dayNames[dow]} ${dateStr} ${hStart}–${hEnd}`; + } + + // RECURRING (u otros): usar dates[] + const ranges = Array.isArray(clase?.dates) ? clase.dates : []; + if (!ranges.length) return "—"; + + return buildRecurringSchedule(parseSlots(ranges)); +}; diff --git a/bot-wsp/src/whatsapp/utils/chunkArray.ts b/bot-wsp/src/whatsapp/utils/chunkArray.ts new file mode 100644 index 0000000..79eb581 --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/chunkArray.ts @@ -0,0 +1,7 @@ +export function chunkArray(arr: T[], size: number): T[][] { + const result: T[][] = []; + for (let i = 0; i < arr.length; i += size) { + result.push(arr.slice(i, i + size)); + } + return result; +} \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/exitFlow.ts b/bot-wsp/src/whatsapp/utils/exitFlow.ts new file mode 100644 index 0000000..fb19860 --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/exitFlow.ts @@ -0,0 +1,50 @@ +/** + * Verifica si el mensaje es una palabra de salida + * @returns true si debe salir del flujo, false en caso contrario + */ +export const shouldExitFlow = (message: string): boolean => { + // normalizo y comparo palabra completa + const norm = (message ?? "") + .toLowerCase() + .normalize('NFD').replace(/\p{Diacritic}/gu, '') + .trim(); + + const finishFlow = new Set(['chau', 'adios', 'salir', 'cancelar']); + + return finishFlow.has(norm); +}; + +/** + * Maneja la salida del flujo con mensaje y limpieza de estado + * Retorna true si se debe salir, false si no + */ +export const exitFlow = async ( + message: string, + endFlow: (message?: string) => Promise | void, + state: any +): Promise => { + if (shouldExitFlow(message)) { + state?.clear?.(); + await endFlow('👋 Nos vemos pronto'); + return true; + } + return false; +}; + +/** + * Valida si la entrada está dentro de las opciones válidas + * Si no es válida, ejecuta fallBack con el mensaje de error + * @returns true si la opción es válida, false si no lo es (y ejecuta fallBack) + */ +export const validateOption = ( + input: string, + validOptions: string[], + fallBack: (message: string) => any +): boolean => { + if (!validOptions.includes(input)) { + const optionsText = validOptions.map(opt => `*${opt}*`).join(', '); + fallBack(`❌ Opción no válida. Escribe ${optionsText} o *cancelar* para salir.`); + return false; + } + return true; +}; diff --git a/bot-wsp/src/whatsapp/utils/formatCurrency.ts b/bot-wsp/src/whatsapp/utils/formatCurrency.ts new file mode 100644 index 0000000..6641ac3 --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/formatCurrency.ts @@ -0,0 +1,5 @@ +// Formatea valores ARS sin decimales “feos” +export const formatCurrency = (value?: number) => + typeof value === "number" + ? new Intl.NumberFormat("es-AR", { style: "currency", currency: "ARS", maximumFractionDigits: 0 }).format(value) + : "—"; diff --git a/bot-wsp/src/whatsapp/utils/generateTimer.ts b/bot-wsp/src/whatsapp/utils/generateTimer.ts new file mode 100644 index 0000000..fb23e4e --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/generateTimer.ts @@ -0,0 +1,9 @@ +function generateTimer(min: number, max: number) { + const numSal = Math.random(); + + const numeroAleatorio = Math.floor(numSal * (max - min + 1)) + min; + + return numeroAleatorio; +} + +export { generateTimer }; \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/getCurrentAmount.ts b/bot-wsp/src/whatsapp/utils/getCurrentAmount.ts new file mode 100644 index 0000000..3c192bc --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/getCurrentAmount.ts @@ -0,0 +1,38 @@ +/** + * Obtiene el precio vigente de una sesión para una fecha específica + * @param clase Objeto sesión con priceHistories + * @param targetDate Fecha para la cual se quiere el precio (opcional, por defecto es ahora) + * @returns Precio vigente para la fecha especificada + */ +export const getCurrentAmount = (clase: any, targetDate?: Date): number | undefined => { + const target = targetDate || new Date(); + + // Si no hay historial de precios, usar el amount de la sesión + if (!Array.isArray(clase?.priceHistories) || clase.priceHistories.length === 0) { + return clase?.amount; + } + + // Ordenar por fecha de inicio (más reciente primero) + const sortedHistory = clase.priceHistories + .sort((a: any, b: any) => new Date(b.effectiveFrom).getTime() - new Date(a.effectiveFrom).getTime()); + + // Buscar el precio aplicable para la fecha objetivo + const applicablePrice = sortedHistory.find((p: any) => { + const from = new Date(p.effectiveFrom); + const to = p.effectiveTo ? new Date(p.effectiveTo) : null; + + // Si es el precio vigente (effectiveTo = null) y la fecha es posterior al inicio + if (!to && from <= target) { + return true; + } + + // Si tiene fecha de fin, verificar que esté en el rango + if (to && from <= target && target < to) { + return true; + } + + return false; + }); + + return applicablePrice?.amount || clase?.amount; +}; \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/getCurrentDayOfWeek.ts b/bot-wsp/src/whatsapp/utils/getCurrentDayOfWeek.ts new file mode 100644 index 0000000..20bf647 --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/getCurrentDayOfWeek.ts @@ -0,0 +1,4 @@ +export const getCurrentDayOfWeek = (): string => { + const dias = ['DOMINGO', 'LUNES', 'MARTES', 'MIERCOLES', 'JUEVES', 'VIERNES', 'SABADO']; + return dias[new Date().getDay()]; +}; \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/getCurrentTime.ts b/bot-wsp/src/whatsapp/utils/getCurrentTime.ts new file mode 100644 index 0000000..f18c7a4 --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/getCurrentTime.ts @@ -0,0 +1,4 @@ +export function getCurrentTime(): Date { + const now = new Date(); + return new Date(1970, 0, 1, now.getHours(), now.getMinutes(), now.getSeconds()); +} \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/getInstructorName.ts b/bot-wsp/src/whatsapp/utils/getInstructorName.ts new file mode 100644 index 0000000..691ec0a --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/getInstructorName.ts @@ -0,0 +1,10 @@ +// Primer instructor (fallback a “—”) +export const getInstructorName = (clase: any): string => { + // compatibilidad si viene "instructor" o "instructors" + const arr = Array.isArray(clase?.instructors) + ? clase.instructors + : Array.isArray(clase?.instructor) + ? clase.instructor + : []; + return arr[0]?.name || "—"; +}; \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/parseTemporalReference.ts b/bot-wsp/src/whatsapp/utils/parseTemporalReference.ts new file mode 100644 index 0000000..04c2ac6 --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/parseTemporalReference.ts @@ -0,0 +1,13 @@ +import * as chrono from 'chrono-node'; + +export const parseTemporalReference = (reference: string): { start: Date; end: Date } | null => { + const parsed = chrono.es.parse(reference); + + if (parsed.length === 0) return null; + + const start = parsed[0].start.date(); + const end = parsed[0].end ? parsed[0].end.date() : new Date(start); + end.setHours(start.getHours() + 1); // Si no hay hora de fin, sumamos 1 hora + + return { start, end }; +} \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/presence.ts b/bot-wsp/src/whatsapp/utils/presence.ts new file mode 100644 index 0000000..b38c08a --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/presence.ts @@ -0,0 +1,14 @@ +const typing = async function (ctx: any, provider: any) { + if (provider && provider?.vendor && provider.vendor?.sendPresenceUpdate) { + const id = ctx.key.remoteJid + await provider.vendor.sendPresenceUpdate('composing', id) + } +} +const recording = async function (ctx: any, provider: any) { + if (provider && provider?.vendor && provider.vendor?.sendPresenceUpdate) { + const id = ctx.key.remoteJid + await provider.vendor.sendPresenceUpdate('recording', id) + } +} + +export { typing, recording } \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/utils/validateUserInput.ts b/bot-wsp/src/whatsapp/utils/validateUserInput.ts new file mode 100644 index 0000000..3410e4e --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/validateUserInput.ts @@ -0,0 +1,72 @@ +type ParsedUser = { + customId: string; + name: string; + phone: string | null; + birth: Date | null; +}; + +export const validateUserInput = (input: string): { errors: string[]; data?: ParsedUser } => { + const errors: string[] = []; + + // 1) ID al inicio: U-XXX (letras o números) + const idMatch = input.match(/^U-[A-Za-z0-9]{3}/); + const customId = idMatch?.[0] ?? ''; + if (!customId) { + errors.push('ID inválido. Debe comenzar con U- seguido de 3 letras o dígitos.'); + } + + // 2) El resto del string sin el ID + const restAfterId = input.slice(customId.length).trim(); + + // 3) Fecha al final: dd/mm/yyyy + const birthMatch = restAfterId.match(/(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/); + const birthStr = birthMatch?.[0] ?? ''; + if (!birthStr) { + errors.push('Fecha de nacimiento inválida. Formato requerido: dd/mm/yyyy.'); + } + + // 4) Resto sin la fecha + const restWithoutBirth = birthStr + ? restAfterId.slice(0, restAfterId.length - birthStr.length).trim() + : restAfterId; + + // 5) Teléfono al final: 7 a 15 dígitos + const phoneMatch = restWithoutBirth.match(/\d{7,15}$/); + const phone = phoneMatch?.[0] ?? null; + if (!phone) { + errors.push('Teléfono inválido. Debe tener entre 7 y 15 dígitos.'); + } + + // 6) Nombre = lo que queda + const name = phone + ? restWithoutBirth.slice(0, restWithoutBirth.length - phone.length).trim() + : restWithoutBirth.trim(); + + if (!/^[A-Za-zÁÉÍÓÚÜÑáéíóúüñ ]+$/.test(name) || name.length === 0) { + errors.push('Nombre inválido. Solo se permiten letras y espacios.'); + } + + // 7) Convertir fecha a objeto Date + let birth: Date | null = null; + if (birthStr) { + const [day, month, year] = birthStr.split('/'); + birth = new Date(`${year}-${month}-${day}`); + if (isNaN(birth.getTime())) { + errors.push('Fecha de nacimiento inválida.'); + } + } + + if (errors.length > 0) { + return { errors }; + } + + return { + errors: [], + data: { + customId, + name, + phone, + birth, + }, + }; +}; diff --git a/bot-wsp/src/whatsapp/utils/validations/validateCustomId.ts b/bot-wsp/src/whatsapp/utils/validations/validateCustomId.ts new file mode 100644 index 0000000..b778b4a --- /dev/null +++ b/bot-wsp/src/whatsapp/utils/validations/validateCustomId.ts @@ -0,0 +1,15 @@ +export function validateCustomId(input: string, prefixChar: string): { customId?: string; error?: string } { + const escapedChar = prefixChar.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); // Escapar cualquier char especial + const regex = new RegExp(`^${escapedChar}-[A-Za-z0-9]{3}`); + const idMatch = input.match(regex); + + if (!idMatch) { + return { + error: `ID inválido. Debe comenzar con ${prefixChar}- seguido de 3 letras o dígitos.`, + }; + } + + return { + customId: idMatch[0], + }; +} \ No newline at end of file diff --git a/bot-wsp/src/whatsapp/whatsapp.controller.ts b/bot-wsp/src/whatsapp/whatsapp.controller.ts new file mode 100644 index 0000000..c60a472 --- /dev/null +++ b/bot-wsp/src/whatsapp/whatsapp.controller.ts @@ -0,0 +1,81 @@ +import { Controller, Get, Param, Query, Sse, UseGuards, MessageEvent as NestMessageEvent } from '@nestjs/common'; +import { ApiTags, ApiBearerAuth, ApiOperation, ApiResponse } from '@nestjs/swagger'; +import { WhatsappService, WhatsappStatus } from './whatsapp.service.js'; +import { AuthTokenGuard } from '../common/guards/auth-token.guard.js'; +import { AuthUser } from '../common/types.js'; +import { User } from '../common/decoratos/user.decorator.js'; +import { distinctUntilChanged, from, interval, map, Observable, share, switchMap } from 'rxjs'; + +@ApiTags('WhatsApp') +@Controller('whatsapp') +export class WhatsappController { + constructor(private readonly whatsappService: WhatsappService) { } + + @Get('status') + @ApiOperation({ + summary: 'Obtener estado del sistema WhatsApp', + description: 'Retorna el estado de conexión de WhatsApp, información del sistema, URL del frontend y otros datos relevantes' + }) + @ApiResponse({ + status: 200, + description: 'Estado del sistema obtenido correctamente', + schema: { + example: { + status: 'Correcto', + phone: '5491112345678', + qr: 'data:image/png;base64,iVBORw0KGgo...', + uptime: 3600, + environment: 'production', + frontUrl: 'https://app.example.com', + apiVersion: '1.0.0', + timestamp: '2025-12-10T21:30:00.000Z' + } + } + }) + async getStatus(): Promise { + return await this.whatsappService.status(); + } + + @Get('send/:number/:message') + async sendMessage( + @Param('number') number: string, + @Param('message') message: string + ): Promise { + return await this.whatsappService.sendText(number, message); + } + + @UseGuards(AuthTokenGuard) + @Get('profile-picture/:phone') + async getProfilePicture( + @Param('phone') phone: string, + @Query('format') format?: 'url' | 'base64', + @User() user?: AuthUser, + ): Promise<{ url: string | null } | { base64: string | null }> { + const allowed = user?.role === 'ADMIN' || user?.role === 'INSTRUCTOR'; + if (!allowed) { + throw new Error('No tienes permisos para obtener fotos de perfil'); + } + + if (format === 'base64') { + const base64 = await this.whatsappService.getProfilePictureBase64(phone); + return { base64 }; + } + + const url = await this.whatsappService.getProfilePicture(phone); + return { url }; + } + + // @UseGuards(AuthTokenGuard) + @Sse('events') + events(): Observable { + return interval(2000).pipe( + switchMap(() => from(this.whatsappService.status())), // Promise -> Observable + distinctUntilChanged( + (a, b) => a.status === b.status && a.phone === b.phone && a.qr === b.qr + ), + map((payload: WhatsappStatus): NestMessageEvent => ({ data: payload })), // 👈 devolvé el tipo de Nest + share(), + ); + } + +} diff --git a/bot-wsp/src/whatsapp/whatsapp.module.ts b/bot-wsp/src/whatsapp/whatsapp.module.ts new file mode 100644 index 0000000..e6a703e --- /dev/null +++ b/bot-wsp/src/whatsapp/whatsapp.module.ts @@ -0,0 +1,20 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { InvoicesModule } from '../invoices/invoices.module.js'; +import { AuthModule } from '../auth/auth.module.js'; +import { IaModule } from '../ia/ia.module.js'; +import { OdooModule } from '../odoo/odoo.module.js'; +import { SessionsModule } from '../sessions/sessions.module.js'; +import { UserModule } from '../user/user.module.js'; +import { QueueService } from './queue.service.js'; +import { WhatsappController } from './whatsapp.controller.js'; +import { WhatsappService } from './whatsapp.service.js'; +import { SubscriptionsModule } from '../subscriptions/subscriptions.module.js'; + + +@Module({ + controllers: [WhatsappController], + providers: [WhatsappService, QueueService], + exports: [WhatsappService], + imports: [UserModule, SessionsModule, OdooModule, forwardRef(() => AuthModule), InvoicesModule, SubscriptionsModule], +}) +export class WhatsappModule { } diff --git a/bot-wsp/src/whatsapp/whatsapp.service.ts b/bot-wsp/src/whatsapp/whatsapp.service.ts new file mode 100644 index 0000000..14ca161 --- /dev/null +++ b/bot-wsp/src/whatsapp/whatsapp.service.ts @@ -0,0 +1,336 @@ +// src/whatsapp/whatsapp.service.ts +import { + addKeyword, + createBot, + createFlow, + EVENTS, + MemoryDB +} from '@builderbot/bot'; +import { + TFlow +} from '@builderbot/bot/dist/types.js'; +import { Injectable, Logger, OnModuleInit } from '@nestjs/common'; +import { UserRole } from '@prisma/client'; +import { readFile } from 'fs/promises'; +import { join } from 'path'; +import { AuthService } from '../auth/auth.service.js'; +import { IaSubscriptionService } from '../ia/services/ia.subscription.service.js'; +import { InvoicesService } from '../invoices/invoices.service.js'; +import { SessionsService } from '../sessions/sessions.service.js'; +import { SubscriptionsService } from '../subscriptions/subscriptions.service.js'; +import { UserService } from '../user/user.service.js'; +import { getAdminFlows } from './flows/admin/adminFlows.js'; +import { getProfessorFlows } from './flows/professor/professorFlows.js'; +import { getUserFlows } from './flows/user/userFlows.js'; +import { AnyProvider, createAdapterProvider } from './provider.factory.js'; + +@Injectable() +export class WhatsappService implements OnModuleInit { + private readonly logger = new Logger(WhatsappService.name); + //@ts-ignore + private provider: AnyProvider; + private stateHandler: any; + private readonly startTime: number = Date.now(); + + constructor( + private userService: UserService, + private sessionService: SessionsService, + private readonly authService: AuthService, + private readonly invoicesService: InvoicesService, + private readonly subscriptionsService: SubscriptionsService, + ) { + } + + /** OnModuleInit: arranca el bot con tu flujo y lo expone como singleton */ + async onModuleInit(): Promise { + this.logger.log('Inicializando WhatsApp bot…'); + try { + const { flows: adminFlows, references } = getAdminFlows({ + userService: this.userService, + sessionService: this.sessionService, + iaService: undefined, + iaSubscription: {} as IaSubscriptionService, + authService: this.authService, + }); + + const { references: referencesUser, flows: userFlows } = getUserFlows({ + authService: this.authService, + userService: this.userService, + invoicesService: this.invoicesService, + sessionService: this.sessionService, + subscriptionsService: this.subscriptionsService, + }) + const { references: referencesProfessor, flows: professorFlows } = getProfessorFlows({ + authService: this.authService, + userService: this.userService, + }) + + + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const welcomeFlow: TFlow = addKeyword(EVENTS.WELCOME) + .addAction(async (ctx, { flowDynamic, gotoFlow, state, fallBack, endFlow }) => { + await flowDynamic('🙌 ¡Hola! Bienvenido al bot.'); + const userFound = await this.userService.findByPhone(ctx.from); + if (!userFound) { return endFlow('❌ Todavia no estás registrado. Por favor, contacta al administrador.') } + + // Actualizar foto de perfil si es necesario + try { + const profilePicBase64 = await this.getProfilePictureBase64(ctx.from); + if (profilePicBase64) { + await this.userService.updateProfilePictureIfNeeded(userFound.id, profilePicBase64); + this.logger.debug(`Foto de perfil procesada para usuario ${userFound.id}`); + } + } catch (error) { + this.logger.warn(`No se pudo actualizar foto de perfil para ${ctx.from}:`, error); + // No fallar el flujo si falla la foto + } + + const role = userFound.role; + + const menuByRole: Record = { + [UserRole.ADMIN]: references.adminMenu, + [UserRole.USER]: referencesUser.userMenu, + [UserRole.INSTRUCTOR]: referencesProfessor.professorMenu, + [UserRole.GUEST]: undefined + } + + //NOTE Detecto si es un usuario admin + const userAdmin = await this.userService.getUserAdmin(); + const { phone } = userAdmin || {}; + + const menu = menuByRole[role]; + + if (!!phone && ctx.from.includes(phone)) { + return gotoFlow(references.adminMenu); + } + + return gotoFlow(menu); + }) + + // 1) Creamos el flows de usuarios + const adapterFlow = createFlow([ + welcomeFlow, + ...adminFlows, + ...userFlows, + ...professorFlows, + ]); + + // 2) Creamos el provider según la variable de entorno PROVIDER + const adapterProvider = await this.createAdapterProvider(); + + // 3) Base de datos en memoria + const adapterDB = new MemoryDB(); + + // 4) Creamos el bot y levantamos su servidor HTTP + const { httpServer, handleCtx, globalStateHandler, provider } = await createBot({ + flow: adapterFlow, + provider: adapterProvider, + database: adapterDB, + }); + + this.stateHandler = provider + this.logger.log('Bot creado exitosamente'); + + // Log del estado del provider para debugging + this.logger.log('Estado del provider después de crear bot:', { + hasProvider: !!provider, + hasVendor: !!provider?.vendor, + vendorKeys: provider?.vendor ? Object.keys(provider.vendor) : [], + }); + + // Escuchar eventos del adapterProvider (no del provider retornado) + if (adapterProvider?.on) { + this.logger.log('✅ Configurando listeners de eventos de Baileys...'); + + adapterProvider.on('ready', () => { + this.logger.log('✅ WhatsApp conectado exitosamente!'); + }); + + adapterProvider.on('auth_failure', (error: any) => { + this.logger.error('❌ Error de autenticación de WhatsApp:', error); + }); + + adapterProvider.on('message', async (msg) => { + this.logger.debug('📨 Mensaje recibido de:', JSON.stringify(msg, null, 2)); + + // Intentar obtener foto de perfil + try { + const jid = msg.key.remoteJid; + if (jid && this.stateHandler?.vendor) { + const profilePicUrl = await this.stateHandler.vendor.profilePictureUrl(jid, 'image'); + this.logger.debug('📸 URL de foto de perfil:', profilePicUrl); + } + } catch (error) { + this.logger.debug('⚠️ No se pudo obtener foto de perfil:', error); + } + }); + } else { + this.logger.warn('⚠️ El adapterProvider no tiene método "on" para escuchar eventos'); + } + + httpServer(+(process.env.PORT_WSP ?? 3008)); + this.logger.log('WhatsApp bot listo en puerto ' + (process.env.PORT_WSP ?? 3008)); + + // 5) Guardamos el provider para uso futuro + this.provider = adapterProvider; + + } catch (err) { + this.logger.error('Error al inicializar WhatsApp bot', err); + } + } + + // ─── Provider factory ──────────────────────────────────────────────────────── + private async createAdapterProvider(): Promise { + return createAdapterProvider(this.logger); + } + + async status(): Promise { + try { + this.logger.debug('📊 Consultando estado de WhatsApp...'); + const qrDataUrl = await this.getQrDataUrl(); + + const state = this.stateHandler?.vendor?.user; + + this.logger.debug('Estado del stateHandler:', { + hasStateHandler: !!this.stateHandler, + hasVendor: !!this.stateHandler?.vendor, + hasUser: !!state, + userId: state?.id, + }); + + const numberPhone = state?.id.split('@')[0].split(':')[0]; + + const phone = numberPhone || null; + const uptime = Math.floor((Date.now() - this.startTime) / 1000); + + const status: WhatsappStatus = { + status: phone ? 'Correcto' : 'Sin session', + phone: phone ?? 'No disponible', + qr: qrDataUrl, + uptime, + environment: process.env.NODE_ENV || 'development', + frontUrl: process.env.FRONT_URL || 'http://localhost:3000', + apiVersion: '1.0.0', + timestamp: new Date().toISOString(), + }; + + this.logger.debug(`Estado: ${status.status}, Phone: ${status.phone}, Has QR: ${!!qrDataUrl}`); + return status; + } catch (error: any) { + this.logger.error('Error al obtener el estado de WhatsApp', error); + throw new Error('No se pudo obtener el estado de WhatsApp'); + } + } + + /** Devuelve `data:image/png;base64,...` o `null` si no existe */ + async getQrDataUrl(): Promise { + // ⚠️ Evitá __dirname confuso al compilar. process.cwd() apunta al root del proyecto. + const possiblePaths = [ + join(process.cwd(), 'bot.qr.png'), + join(process.cwd(), 'bot_sessions', 'bot.qr.png'), + join(process.cwd(), '.baileys', 'bot.qr.png'), + join('/tmp', 'bot.qr.png'), + ]; + + for (const qrPath of possiblePaths) { + try { + this.logger.debug(`🔍 Buscando QR en: ${qrPath}`); + const buf = await readFile(qrPath); // + const base64 = buf.toString('base64'); // "iVBORw0KGgoAAA..." + this.logger.log(`✅ QR encontrado en: ${qrPath}`); + return `data:image/png;base64,${base64}`; + } catch (e: any) { + if (e?.code !== 'ENOENT') { + this.logger.warn(`⚠️ Error leyendo ${qrPath}:`, e?.message); + } + // Si es ENOENT, simplemente continuar con la siguiente ruta + } + } + // no hay QR generado aún + this.logger.debug('❌ No se encontró bot.qr.png en ninguna ubicación'); + this.logger.debug('💡 BuilderBot puede estar mostrando el QR en http://localhost:3008/'); + return null; + } + + + /** Envia un texto */ + async sendText(to: string, text: string) { + if (!this.provider) throw new Error('Bot no inicializado aún'); + const number = to.includes('549') ? to : `549${to}`; + // Quitá todo lo que no sea dígito + const onlyDigits = number.replace(/\D/g, ''); + // Si no viene con @c.us, lo agregas + const jid = number.includes('@') ? number : `${onlyDigits}@c.us`; + this.logger.log(`Enviando mensaje a ${jid}: ${text}`); + return this.provider.sendText(jid, text); + } + + /** + * Obtiene la URL de la foto de perfil de un usuario + * @param phone - Número de teléfono (puede incluir o no 549) + * @param quality - 'image' para alta calidad, 'preview' para baja calidad + * @returns URL de la foto o null si no existe + */ + async getProfilePicture(phone: string, quality: 'image' | 'preview' = 'image'): Promise { + try { + if (!this.stateHandler?.vendor) { + throw new Error('WhatsApp no está conectado'); + } + + // Normalizar el número de teléfono + const number = phone.includes('549') ? phone : `549${phone}`; + const onlyDigits = number.replace(/\D/g, ''); + const jid = number.includes('@') ? number : `${onlyDigits}@s.whatsapp.net`; + + this.logger.log(`Obteniendo foto de perfil de ${jid}`); + + // Obtener la URL de la foto de perfil + const profilePicUrl = await this.stateHandler.vendor.profilePictureUrl(jid, quality); + + this.logger.log(`Foto de perfil obtenida: ${profilePicUrl}`); + return profilePicUrl; + } catch (error: any) { + this.logger.warn(`No se pudo obtener foto de perfil para ${phone}:`, error.message); + return null; + } + } + + /** + * Descarga la foto de perfil y la retorna como base64 + * @param phone - Número de teléfono + * @returns Data URL (data:image/jpeg;base64,...) o null + */ + async getProfilePictureBase64(phone: string): Promise { + try { + const url = await this.getProfilePicture(phone, 'image'); + if (!url) return null; + + // Descargar la imagen + const response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const buffer = await response.arrayBuffer(); + const base64 = Buffer.from(buffer).toString('base64'); + + return `data:image/jpeg;base64,${base64}`; + } catch (error: any) { + this.logger.error(`Error descargando foto de perfil para ${phone}:`, error.message); + return null; + } + } +} + + +export type WhatsappStatus = { + status: 'Correcto' | 'Sin session'; + phone: string; + qr: string | null; // Data URL o null + uptime: number; // segundos desde que inició + environment: string; // production, development, etc + frontUrl: string; // URL del frontend + apiVersion: string; // versión del API + timestamp: string; // ISO timestamp +}; \ No newline at end of file diff --git a/bot-wsp/tmp/.gitkeep b/bot-wsp/tmp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/bot-wsp/tsconfig.build.json b/bot-wsp/tsconfig.build.json new file mode 100644 index 0000000..ffc446d --- /dev/null +++ b/bot-wsp/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "rootDir": "src", // origen de los .ts + "outDir": "dist", // destino de los .js + "incremental": false // opcional: fuerza build limpio siempre + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "dist", "**/*.spec.ts", "**/*.test.ts"] +} diff --git a/bot-wsp/tsconfig.json b/bot-wsp/tsconfig.json new file mode 100644 index 0000000..58fbe59 --- /dev/null +++ b/bot-wsp/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "ES2021", // a qué versión de JS transpilar + "module": "CommonJS", // usar require()/exports para Node + "moduleResolution": "node", + "esModuleInterop": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "incremental": true, + "sourceMap": true, + "baseUrl": ".", + "paths": { + "~/*": [ + "src/*" + ] + } + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "node_modules", + "dist", + "**/*.spec.ts", + "**/*.test.ts" + ] +} \ No newline at end of file diff --git a/bot-wsp/tsconfig.tsbuildinfo b/bot-wsp/tsconfig.tsbuildinfo new file mode 100644 index 0000000..ba4c098 --- /dev/null +++ b/bot-wsp/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"fileNames":["./node_modules/typescript/lib/lib.es5.d.ts","./node_modules/typescript/lib/lib.es2015.d.ts","./node_modules/typescript/lib/lib.es2016.d.ts","./node_modules/typescript/lib/lib.es2017.d.ts","./node_modules/typescript/lib/lib.es2018.d.ts","./node_modules/typescript/lib/lib.es2019.d.ts","./node_modules/typescript/lib/lib.es2020.d.ts","./node_modules/typescript/lib/lib.es2021.d.ts","./node_modules/typescript/lib/lib.es2022.d.ts","./node_modules/typescript/lib/lib.dom.d.ts","./node_modules/typescript/lib/lib.dom.iterable.d.ts","./node_modules/typescript/lib/lib.dom.asynciterable.d.ts","./node_modules/typescript/lib/lib.webworker.importscripts.d.ts","./node_modules/typescript/lib/lib.scripthost.d.ts","./node_modules/typescript/lib/lib.es2015.core.d.ts","./node_modules/typescript/lib/lib.es2015.collection.d.ts","./node_modules/typescript/lib/lib.es2015.generator.d.ts","./node_modules/typescript/lib/lib.es2015.iterable.d.ts","./node_modules/typescript/lib/lib.es2015.promise.d.ts","./node_modules/typescript/lib/lib.es2015.proxy.d.ts","./node_modules/typescript/lib/lib.es2015.reflect.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.d.ts","./node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2016.array.include.d.ts","./node_modules/typescript/lib/lib.es2016.intl.d.ts","./node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","./node_modules/typescript/lib/lib.es2017.date.d.ts","./node_modules/typescript/lib/lib.es2017.object.d.ts","./node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2017.string.d.ts","./node_modules/typescript/lib/lib.es2017.intl.d.ts","./node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","./node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","./node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","./node_modules/typescript/lib/lib.es2018.intl.d.ts","./node_modules/typescript/lib/lib.es2018.promise.d.ts","./node_modules/typescript/lib/lib.es2018.regexp.d.ts","./node_modules/typescript/lib/lib.es2019.array.d.ts","./node_modules/typescript/lib/lib.es2019.object.d.ts","./node_modules/typescript/lib/lib.es2019.string.d.ts","./node_modules/typescript/lib/lib.es2019.symbol.d.ts","./node_modules/typescript/lib/lib.es2019.intl.d.ts","./node_modules/typescript/lib/lib.es2020.bigint.d.ts","./node_modules/typescript/lib/lib.es2020.date.d.ts","./node_modules/typescript/lib/lib.es2020.promise.d.ts","./node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","./node_modules/typescript/lib/lib.es2020.string.d.ts","./node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","./node_modules/typescript/lib/lib.es2020.intl.d.ts","./node_modules/typescript/lib/lib.es2020.number.d.ts","./node_modules/typescript/lib/lib.es2021.promise.d.ts","./node_modules/typescript/lib/lib.es2021.string.d.ts","./node_modules/typescript/lib/lib.es2021.weakref.d.ts","./node_modules/typescript/lib/lib.es2021.intl.d.ts","./node_modules/typescript/lib/lib.es2022.array.d.ts","./node_modules/typescript/lib/lib.es2022.error.d.ts","./node_modules/typescript/lib/lib.es2022.intl.d.ts","./node_modules/typescript/lib/lib.es2022.object.d.ts","./node_modules/typescript/lib/lib.es2022.string.d.ts","./node_modules/typescript/lib/lib.es2022.regexp.d.ts","./node_modules/typescript/lib/lib.decorators.d.ts","./node_modules/typescript/lib/lib.decorators.legacy.d.ts","./node_modules/typescript/lib/lib.es2022.full.d.ts","./node_modules/reflect-metadata/index.d.ts","./node_modules/@nestjs/common/decorators/core/bind.decorator.d.ts","./node_modules/@nestjs/common/interfaces/abstract.interface.d.ts","./node_modules/@nestjs/common/interfaces/controllers/controller-metadata.interface.d.ts","./node_modules/@nestjs/common/interfaces/controllers/controller.interface.d.ts","./node_modules/@nestjs/common/interfaces/features/arguments-host.interface.d.ts","./node_modules/@nestjs/common/interfaces/exceptions/exception-filter.interface.d.ts","./node_modules/rxjs/dist/types/internal/Subscription.d.ts","./node_modules/rxjs/dist/types/internal/Subscriber.d.ts","./node_modules/rxjs/dist/types/internal/Operator.d.ts","./node_modules/rxjs/dist/types/internal/Observable.d.ts","./node_modules/rxjs/dist/types/internal/types.d.ts","./node_modules/rxjs/dist/types/internal/operators/audit.d.ts","./node_modules/rxjs/dist/types/internal/operators/auditTime.d.ts","./node_modules/rxjs/dist/types/internal/operators/buffer.d.ts","./node_modules/rxjs/dist/types/internal/operators/bufferCount.d.ts","./node_modules/rxjs/dist/types/internal/operators/bufferTime.d.ts","./node_modules/rxjs/dist/types/internal/operators/bufferToggle.d.ts","./node_modules/rxjs/dist/types/internal/operators/bufferWhen.d.ts","./node_modules/rxjs/dist/types/internal/operators/catchError.d.ts","./node_modules/rxjs/dist/types/internal/operators/combineLatestAll.d.ts","./node_modules/rxjs/dist/types/internal/operators/combineAll.d.ts","./node_modules/rxjs/dist/types/internal/operators/combineLatest.d.ts","./node_modules/rxjs/dist/types/internal/operators/combineLatestWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/concat.d.ts","./node_modules/rxjs/dist/types/internal/operators/concatAll.d.ts","./node_modules/rxjs/dist/types/internal/operators/concatMap.d.ts","./node_modules/rxjs/dist/types/internal/operators/concatMapTo.d.ts","./node_modules/rxjs/dist/types/internal/operators/concatWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/connect.d.ts","./node_modules/rxjs/dist/types/internal/operators/count.d.ts","./node_modules/rxjs/dist/types/internal/operators/debounce.d.ts","./node_modules/rxjs/dist/types/internal/operators/debounceTime.d.ts","./node_modules/rxjs/dist/types/internal/operators/defaultIfEmpty.d.ts","./node_modules/rxjs/dist/types/internal/operators/delay.d.ts","./node_modules/rxjs/dist/types/internal/operators/delayWhen.d.ts","./node_modules/rxjs/dist/types/internal/operators/dematerialize.d.ts","./node_modules/rxjs/dist/types/internal/operators/distinct.d.ts","./node_modules/rxjs/dist/types/internal/operators/distinctUntilChanged.d.ts","./node_modules/rxjs/dist/types/internal/operators/distinctUntilKeyChanged.d.ts","./node_modules/rxjs/dist/types/internal/operators/elementAt.d.ts","./node_modules/rxjs/dist/types/internal/operators/endWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/every.d.ts","./node_modules/rxjs/dist/types/internal/operators/exhaustAll.d.ts","./node_modules/rxjs/dist/types/internal/operators/exhaust.d.ts","./node_modules/rxjs/dist/types/internal/operators/exhaustMap.d.ts","./node_modules/rxjs/dist/types/internal/operators/expand.d.ts","./node_modules/rxjs/dist/types/internal/operators/filter.d.ts","./node_modules/rxjs/dist/types/internal/operators/finalize.d.ts","./node_modules/rxjs/dist/types/internal/operators/find.d.ts","./node_modules/rxjs/dist/types/internal/operators/findIndex.d.ts","./node_modules/rxjs/dist/types/internal/operators/first.d.ts","./node_modules/rxjs/dist/types/internal/Subject.d.ts","./node_modules/rxjs/dist/types/internal/operators/groupBy.d.ts","./node_modules/rxjs/dist/types/internal/operators/ignoreElements.d.ts","./node_modules/rxjs/dist/types/internal/operators/isEmpty.d.ts","./node_modules/rxjs/dist/types/internal/operators/last.d.ts","./node_modules/rxjs/dist/types/internal/operators/map.d.ts","./node_modules/rxjs/dist/types/internal/operators/mapTo.d.ts","./node_modules/rxjs/dist/types/internal/Notification.d.ts","./node_modules/rxjs/dist/types/internal/operators/materialize.d.ts","./node_modules/rxjs/dist/types/internal/operators/max.d.ts","./node_modules/rxjs/dist/types/internal/operators/merge.d.ts","./node_modules/rxjs/dist/types/internal/operators/mergeAll.d.ts","./node_modules/rxjs/dist/types/internal/operators/mergeMap.d.ts","./node_modules/rxjs/dist/types/internal/operators/flatMap.d.ts","./node_modules/rxjs/dist/types/internal/operators/mergeMapTo.d.ts","./node_modules/rxjs/dist/types/internal/operators/mergeScan.d.ts","./node_modules/rxjs/dist/types/internal/operators/mergeWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/min.d.ts","./node_modules/rxjs/dist/types/internal/observable/ConnectableObservable.d.ts","./node_modules/rxjs/dist/types/internal/operators/multicast.d.ts","./node_modules/rxjs/dist/types/internal/operators/observeOn.d.ts","./node_modules/rxjs/dist/types/internal/operators/onErrorResumeNextWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/pairwise.d.ts","./node_modules/rxjs/dist/types/internal/operators/partition.d.ts","./node_modules/rxjs/dist/types/internal/operators/pluck.d.ts","./node_modules/rxjs/dist/types/internal/operators/publish.d.ts","./node_modules/rxjs/dist/types/internal/operators/publishBehavior.d.ts","./node_modules/rxjs/dist/types/internal/operators/publishLast.d.ts","./node_modules/rxjs/dist/types/internal/operators/publishReplay.d.ts","./node_modules/rxjs/dist/types/internal/operators/race.d.ts","./node_modules/rxjs/dist/types/internal/operators/raceWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/reduce.d.ts","./node_modules/rxjs/dist/types/internal/operators/repeat.d.ts","./node_modules/rxjs/dist/types/internal/operators/repeatWhen.d.ts","./node_modules/rxjs/dist/types/internal/operators/retry.d.ts","./node_modules/rxjs/dist/types/internal/operators/retryWhen.d.ts","./node_modules/rxjs/dist/types/internal/operators/refCount.d.ts","./node_modules/rxjs/dist/types/internal/operators/sample.d.ts","./node_modules/rxjs/dist/types/internal/operators/sampleTime.d.ts","./node_modules/rxjs/dist/types/internal/operators/scan.d.ts","./node_modules/rxjs/dist/types/internal/operators/sequenceEqual.d.ts","./node_modules/rxjs/dist/types/internal/operators/share.d.ts","./node_modules/rxjs/dist/types/internal/operators/shareReplay.d.ts","./node_modules/rxjs/dist/types/internal/operators/single.d.ts","./node_modules/rxjs/dist/types/internal/operators/skip.d.ts","./node_modules/rxjs/dist/types/internal/operators/skipLast.d.ts","./node_modules/rxjs/dist/types/internal/operators/skipUntil.d.ts","./node_modules/rxjs/dist/types/internal/operators/skipWhile.d.ts","./node_modules/rxjs/dist/types/internal/operators/startWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/subscribeOn.d.ts","./node_modules/rxjs/dist/types/internal/operators/switchAll.d.ts","./node_modules/rxjs/dist/types/internal/operators/switchMap.d.ts","./node_modules/rxjs/dist/types/internal/operators/switchMapTo.d.ts","./node_modules/rxjs/dist/types/internal/operators/switchScan.d.ts","./node_modules/rxjs/dist/types/internal/operators/take.d.ts","./node_modules/rxjs/dist/types/internal/operators/takeLast.d.ts","./node_modules/rxjs/dist/types/internal/operators/takeUntil.d.ts","./node_modules/rxjs/dist/types/internal/operators/takeWhile.d.ts","./node_modules/rxjs/dist/types/internal/operators/tap.d.ts","./node_modules/rxjs/dist/types/internal/operators/throttle.d.ts","./node_modules/rxjs/dist/types/internal/operators/throttleTime.d.ts","./node_modules/rxjs/dist/types/internal/operators/throwIfEmpty.d.ts","./node_modules/rxjs/dist/types/internal/operators/timeInterval.d.ts","./node_modules/rxjs/dist/types/internal/operators/timeout.d.ts","./node_modules/rxjs/dist/types/internal/operators/timeoutWith.d.ts","./node_modules/rxjs/dist/types/internal/operators/timestamp.d.ts","./node_modules/rxjs/dist/types/internal/operators/toArray.d.ts","./node_modules/rxjs/dist/types/internal/operators/window.d.ts","./node_modules/rxjs/dist/types/internal/operators/windowCount.d.ts","./node_modules/rxjs/dist/types/internal/operators/windowTime.d.ts","./node_modules/rxjs/dist/types/internal/operators/windowToggle.d.ts","./node_modules/rxjs/dist/types/internal/operators/windowWhen.d.ts","./node_modules/rxjs/dist/types/internal/operators/withLatestFrom.d.ts","./node_modules/rxjs/dist/types/internal/operators/zip.d.ts","./node_modules/rxjs/dist/types/internal/operators/zipAll.d.ts","./node_modules/rxjs/dist/types/internal/operators/zipWith.d.ts","./node_modules/rxjs/dist/types/operators/index.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/Action.d.ts","./node_modules/rxjs/dist/types/internal/Scheduler.d.ts","./node_modules/rxjs/dist/types/internal/testing/TestMessage.d.ts","./node_modules/rxjs/dist/types/internal/testing/SubscriptionLog.d.ts","./node_modules/rxjs/dist/types/internal/testing/SubscriptionLoggable.d.ts","./node_modules/rxjs/dist/types/internal/testing/ColdObservable.d.ts","./node_modules/rxjs/dist/types/internal/testing/HotObservable.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/AsyncScheduler.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/timerHandle.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/AsyncAction.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/VirtualTimeScheduler.d.ts","./node_modules/rxjs/dist/types/internal/testing/TestScheduler.d.ts","./node_modules/rxjs/dist/types/testing/index.d.ts","./node_modules/rxjs/dist/types/internal/symbol/observable.d.ts","./node_modules/rxjs/dist/types/internal/observable/dom/animationFrames.d.ts","./node_modules/rxjs/dist/types/internal/BehaviorSubject.d.ts","./node_modules/rxjs/dist/types/internal/ReplaySubject.d.ts","./node_modules/rxjs/dist/types/internal/AsyncSubject.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/AsapScheduler.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/asap.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/async.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/QueueScheduler.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/queue.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/AnimationFrameScheduler.d.ts","./node_modules/rxjs/dist/types/internal/scheduler/animationFrame.d.ts","./node_modules/rxjs/dist/types/internal/util/identity.d.ts","./node_modules/rxjs/dist/types/internal/util/pipe.d.ts","./node_modules/rxjs/dist/types/internal/util/noop.d.ts","./node_modules/rxjs/dist/types/internal/util/isObservable.d.ts","./node_modules/rxjs/dist/types/internal/lastValueFrom.d.ts","./node_modules/rxjs/dist/types/internal/firstValueFrom.d.ts","./node_modules/rxjs/dist/types/internal/util/ArgumentOutOfRangeError.d.ts","./node_modules/rxjs/dist/types/internal/util/EmptyError.d.ts","./node_modules/rxjs/dist/types/internal/util/NotFoundError.d.ts","./node_modules/rxjs/dist/types/internal/util/ObjectUnsubscribedError.d.ts","./node_modules/rxjs/dist/types/internal/util/SequenceError.d.ts","./node_modules/rxjs/dist/types/internal/util/UnsubscriptionError.d.ts","./node_modules/rxjs/dist/types/internal/observable/bindCallback.d.ts","./node_modules/rxjs/dist/types/internal/observable/bindNodeCallback.d.ts","./node_modules/rxjs/dist/types/internal/AnyCatcher.d.ts","./node_modules/rxjs/dist/types/internal/observable/combineLatest.d.ts","./node_modules/rxjs/dist/types/internal/observable/concat.d.ts","./node_modules/rxjs/dist/types/internal/observable/connectable.d.ts","./node_modules/rxjs/dist/types/internal/observable/defer.d.ts","./node_modules/rxjs/dist/types/internal/observable/empty.d.ts","./node_modules/rxjs/dist/types/internal/observable/forkJoin.d.ts","./node_modules/rxjs/dist/types/internal/observable/from.d.ts","./node_modules/rxjs/dist/types/internal/observable/fromEvent.d.ts","./node_modules/rxjs/dist/types/internal/observable/fromEventPattern.d.ts","./node_modules/rxjs/dist/types/internal/observable/generate.d.ts","./node_modules/rxjs/dist/types/internal/observable/iif.d.ts","./node_modules/rxjs/dist/types/internal/observable/interval.d.ts","./node_modules/rxjs/dist/types/internal/observable/merge.d.ts","./node_modules/rxjs/dist/types/internal/observable/never.d.ts","./node_modules/rxjs/dist/types/internal/observable/of.d.ts","./node_modules/rxjs/dist/types/internal/observable/onErrorResumeNext.d.ts","./node_modules/rxjs/dist/types/internal/observable/pairs.d.ts","./node_modules/rxjs/dist/types/internal/observable/partition.d.ts","./node_modules/rxjs/dist/types/internal/observable/race.d.ts","./node_modules/rxjs/dist/types/internal/observable/range.d.ts","./node_modules/rxjs/dist/types/internal/observable/throwError.d.ts","./node_modules/rxjs/dist/types/internal/observable/timer.d.ts","./node_modules/rxjs/dist/types/internal/observable/using.d.ts","./node_modules/rxjs/dist/types/internal/observable/zip.d.ts","./node_modules/rxjs/dist/types/internal/scheduled/scheduled.d.ts","./node_modules/rxjs/dist/types/internal/config.d.ts","./node_modules/rxjs/dist/types/index.d.ts","./node_modules/@nestjs/common/interfaces/exceptions/rpc-exception-filter.interface.d.ts","./node_modules/@nestjs/common/interfaces/exceptions/ws-exception-filter.interface.d.ts","./node_modules/@nestjs/common/interfaces/external/validation-error.interface.d.ts","./node_modules/@nestjs/common/interfaces/features/execution-context.interface.d.ts","./node_modules/@nestjs/common/interfaces/features/can-activate.interface.d.ts","./node_modules/@nestjs/common/interfaces/features/custom-route-param-factory.interface.d.ts","./node_modules/@nestjs/common/interfaces/features/nest-interceptor.interface.d.ts","./node_modules/@nestjs/common/interfaces/features/paramtype.interface.d.ts","./node_modules/@nestjs/common/interfaces/type.interface.d.ts","./node_modules/@nestjs/common/interfaces/features/pipe-transform.interface.d.ts","./node_modules/@nestjs/common/enums/request-method.enum.d.ts","./node_modules/@nestjs/common/enums/http-status.enum.d.ts","./node_modules/@nestjs/common/enums/shutdown-signal.enum.d.ts","./node_modules/@nestjs/common/enums/version-type.enum.d.ts","./node_modules/@nestjs/common/enums/index.d.ts","./node_modules/@nestjs/common/interfaces/version-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/middleware/middleware-configuration.interface.d.ts","./node_modules/@nestjs/common/interfaces/middleware/middleware-consumer.interface.d.ts","./node_modules/@nestjs/common/interfaces/middleware/middleware-config-proxy.interface.d.ts","./node_modules/@nestjs/common/interfaces/middleware/nest-middleware.interface.d.ts","./node_modules/@nestjs/common/interfaces/middleware/index.d.ts","./node_modules/@nestjs/common/interfaces/global-prefix-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/hooks/before-application-shutdown.interface.d.ts","./node_modules/@nestjs/common/interfaces/hooks/on-application-bootstrap.interface.d.ts","./node_modules/@nestjs/common/interfaces/hooks/on-application-shutdown.interface.d.ts","./node_modules/@nestjs/common/interfaces/hooks/on-destroy.interface.d.ts","./node_modules/@nestjs/common/interfaces/hooks/on-init.interface.d.ts","./node_modules/@nestjs/common/interfaces/hooks/index.d.ts","./node_modules/@nestjs/common/interfaces/http/http-exception-body.interface.d.ts","./node_modules/@nestjs/common/interfaces/http/http-redirect-response.interface.d.ts","./node_modules/@nestjs/common/interfaces/external/cors-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/external/https-options.interface.d.ts","./node_modules/@nestjs/common/services/logger.service.d.ts","./node_modules/@nestjs/common/interfaces/nest-application-context-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/nest-application-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/http/http-server.interface.d.ts","./node_modules/@nestjs/common/interfaces/http/message-event.interface.d.ts","./node_modules/@nestjs/common/interfaces/http/raw-body-request.interface.d.ts","./node_modules/@nestjs/common/interfaces/http/index.d.ts","./node_modules/@nestjs/common/interfaces/injectable.interface.d.ts","./node_modules/@nestjs/common/interfaces/microservices/nest-hybrid-application-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/forward-reference.interface.d.ts","./node_modules/@nestjs/common/interfaces/scope-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/injection-token.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/optional-factory-dependency.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/provider.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/module-metadata.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/dynamic-module.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/introspection-result.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/nest-module.interface.d.ts","./node_modules/@nestjs/common/interfaces/modules/index.d.ts","./node_modules/@nestjs/common/interfaces/nest-application-context.interface.d.ts","./node_modules/@nestjs/common/interfaces/websockets/web-socket-adapter.interface.d.ts","./node_modules/@nestjs/common/interfaces/nest-application.interface.d.ts","./node_modules/@nestjs/common/interfaces/nest-microservice.interface.d.ts","./node_modules/@nestjs/common/interfaces/index.d.ts","./node_modules/@nestjs/common/decorators/core/catch.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/controller.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/dependencies.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/exception-filters.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/inject.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/injectable.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/optional.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/set-metadata.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/use-guards.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/use-interceptors.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/use-pipes.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/apply-decorators.d.ts","./node_modules/@nestjs/common/decorators/core/version.decorator.d.ts","./node_modules/@nestjs/common/decorators/core/index.d.ts","./node_modules/@nestjs/common/decorators/modules/global.decorator.d.ts","./node_modules/@nestjs/common/decorators/modules/module.decorator.d.ts","./node_modules/@nestjs/common/decorators/modules/index.d.ts","./node_modules/@nestjs/common/decorators/http/request-mapping.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/route-params.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/http-code.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/create-route-param-metadata.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/render.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/header.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/redirect.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/sse.decorator.d.ts","./node_modules/@nestjs/common/decorators/http/index.d.ts","./node_modules/@nestjs/common/decorators/index.d.ts","./node_modules/@nestjs/common/exceptions/http.exception.d.ts","./node_modules/@nestjs/common/exceptions/bad-request.exception.d.ts","./node_modules/@nestjs/common/exceptions/unauthorized.exception.d.ts","./node_modules/@nestjs/common/exceptions/method-not-allowed.exception.d.ts","./node_modules/@nestjs/common/exceptions/not-found.exception.d.ts","./node_modules/@nestjs/common/exceptions/forbidden.exception.d.ts","./node_modules/@nestjs/common/exceptions/not-acceptable.exception.d.ts","./node_modules/@nestjs/common/exceptions/request-timeout.exception.d.ts","./node_modules/@nestjs/common/exceptions/conflict.exception.d.ts","./node_modules/@nestjs/common/exceptions/gone.exception.d.ts","./node_modules/@nestjs/common/exceptions/payload-too-large.exception.d.ts","./node_modules/@nestjs/common/exceptions/unsupported-media-type.exception.d.ts","./node_modules/@nestjs/common/exceptions/unprocessable-entity.exception.d.ts","./node_modules/@nestjs/common/exceptions/internal-server-error.exception.d.ts","./node_modules/@nestjs/common/exceptions/not-implemented.exception.d.ts","./node_modules/@nestjs/common/exceptions/http-version-not-supported.exception.d.ts","./node_modules/@nestjs/common/exceptions/bad-gateway.exception.d.ts","./node_modules/@nestjs/common/exceptions/service-unavailable.exception.d.ts","./node_modules/@nestjs/common/exceptions/gateway-timeout.exception.d.ts","./node_modules/@nestjs/common/exceptions/im-a-teapot.exception.d.ts","./node_modules/@nestjs/common/exceptions/precondition-failed.exception.d.ts","./node_modules/@nestjs/common/exceptions/misdirected.exception.d.ts","./node_modules/@nestjs/common/exceptions/index.d.ts","./node_modules/@nestjs/common/file-stream/interfaces/streamable-options.interface.d.ts","./node_modules/@nestjs/common/file-stream/interfaces/streamable-handler-response.interface.d.ts","./node_modules/@nestjs/common/file-stream/interfaces/index.d.ts","./node_modules/@nestjs/common/services/console-logger.service.d.ts","./node_modules/@nestjs/common/services/index.d.ts","./node_modules/@nestjs/common/file-stream/streamable-file.d.ts","./node_modules/@nestjs/common/file-stream/index.d.ts","./node_modules/@nestjs/common/module-utils/constants.d.ts","./node_modules/@nestjs/common/module-utils/interfaces/configurable-module-async-options.interface.d.ts","./node_modules/@nestjs/common/module-utils/interfaces/configurable-module-cls.interface.d.ts","./node_modules/@nestjs/common/module-utils/interfaces/configurable-module-host.interface.d.ts","./node_modules/@nestjs/common/module-utils/interfaces/index.d.ts","./node_modules/@nestjs/common/module-utils/configurable-module.builder.d.ts","./node_modules/@nestjs/common/module-utils/index.d.ts","./node_modules/@nestjs/common/pipes/default-value.pipe.d.ts","./node_modules/@nestjs/common/interfaces/external/class-transform-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/external/transformer-package.interface.d.ts","./node_modules/@nestjs/common/interfaces/external/validator-options.interface.d.ts","./node_modules/@nestjs/common/interfaces/external/validator-package.interface.d.ts","./node_modules/@nestjs/common/utils/http-error-by-code.util.d.ts","./node_modules/@nestjs/common/pipes/validation.pipe.d.ts","./node_modules/@nestjs/common/pipes/parse-array.pipe.d.ts","./node_modules/@nestjs/common/pipes/parse-bool.pipe.d.ts","./node_modules/@nestjs/common/pipes/parse-int.pipe.d.ts","./node_modules/@nestjs/common/pipes/parse-float.pipe.d.ts","./node_modules/@nestjs/common/pipes/parse-enum.pipe.d.ts","./node_modules/@nestjs/common/pipes/parse-uuid.pipe.d.ts","./node_modules/@nestjs/common/pipes/file/interfaces/file.interface.d.ts","./node_modules/@nestjs/common/pipes/file/interfaces/index.d.ts","./node_modules/@nestjs/common/pipes/file/file-validator.interface.d.ts","./node_modules/@nestjs/common/pipes/file/file-type.validator.d.ts","./node_modules/@nestjs/common/pipes/file/max-file-size.validator.d.ts","./node_modules/@nestjs/common/pipes/file/parse-file-options.interface.d.ts","./node_modules/@nestjs/common/pipes/file/parse-file.pipe.d.ts","./node_modules/@nestjs/common/pipes/file/parse-file-pipe.builder.d.ts","./node_modules/@nestjs/common/pipes/file/index.d.ts","./node_modules/@nestjs/common/pipes/index.d.ts","./node_modules/@nestjs/common/serializer/class-serializer.interfaces.d.ts","./node_modules/@nestjs/common/serializer/class-serializer.interceptor.d.ts","./node_modules/@nestjs/common/serializer/decorators/serialize-options.decorator.d.ts","./node_modules/@nestjs/common/serializer/decorators/index.d.ts","./node_modules/@nestjs/common/serializer/index.d.ts","./node_modules/@nestjs/common/utils/forward-ref.util.d.ts","./node_modules/@nestjs/common/utils/index.d.ts","./node_modules/@nestjs/common/index.d.ts","./node_modules/@prisma/client/runtime/library.d.ts","./node_modules/.prisma/client/index.d.ts","./node_modules/.prisma/client/default.d.ts","./node_modules/@prisma/client/default.d.ts","./node_modules/dayjs/locale/types.d.ts","./node_modules/dayjs/locale/index.d.ts","./node_modules/dayjs/index.d.ts","./src/odoo/entities/odoo.entity.ts","./node_modules/axios/index.d.ts","./node_modules/@nestjs/axios/dist/interfaces/http-module.interface.d.ts","./node_modules/@nestjs/axios/dist/interfaces/index.d.ts","./node_modules/@nestjs/axios/dist/http.module.d.ts","./node_modules/@nestjs/axios/dist/http.service.d.ts","./node_modules/@nestjs/axios/dist/index.d.ts","./node_modules/@nestjs/axios/index.d.ts","./src/odoo/odoo.service.ts","./src/prisma/prisma.service.ts","./src/custom-id/custom-id.service.ts","./node_modules/class-validator/types/validation/ValidationError.d.ts","./node_modules/class-validator/types/validation/ValidatorOptions.d.ts","./node_modules/class-validator/types/validation-schema/ValidationSchema.d.ts","./node_modules/class-validator/types/container.d.ts","./node_modules/class-validator/types/validation/ValidationArguments.d.ts","./node_modules/class-validator/types/decorator/ValidationOptions.d.ts","./node_modules/class-validator/types/decorator/common/Allow.d.ts","./node_modules/class-validator/types/decorator/common/IsDefined.d.ts","./node_modules/class-validator/types/decorator/common/IsOptional.d.ts","./node_modules/class-validator/types/decorator/common/Validate.d.ts","./node_modules/class-validator/types/validation/ValidatorConstraintInterface.d.ts","./node_modules/class-validator/types/decorator/common/ValidateBy.d.ts","./node_modules/class-validator/types/decorator/common/ValidateIf.d.ts","./node_modules/class-validator/types/decorator/common/ValidateNested.d.ts","./node_modules/class-validator/types/decorator/common/ValidatePromise.d.ts","./node_modules/class-validator/types/decorator/common/IsLatLong.d.ts","./node_modules/class-validator/types/decorator/common/IsLatitude.d.ts","./node_modules/class-validator/types/decorator/common/IsLongitude.d.ts","./node_modules/class-validator/types/decorator/common/Equals.d.ts","./node_modules/class-validator/types/decorator/common/NotEquals.d.ts","./node_modules/class-validator/types/decorator/common/IsEmpty.d.ts","./node_modules/class-validator/types/decorator/common/IsNotEmpty.d.ts","./node_modules/class-validator/types/decorator/common/IsIn.d.ts","./node_modules/class-validator/types/decorator/common/IsNotIn.d.ts","./node_modules/class-validator/types/decorator/number/IsDivisibleBy.d.ts","./node_modules/class-validator/types/decorator/number/IsPositive.d.ts","./node_modules/class-validator/types/decorator/number/IsNegative.d.ts","./node_modules/class-validator/types/decorator/number/Max.d.ts","./node_modules/class-validator/types/decorator/number/Min.d.ts","./node_modules/class-validator/types/decorator/date/MinDate.d.ts","./node_modules/class-validator/types/decorator/date/MaxDate.d.ts","./node_modules/class-validator/types/decorator/string/Contains.d.ts","./node_modules/class-validator/types/decorator/string/NotContains.d.ts","./node_modules/@types/validator/lib/isBoolean.d.ts","./node_modules/@types/validator/lib/isEmail.d.ts","./node_modules/@types/validator/lib/isFQDN.d.ts","./node_modules/@types/validator/lib/isIBAN.d.ts","./node_modules/@types/validator/lib/isISO31661Alpha2.d.ts","./node_modules/@types/validator/lib/isISO4217.d.ts","./node_modules/@types/validator/lib/isISO6391.d.ts","./node_modules/@types/validator/lib/isTaxID.d.ts","./node_modules/@types/validator/lib/isURL.d.ts","./node_modules/@types/validator/index.d.ts","./node_modules/class-validator/types/decorator/string/IsAlpha.d.ts","./node_modules/class-validator/types/decorator/string/IsAlphanumeric.d.ts","./node_modules/class-validator/types/decorator/string/IsDecimal.d.ts","./node_modules/class-validator/types/decorator/string/IsAscii.d.ts","./node_modules/class-validator/types/decorator/string/IsBase64.d.ts","./node_modules/class-validator/types/decorator/string/IsByteLength.d.ts","./node_modules/class-validator/types/decorator/string/IsCreditCard.d.ts","./node_modules/class-validator/types/decorator/string/IsCurrency.d.ts","./node_modules/class-validator/types/decorator/string/IsEmail.d.ts","./node_modules/class-validator/types/decorator/string/IsFQDN.d.ts","./node_modules/class-validator/types/decorator/string/IsFullWidth.d.ts","./node_modules/class-validator/types/decorator/string/IsHalfWidth.d.ts","./node_modules/class-validator/types/decorator/string/IsVariableWidth.d.ts","./node_modules/class-validator/types/decorator/string/IsHexColor.d.ts","./node_modules/class-validator/types/decorator/string/IsHexadecimal.d.ts","./node_modules/class-validator/types/decorator/string/IsMacAddress.d.ts","./node_modules/class-validator/types/decorator/string/IsIP.d.ts","./node_modules/class-validator/types/decorator/string/IsPort.d.ts","./node_modules/class-validator/types/decorator/string/IsISBN.d.ts","./node_modules/class-validator/types/decorator/string/IsISIN.d.ts","./node_modules/class-validator/types/decorator/string/IsISO8601.d.ts","./node_modules/class-validator/types/decorator/string/IsJSON.d.ts","./node_modules/class-validator/types/decorator/string/IsJWT.d.ts","./node_modules/class-validator/types/decorator/string/IsLowercase.d.ts","./node_modules/class-validator/types/decorator/string/IsMobilePhone.d.ts","./node_modules/class-validator/types/decorator/string/IsISO31661Alpha2.d.ts","./node_modules/class-validator/types/decorator/string/IsISO31661Alpha3.d.ts","./node_modules/class-validator/types/decorator/string/IsMongoId.d.ts","./node_modules/class-validator/types/decorator/string/IsMultibyte.d.ts","./node_modules/class-validator/types/decorator/string/IsSurrogatePair.d.ts","./node_modules/class-validator/types/decorator/string/IsUrl.d.ts","./node_modules/class-validator/types/decorator/string/IsUUID.d.ts","./node_modules/class-validator/types/decorator/string/IsFirebasePushId.d.ts","./node_modules/class-validator/types/decorator/string/IsUppercase.d.ts","./node_modules/class-validator/types/decorator/string/Length.d.ts","./node_modules/class-validator/types/decorator/string/MaxLength.d.ts","./node_modules/class-validator/types/decorator/string/MinLength.d.ts","./node_modules/class-validator/types/decorator/string/Matches.d.ts","./node_modules/libphonenumber-js/types.d.cts","./node_modules/libphonenumber-js/max/index.d.cts","./node_modules/class-validator/types/decorator/string/IsPhoneNumber.d.ts","./node_modules/class-validator/types/decorator/string/IsMilitaryTime.d.ts","./node_modules/class-validator/types/decorator/string/IsHash.d.ts","./node_modules/class-validator/types/decorator/string/IsISSN.d.ts","./node_modules/class-validator/types/decorator/string/IsDateString.d.ts","./node_modules/class-validator/types/decorator/string/IsBooleanString.d.ts","./node_modules/class-validator/types/decorator/string/IsNumberString.d.ts","./node_modules/class-validator/types/decorator/string/IsBase32.d.ts","./node_modules/class-validator/types/decorator/string/IsBIC.d.ts","./node_modules/class-validator/types/decorator/string/IsBtcAddress.d.ts","./node_modules/class-validator/types/decorator/string/IsDataURI.d.ts","./node_modules/class-validator/types/decorator/string/IsEAN.d.ts","./node_modules/class-validator/types/decorator/string/IsEthereumAddress.d.ts","./node_modules/class-validator/types/decorator/string/IsHSL.d.ts","./node_modules/class-validator/types/decorator/string/IsIBAN.d.ts","./node_modules/class-validator/types/decorator/string/IsIdentityCard.d.ts","./node_modules/class-validator/types/decorator/string/IsISRC.d.ts","./node_modules/class-validator/types/decorator/string/IsLocale.d.ts","./node_modules/class-validator/types/decorator/string/IsMagnetURI.d.ts","./node_modules/class-validator/types/decorator/string/IsMimeType.d.ts","./node_modules/class-validator/types/decorator/string/IsOctal.d.ts","./node_modules/class-validator/types/decorator/string/IsPassportNumber.d.ts","./node_modules/class-validator/types/decorator/string/IsPostalCode.d.ts","./node_modules/class-validator/types/decorator/string/IsRFC3339.d.ts","./node_modules/class-validator/types/decorator/string/IsRgbColor.d.ts","./node_modules/class-validator/types/decorator/string/IsSemVer.d.ts","./node_modules/class-validator/types/decorator/string/IsStrongPassword.d.ts","./node_modules/class-validator/types/decorator/string/IsTimeZone.d.ts","./node_modules/class-validator/types/decorator/string/IsBase58.d.ts","./node_modules/class-validator/types/decorator/string/is-tax-id.d.ts","./node_modules/class-validator/types/decorator/string/is-iso4217-currency-code.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsBoolean.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsDate.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsNumber.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsEnum.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsInt.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsString.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsArray.d.ts","./node_modules/class-validator/types/decorator/typechecker/IsObject.d.ts","./node_modules/class-validator/types/decorator/array/ArrayContains.d.ts","./node_modules/class-validator/types/decorator/array/ArrayNotContains.d.ts","./node_modules/class-validator/types/decorator/array/ArrayNotEmpty.d.ts","./node_modules/class-validator/types/decorator/array/ArrayMinSize.d.ts","./node_modules/class-validator/types/decorator/array/ArrayMaxSize.d.ts","./node_modules/class-validator/types/decorator/array/ArrayUnique.d.ts","./node_modules/class-validator/types/decorator/object/IsNotEmptyObject.d.ts","./node_modules/class-validator/types/decorator/object/IsInstance.d.ts","./node_modules/class-validator/types/decorator/decorators.d.ts","./node_modules/class-validator/types/validation/ValidationTypes.d.ts","./node_modules/class-validator/types/validation/Validator.d.ts","./node_modules/class-validator/types/register-decorator.d.ts","./node_modules/class-validator/types/metadata/ValidationMetadataArgs.d.ts","./node_modules/class-validator/types/metadata/ValidationMetadata.d.ts","./node_modules/class-validator/types/metadata/ConstraintMetadata.d.ts","./node_modules/class-validator/types/metadata/MetadataStorage.d.ts","./node_modules/class-validator/types/index.d.ts","./node_modules/class-transformer/types/interfaces/decorator-options/expose-options.interface.d.ts","./node_modules/class-transformer/types/interfaces/decorator-options/exclude-options.interface.d.ts","./node_modules/class-transformer/types/interfaces/decorator-options/transform-options.interface.d.ts","./node_modules/class-transformer/types/interfaces/decorator-options/type-discriminator-descriptor.interface.d.ts","./node_modules/class-transformer/types/interfaces/decorator-options/type-options.interface.d.ts","./node_modules/class-transformer/types/interfaces/metadata/exclude-metadata.interface.d.ts","./node_modules/class-transformer/types/interfaces/metadata/expose-metadata.interface.d.ts","./node_modules/class-transformer/types/enums/transformation-type.enum.d.ts","./node_modules/class-transformer/types/enums/index.d.ts","./node_modules/class-transformer/types/interfaces/target-map.interface.d.ts","./node_modules/class-transformer/types/interfaces/class-transformer-options.interface.d.ts","./node_modules/class-transformer/types/interfaces/metadata/transform-fn-params.interface.d.ts","./node_modules/class-transformer/types/interfaces/metadata/transform-metadata.interface.d.ts","./node_modules/class-transformer/types/interfaces/metadata/type-metadata.interface.d.ts","./node_modules/class-transformer/types/interfaces/class-constructor.type.d.ts","./node_modules/class-transformer/types/interfaces/type-help-options.interface.d.ts","./node_modules/class-transformer/types/interfaces/index.d.ts","./node_modules/class-transformer/types/ClassTransformer.d.ts","./node_modules/class-transformer/types/decorators/exclude.decorator.d.ts","./node_modules/class-transformer/types/decorators/expose.decorator.d.ts","./node_modules/class-transformer/types/decorators/transform-instance-to-instance.decorator.d.ts","./node_modules/class-transformer/types/decorators/transform-instance-to-plain.decorator.d.ts","./node_modules/class-transformer/types/decorators/transform-plain-to-instance.decorator.d.ts","./node_modules/class-transformer/types/decorators/transform.decorator.d.ts","./node_modules/class-transformer/types/decorators/type.decorator.d.ts","./node_modules/class-transformer/types/decorators/index.d.ts","./node_modules/class-transformer/types/index.d.ts","./src/sessions/dto/create-session.dto.ts","./node_modules/dayjs/plugin/utc.d.ts","./node_modules/dayjs/plugin/timezone.d.ts","./src/sessions/entities/session.entity.ts","./src/common/types.ts","./src/sessions/sessions.service.ts","./src/user/user.dto.ts","./src/user/user.service.ts","./src/subscriptions/subscriptions.service.ts","./src/invoices/invoices.service.ts","./node_modules/@types/node/compatibility/disposable.d.ts","./node_modules/@types/node/compatibility/indexable.d.ts","./node_modules/@types/node/compatibility/iterators.d.ts","./node_modules/@types/node/compatibility/index.d.ts","./node_modules/@types/node/globals.typedarray.d.ts","./node_modules/@types/node/buffer.buffer.d.ts","./node_modules/buffer/index.d.ts","./node_modules/undici-types/header.d.ts","./node_modules/undici-types/readable.d.ts","./node_modules/undici-types/file.d.ts","./node_modules/undici-types/fetch.d.ts","./node_modules/undici-types/formdata.d.ts","./node_modules/undici-types/connector.d.ts","./node_modules/undici-types/client.d.ts","./node_modules/undici-types/errors.d.ts","./node_modules/undici-types/dispatcher.d.ts","./node_modules/undici-types/global-dispatcher.d.ts","./node_modules/undici-types/global-origin.d.ts","./node_modules/undici-types/pool-stats.d.ts","./node_modules/undici-types/pool.d.ts","./node_modules/undici-types/handlers.d.ts","./node_modules/undici-types/balanced-pool.d.ts","./node_modules/undici-types/agent.d.ts","./node_modules/undici-types/mock-interceptor.d.ts","./node_modules/undici-types/mock-agent.d.ts","./node_modules/undici-types/mock-client.d.ts","./node_modules/undici-types/mock-pool.d.ts","./node_modules/undici-types/mock-errors.d.ts","./node_modules/undici-types/proxy-agent.d.ts","./node_modules/undici-types/env-http-proxy-agent.d.ts","./node_modules/undici-types/retry-handler.d.ts","./node_modules/undici-types/retry-agent.d.ts","./node_modules/undici-types/api.d.ts","./node_modules/undici-types/interceptors.d.ts","./node_modules/undici-types/util.d.ts","./node_modules/undici-types/cookies.d.ts","./node_modules/undici-types/patch.d.ts","./node_modules/undici-types/websocket.d.ts","./node_modules/undici-types/eventsource.d.ts","./node_modules/undici-types/filereader.d.ts","./node_modules/undici-types/diagnostics-channel.d.ts","./node_modules/undici-types/content-type.d.ts","./node_modules/undici-types/cache.d.ts","./node_modules/undici-types/index.d.ts","./node_modules/@types/node/globals.d.ts","./node_modules/@types/node/assert.d.ts","./node_modules/@types/node/assert/strict.d.ts","./node_modules/@types/node/async_hooks.d.ts","./node_modules/@types/node/buffer.d.ts","./node_modules/@types/node/child_process.d.ts","./node_modules/@types/node/cluster.d.ts","./node_modules/@types/node/console.d.ts","./node_modules/@types/node/constants.d.ts","./node_modules/@types/node/crypto.d.ts","./node_modules/@types/node/dgram.d.ts","./node_modules/@types/node/diagnostics_channel.d.ts","./node_modules/@types/node/dns.d.ts","./node_modules/@types/node/dns/promises.d.ts","./node_modules/@types/node/domain.d.ts","./node_modules/@types/node/dom-events.d.ts","./node_modules/@types/node/events.d.ts","./node_modules/@types/node/fs.d.ts","./node_modules/@types/node/fs/promises.d.ts","./node_modules/@types/node/http.d.ts","./node_modules/@types/node/http2.d.ts","./node_modules/@types/node/https.d.ts","./node_modules/@types/node/inspector.d.ts","./node_modules/@types/node/module.d.ts","./node_modules/@types/node/net.d.ts","./node_modules/@types/node/os.d.ts","./node_modules/@types/node/path.d.ts","./node_modules/@types/node/perf_hooks.d.ts","./node_modules/@types/node/process.d.ts","./node_modules/@types/node/punycode.d.ts","./node_modules/@types/node/querystring.d.ts","./node_modules/@types/node/readline.d.ts","./node_modules/@types/node/readline/promises.d.ts","./node_modules/@types/node/repl.d.ts","./node_modules/@types/node/sea.d.ts","./node_modules/@types/node/stream.d.ts","./node_modules/@types/node/stream/promises.d.ts","./node_modules/@types/node/stream/consumers.d.ts","./node_modules/@types/node/stream/web.d.ts","./node_modules/@types/node/string_decoder.d.ts","./node_modules/@types/node/test.d.ts","./node_modules/@types/node/timers.d.ts","./node_modules/@types/node/timers/promises.d.ts","./node_modules/@types/node/tls.d.ts","./node_modules/@types/node/trace_events.d.ts","./node_modules/@types/node/tty.d.ts","./node_modules/@types/node/url.d.ts","./node_modules/@types/node/util.d.ts","./node_modules/@types/node/v8.d.ts","./node_modules/@types/node/vm.d.ts","./node_modules/@types/node/wasi.d.ts","./node_modules/@types/node/worker_threads.d.ts","./node_modules/@types/node/zlib.d.ts","./node_modules/@types/node/index.d.ts","./node_modules/@types/mime/index.d.ts","./node_modules/@types/send/index.d.ts","./node_modules/@types/qs/index.d.ts","./node_modules/@types/range-parser/index.d.ts","./node_modules/@types/express-serve-static-core/index.d.ts","./node_modules/@types/http-errors/index.d.ts","./node_modules/@types/serve-static/index.d.ts","./node_modules/@types/connect/index.d.ts","./node_modules/@types/body-parser/index.d.ts","./node_modules/@types/express/index.d.ts","./src/common/decoratos/user.decorator.ts","./src/common/guards/auth-token.guard.ts","./src/invoices/invoices.controller.ts","./src/prisma/prisma.module.ts","./src/odoo/odoo.controller.ts","./src/odoo/odoo.module.ts","./src/subscriptions/dto/create-subscription.dto.ts","./node_modules/@nestjs/mapped-types/dist/mapped-type.interface.d.ts","./node_modules/@nestjs/mapped-types/dist/types/remove-fields-with-type.type.d.ts","./node_modules/@nestjs/mapped-types/dist/intersection-type.helper.d.ts","./node_modules/@nestjs/mapped-types/dist/omit-type.helper.d.ts","./node_modules/@nestjs/mapped-types/dist/partial-type.helper.d.ts","./node_modules/@nestjs/mapped-types/dist/pick-type.helper.d.ts","./node_modules/@nestjs/mapped-types/dist/type-helpers.utils.d.ts","./node_modules/@nestjs/mapped-types/dist/index.d.ts","./node_modules/@nestjs/mapped-types/index.d.ts","./src/subscriptions/dto/update-subscription.dto.ts","./src/subscriptions/subscriptions.controller.ts","./src/sessions/sessions.controller.ts","./src/custom-id/custom-id.module.ts","./src/sessions/sessions.module.ts","./src/user/user.controller.ts","./src/user/user.module.ts","./src/subscriptions/subscriptions.module.ts","./src/invoices/invoices.module.ts","./node_modules/@types/jsonwebtoken/index.d.ts","./node_modules/@nestjs/jwt/dist/interfaces/jwt-module-options.interface.d.ts","./node_modules/@nestjs/jwt/dist/interfaces/index.d.ts","./node_modules/@nestjs/jwt/dist/jwt.errors.d.ts","./node_modules/@nestjs/jwt/dist/jwt.module.d.ts","./node_modules/@nestjs/jwt/dist/jwt.service.d.ts","./node_modules/@nestjs/jwt/dist/index.d.ts","./node_modules/@nestjs/jwt/index.d.ts","./node_modules/nanoid/index.d.ts","./src/auth/auth.service.ts","./src/auth/auth.controller.ts","./node_modules/@nestjs/schedule/dist/enums/cron-expression.enum.d.ts","./node_modules/@nestjs/schedule/dist/enums/index.d.ts","./node_modules/@types/luxon/src/zone.d.ts","./node_modules/@types/luxon/src/settings.d.ts","./node_modules/@types/luxon/src/_util.d.ts","./node_modules/@types/luxon/src/misc.d.ts","./node_modules/@types/luxon/src/duration.d.ts","./node_modules/@types/luxon/src/interval.d.ts","./node_modules/@types/luxon/src/datetime.d.ts","./node_modules/@types/luxon/src/info.d.ts","./node_modules/@types/luxon/src/luxon.d.ts","./node_modules/@types/luxon/index.d.ts","./node_modules/cron/dist/errors.d.ts","./node_modules/cron/dist/constants.d.ts","./node_modules/cron/dist/job.d.ts","./node_modules/cron/dist/types/utils.d.ts","./node_modules/cron/dist/types/cron.types.d.ts","./node_modules/cron/dist/time.d.ts","./node_modules/cron/dist/index.d.ts","./node_modules/@nestjs/schedule/dist/decorators/cron.decorator.d.ts","./node_modules/@nestjs/schedule/dist/decorators/interval.decorator.d.ts","./node_modules/@nestjs/schedule/dist/decorators/timeout.decorator.d.ts","./node_modules/@nestjs/schedule/dist/decorators/index.d.ts","./node_modules/@nestjs/schedule/dist/interfaces/schedule-module-options.interface.d.ts","./node_modules/@nestjs/schedule/dist/schedule.module.d.ts","./node_modules/@nestjs/schedule/dist/scheduler.registry.d.ts","./node_modules/@nestjs/schedule/dist/index.d.ts","./node_modules/@nestjs/schedule/index.d.ts","./src/auth/token-cleanup.service.ts","./src/auth/auth.module.ts","./node_modules/@dqbd/tiktoken/tiktoken.d.ts","./src/ia/prompts/buildPromptInferAction.ts","./src/ia/ia.service.ts","./src/ia/dto/create-ia.dto.ts","./src/ia/dto/update-ia.dto.ts","./src/ia/ia.controller.ts","./src/ia/services/builderSubscriptionPrompt.ts","./src/ia/services/ia.subscription.service.ts","./src/ia/ia.module.ts","./src/whatsapp/queue.service.ts","./node_modules/@builderbot/bot/dist/context/globalstateClass.d.ts","./node_modules/@builderbot/bot/dist/context/stateClass.d.ts","./node_modules/@builderbot/bot/dist/context/idlestateClass.d.ts","./node_modules/@builderbot/bot/dist/context/index.d.ts","./node_modules/@types/trouter/index.d.ts","./node_modules/@types/polka/index.d.ts","./node_modules/@builderbot/bot/dist/provider/interface/server.d.ts","./node_modules/@builderbot/bot/dist/core/eventEmitterClass.d.ts","./node_modules/@builderbot/bot/dist/provider/interface/provider.d.ts","./node_modules/@builderbot/bot/dist/utils/blacklistClass.d.ts","./node_modules/@builderbot/bot/dist/utils/delay.d.ts","./node_modules/@builderbot/bot/dist/utils/flattener.d.ts","./node_modules/@builderbot/bot/dist/utils/hash.d.ts","./node_modules/@builderbot/bot/dist/utils/interactive.d.ts","./node_modules/@builderbot/bot/dist/utils/queueClass.d.ts","./node_modules/@builderbot/bot/dist/utils/download.d.ts","./node_modules/@builderbot/bot/dist/utils/convertAudio.d.ts","./node_modules/@builderbot/bot/dist/utils/cleanImage.d.ts","./node_modules/@builderbot/bot/dist/utils/event.d.ts","./node_modules/@builderbot/bot/dist/utils/index.d.ts","./node_modules/@builderbot/bot/dist/types.d.ts","./node_modules/@builderbot/bot/dist/db/index.d.ts","./node_modules/@builderbot/bot/dist/io/flowClass.d.ts","./node_modules/@builderbot/bot/dist/core/coreClass.d.ts","./node_modules/@builderbot/bot/dist/io/events/index.d.ts","./node_modules/@builderbot/bot/dist/io/methods/addAnswer.d.ts","./node_modules/@builderbot/bot/dist/io/methods/addKeyword.d.ts","./node_modules/@builderbot/bot/dist/provider/providerMock.d.ts","./node_modules/@builderbot/bot/dist/index.d.ts","./node_modules/@builderbot/provider-baileys/dist/utils.d.ts","./node_modules/node-cache/index.d.ts","./node_modules/protobufjs/index.d.ts","./node_modules/long/umd/types.d.ts","./node_modules/long/umd/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/WAProto/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Contact.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Defaults/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WABinary/constants.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WABinary/types.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WABinary/encode.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WABinary/decode.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WABinary/generic-utils.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WABinary/jid-utils.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WABinary/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/GroupMetadata.d.ts","./node_modules/pino-std-serializers/index.d.ts","./node_modules/sonic-boom/types/index.d.ts","./node_modules/pino/pino.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/logger.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Signal.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Socket.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Message.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Auth.d.ts","./node_modules/@hapi/boom/lib/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Call.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Label.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/LabelAssociation.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/State.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Events.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Chat.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/Product.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Socket/Client/types.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Socket/Client/websocket.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Socket/Client/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Socket/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/generics.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/decode-wa-message.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/messages-media.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/messages.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/validate-connection.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/crypto.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Types/USync.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/USyncUser.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/Protocols/USyncContactProtocol.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/Protocols/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/USyncQuery.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAUSync/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/signal.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/noise-handler.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/history.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/chat-utils.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/lt-hash.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/auth-utils.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/baileys-event-stream.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/use-multi-file-auth-state.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/link-preview.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/event-buffer.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/process-message.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/Utils/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAM/constants.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAM/BinaryInfo.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAM/encode.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/WAM/index.d.ts","./node_modules/@builderbot/provider-baileys/node_modules/baileys/lib/index.d.ts","./node_modules/@builderbot/provider-baileys/dist/baileyWrapper.d.ts","./node_modules/@builderbot/provider-baileys/dist/type.d.ts","./node_modules/@builderbot/provider-baileys/dist/bailey.d.ts","./node_modules/@builderbot/provider-baileys/dist/index.d.ts","./src/whatsapp/flows/admin/session/createSessionFlow.ts","./src/whatsapp/utils/generateTimer.ts","./src/ia/prompts/promptGetSession.ts","./src/whatsapp/flows/admin/session/listSessionFlow.ts","./src/whatsapp/utils/chunkArray.ts","./src/whatsapp/utils/exitFlow.ts","./src/whatsapp/flows/admin/user/listUserFlow.ts","./src/whatsapp/flows/admin/user/userFlow.ts","./src/whatsapp/flows/admin/menu/adminMenu.ts","./src/whatsapp/flows/admin/session/sessionFlow.ts","./node_modules/uuid/dist/cjs/types.d.ts","./node_modules/uuid/dist/cjs/max.d.ts","./node_modules/uuid/dist/cjs/nil.d.ts","./node_modules/uuid/dist/cjs/parse.d.ts","./node_modules/uuid/dist/cjs/stringify.d.ts","./node_modules/uuid/dist/cjs/v1.d.ts","./node_modules/uuid/dist/cjs/v1ToV6.d.ts","./node_modules/uuid/dist/cjs/v35.d.ts","./node_modules/uuid/dist/cjs/v3.d.ts","./node_modules/uuid/dist/cjs/v4.d.ts","./node_modules/uuid/dist/cjs/v5.d.ts","./node_modules/uuid/dist/cjs/v6.d.ts","./node_modules/uuid/dist/cjs/v6ToV1.d.ts","./node_modules/uuid/dist/cjs/v7.d.ts","./node_modules/uuid/dist/cjs/validate.d.ts","./node_modules/uuid/dist/cjs/version.d.ts","./node_modules/uuid/dist/cjs/index.d.ts","./src/whatsapp/flows/subscription/createSubscriptionFlow.ts","./src/whatsapp/utils/validateUserInput.ts","./src/whatsapp/flows/admin/user/updateUserFlow.ts","./src/whatsapp/utils/validations/validateCustomId.ts","./src/whatsapp/flows/admin/user/deleteUser.ts","./src/whatsapp/flows/admin/user/modifyUser.ts","./src/whatsapp/flows/admin/adminFlows.ts","./src/whatsapp/flows/user/menu/userMenu.ts","./src/whatsapp/utils/getInstructorName.ts","./src/whatsapp/utils/buildSchedule.ts","./src/whatsapp/utils/getCurrentAmount.ts","./src/whatsapp/utils/formatCurrency.ts","./src/whatsapp/flows/user/flows/viewNewKeysFlowFlow.ts","./src/whatsapp/flows/user/flows/viewPaymentStatusFlow.ts","./src/whatsapp/flows/user/flows/enrolledNewClassesFlow.ts","./src/whatsapp/flows/user/flows/viewEnrolledClassesFlow.ts","./src/whatsapp/flows/user/userFlows.ts","./src/whatsapp/utils/presence.ts","./src/whatsapp/flows/professor/menu/professorMenu.ts","./src/whatsapp/flows/professor/professorFlows.ts","./src/whatsapp/whatsapp.service.ts","./src/whatsapp/whatsapp.controller.ts","./src/whatsapp/whatsapp.module.ts","./src/attendance/dto/create-attendance.dto.ts","./src/attendance/dto/update-attendance.dto.ts","./src/attendance/attendance.service.ts","./src/attendance/attendance.controller.ts","./src/attendance/attendance.module.ts","./src/rfid/dto/create-rfid.dto.ts","./src/rfid/dto/update-rfid.dto.ts","./src/rfid/rfid.service.ts","./src/rfid/rfid.controller.ts","./src/rfid/rfid.module.ts","./node_modules/@nestjs/throttler/dist/throttler-storage-record.interface.d.ts","./node_modules/@nestjs/throttler/dist/throttler-storage.interface.d.ts","./node_modules/@nestjs/throttler/dist/throttler.guard.interface.d.ts","./node_modules/@nestjs/throttler/dist/throttler-module-options.interface.d.ts","./node_modules/@nestjs/throttler/dist/throttler.decorator.d.ts","./node_modules/@nestjs/throttler/dist/throttler.exception.d.ts","./node_modules/@nestjs/core/adapters/http-adapter.d.ts","./node_modules/@nestjs/core/adapters/index.d.ts","./node_modules/@nestjs/common/constants.d.ts","./node_modules/@nestjs/core/inspector/interfaces/edge.interface.d.ts","./node_modules/@nestjs/core/inspector/interfaces/entrypoint.interface.d.ts","./node_modules/@nestjs/core/inspector/interfaces/extras.interface.d.ts","./node_modules/@nestjs/core/inspector/interfaces/node.interface.d.ts","./node_modules/@nestjs/core/injector/settlement-signal.d.ts","./node_modules/@nestjs/core/injector/injector.d.ts","./node_modules/@nestjs/core/inspector/interfaces/serialized-graph-metadata.interface.d.ts","./node_modules/@nestjs/core/inspector/interfaces/serialized-graph-json.interface.d.ts","./node_modules/@nestjs/core/inspector/serialized-graph.d.ts","./node_modules/@nestjs/core/injector/module-token-factory.d.ts","./node_modules/@nestjs/core/injector/compiler.d.ts","./node_modules/@nestjs/core/injector/modules-container.d.ts","./node_modules/@nestjs/core/injector/container.d.ts","./node_modules/@nestjs/core/injector/instance-links-host.d.ts","./node_modules/@nestjs/core/injector/abstract-instance-resolver.d.ts","./node_modules/@nestjs/core/injector/module-ref.d.ts","./node_modules/@nestjs/core/injector/module.d.ts","./node_modules/@nestjs/core/injector/instance-wrapper.d.ts","./node_modules/@nestjs/core/router/interfaces/exclude-route-metadata.interface.d.ts","./node_modules/@nestjs/core/application-config.d.ts","./node_modules/@nestjs/core/constants.d.ts","./node_modules/@nestjs/core/discovery/discovery-module.d.ts","./node_modules/@nestjs/core/discovery/discovery-service.d.ts","./node_modules/@nestjs/core/discovery/index.d.ts","./node_modules/@nestjs/core/helpers/http-adapter-host.d.ts","./node_modules/@nestjs/core/exceptions/base-exception-filter.d.ts","./node_modules/@nestjs/core/exceptions/index.d.ts","./node_modules/@nestjs/core/helpers/context-id-factory.d.ts","./node_modules/@nestjs/common/interfaces/exceptions/exception-filter-metadata.interface.d.ts","./node_modules/@nestjs/core/exceptions/exceptions-handler.d.ts","./node_modules/@nestjs/core/router/router-proxy.d.ts","./node_modules/@nestjs/core/helpers/context-creator.d.ts","./node_modules/@nestjs/core/exceptions/base-exception-filter-context.d.ts","./node_modules/@nestjs/common/interfaces/exceptions/rpc-exception-filter-metadata.interface.d.ts","./node_modules/@nestjs/common/interfaces/exceptions/index.d.ts","./node_modules/@nestjs/core/exceptions/external-exception-filter.d.ts","./node_modules/@nestjs/core/exceptions/external-exceptions-handler.d.ts","./node_modules/@nestjs/core/exceptions/external-exception-filter-context.d.ts","./node_modules/@nestjs/core/guards/constants.d.ts","./node_modules/@nestjs/core/helpers/execution-context-host.d.ts","./node_modules/@nestjs/core/guards/guards-consumer.d.ts","./node_modules/@nestjs/core/guards/guards-context-creator.d.ts","./node_modules/@nestjs/core/guards/index.d.ts","./node_modules/@nestjs/core/interceptors/interceptors-consumer.d.ts","./node_modules/@nestjs/core/interceptors/interceptors-context-creator.d.ts","./node_modules/@nestjs/core/interceptors/index.d.ts","./node_modules/@nestjs/common/enums/route-paramtypes.enum.d.ts","./node_modules/@nestjs/core/pipes/params-token-factory.d.ts","./node_modules/@nestjs/core/pipes/pipes-consumer.d.ts","./node_modules/@nestjs/core/pipes/pipes-context-creator.d.ts","./node_modules/@nestjs/core/pipes/index.d.ts","./node_modules/@nestjs/core/helpers/context-utils.d.ts","./node_modules/@nestjs/core/injector/inquirer/inquirer-constants.d.ts","./node_modules/@nestjs/core/injector/inquirer/index.d.ts","./node_modules/@nestjs/core/interfaces/module-definition.interface.d.ts","./node_modules/@nestjs/core/interfaces/module-override.interface.d.ts","./node_modules/@nestjs/core/inspector/interfaces/enhancer-metadata-cache-entry.interface.d.ts","./node_modules/@nestjs/core/inspector/graph-inspector.d.ts","./node_modules/@nestjs/core/metadata-scanner.d.ts","./node_modules/@nestjs/core/scanner.d.ts","./node_modules/@nestjs/core/injector/instance-loader.d.ts","./node_modules/@nestjs/core/injector/lazy-module-loader/lazy-module-loader-options.interface.d.ts","./node_modules/@nestjs/core/injector/lazy-module-loader/lazy-module-loader.d.ts","./node_modules/@nestjs/core/injector/index.d.ts","./node_modules/@nestjs/core/helpers/interfaces/external-handler-metadata.interface.d.ts","./node_modules/@nestjs/core/helpers/interfaces/params-metadata.interface.d.ts","./node_modules/@nestjs/core/helpers/external-context-creator.d.ts","./node_modules/@nestjs/core/helpers/index.d.ts","./node_modules/@nestjs/core/inspector/initialize-on-preview.allowlist.d.ts","./node_modules/@nestjs/core/inspector/partial-graph.host.d.ts","./node_modules/@nestjs/core/inspector/index.d.ts","./node_modules/@nestjs/core/middleware/route-info-path-extractor.d.ts","./node_modules/@nestjs/core/middleware/routes-mapper.d.ts","./node_modules/@nestjs/core/middleware/builder.d.ts","./node_modules/@nestjs/core/middleware/index.d.ts","./node_modules/@nestjs/core/nest-application-context.d.ts","./node_modules/@nestjs/core/nest-application.d.ts","./node_modules/@nestjs/common/interfaces/microservices/nest-microservice-options.interface.d.ts","./node_modules/@nestjs/core/nest-factory.d.ts","./node_modules/@nestjs/core/repl/repl.d.ts","./node_modules/@nestjs/core/repl/index.d.ts","./node_modules/@nestjs/core/router/interfaces/routes.interface.d.ts","./node_modules/@nestjs/core/router/interfaces/index.d.ts","./node_modules/@nestjs/core/router/request/request-constants.d.ts","./node_modules/@nestjs/core/router/request/index.d.ts","./node_modules/@nestjs/core/router/router-module.d.ts","./node_modules/@nestjs/core/router/index.d.ts","./node_modules/@nestjs/core/services/reflector.service.d.ts","./node_modules/@nestjs/core/services/index.d.ts","./node_modules/@nestjs/core/index.d.ts","./node_modules/@nestjs/throttler/dist/throttler.guard.d.ts","./node_modules/@nestjs/throttler/dist/throttler.module.d.ts","./node_modules/@nestjs/throttler/dist/throttler.providers.d.ts","./node_modules/@nestjs/throttler/dist/throttler-storage-options.interface.d.ts","./node_modules/@nestjs/throttler/dist/throttler.service.d.ts","./node_modules/@nestjs/throttler/dist/utilities.d.ts","./node_modules/@nestjs/throttler/dist/index.d.ts","./src/dashboard/dto/dashboard.dto.ts","./src/dashboard/dashboard.service.ts","./src/dashboard/dashboard.controller.ts","./src/dashboard/dashboard.module.ts","./node_modules/@nestjs/platform-express/interfaces/nest-express-body-parser-options.interface.d.ts","./node_modules/@nestjs/platform-express/interfaces/nest-express-body-parser.interface.d.ts","./node_modules/@nestjs/platform-express/interfaces/serve-static-options.interface.d.ts","./node_modules/@nestjs/platform-express/adapters/express-adapter.d.ts","./node_modules/@nestjs/platform-express/adapters/index.d.ts","./node_modules/@nestjs/platform-express/interfaces/nest-express-application.interface.d.ts","./node_modules/@nestjs/platform-express/interfaces/index.d.ts","./node_modules/@nestjs/platform-express/multer/interfaces/multer-options.interface.d.ts","./node_modules/@nestjs/platform-express/multer/interceptors/any-files.interceptor.d.ts","./node_modules/@nestjs/platform-express/multer/interceptors/file-fields.interceptor.d.ts","./node_modules/@nestjs/platform-express/multer/interceptors/file.interceptor.d.ts","./node_modules/@nestjs/platform-express/multer/interceptors/files.interceptor.d.ts","./node_modules/@nestjs/platform-express/multer/interceptors/no-files.interceptor.d.ts","./node_modules/@nestjs/platform-express/multer/interceptors/index.d.ts","./node_modules/@nestjs/platform-express/multer/interfaces/files-upload-module.interface.d.ts","./node_modules/@nestjs/platform-express/multer/interfaces/index.d.ts","./node_modules/@nestjs/platform-express/multer/multer.module.d.ts","./node_modules/@nestjs/platform-express/multer/index.d.ts","./node_modules/@nestjs/platform-express/index.d.ts","./node_modules/@types/multer/index.d.ts","./src/backup/backup.service.ts","./src/backup/backup.controller.ts","./src/backup/backup.module.ts","./src/app.module.ts","./src/main.ts","./src/attendance/entities/attendance.entity.ts","./src/custom-id/dto/create-custom-id.dto.ts","./src/custom-id/dto/update-custom-id.dto.ts","./src/custom-id/entities/custom-id.entity.ts","./src/dashboard/dto/create-dashboard.dto.ts","./src/dashboard/dto/update-dashboard.dto.ts","./src/dashboard/entities/dashboard.entity.ts","./src/ia/entities/ia.entity.ts","./src/ia/prompts/buildPromptGetUser.ts","./src/rfid/entities/rfid.entity.ts","./src/subscriptions/entities/subscription.entity.ts","./src/whatsapp/flows/professor/info/viewInfoFlow.ts","./src/whatsapp/flows/professor/session/updateSessionFlowProfessor.ts","./src/whatsapp/utils/getCurrentDayOfWeek.ts","./src/whatsapp/utils/getCurrentTime.ts","./node_modules/chrono-node/dist/esm/types.d.ts","./node_modules/chrono-node/dist/esm/calculation/duration.d.ts","./node_modules/chrono-node/dist/esm/results.d.ts","./node_modules/chrono-node/dist/esm/debugging.d.ts","./node_modules/chrono-node/dist/esm/locales/en/configuration.d.ts","./node_modules/chrono-node/dist/esm/chrono.d.ts","./node_modules/chrono-node/dist/esm/locales/en/index.d.ts","./node_modules/chrono-node/dist/esm/locales/de/index.d.ts","./node_modules/chrono-node/dist/esm/locales/fr/index.d.ts","./node_modules/chrono-node/dist/esm/locales/ja/index.d.ts","./node_modules/chrono-node/dist/esm/locales/pt/index.d.ts","./node_modules/chrono-node/dist/esm/locales/nl/index.d.ts","./node_modules/chrono-node/dist/esm/locales/zh/hant/index.d.ts","./node_modules/chrono-node/dist/esm/locales/zh/hans/index.d.ts","./node_modules/chrono-node/dist/esm/locales/zh/index.d.ts","./node_modules/chrono-node/dist/esm/locales/ru/index.d.ts","./node_modules/chrono-node/dist/esm/locales/es/index.d.ts","./node_modules/chrono-node/dist/esm/locales/uk/index.d.ts","./node_modules/chrono-node/dist/esm/index.d.ts","./src/whatsapp/utils/parseTemporalReference.ts","./node_modules/@types/estree/index.d.ts","./node_modules/@types/json-schema/index.d.ts","./node_modules/@types/eslint/use-at-your-own-risk.d.ts","./node_modules/@types/eslint/index.d.ts","./node_modules/@types/eslint-scope/index.d.ts","./node_modules/@types/long/index.d.ts","./node_modules/form-data/index.d.ts","./node_modules/@types/node-fetch/externals.d.ts","./node_modules/@types/node-fetch/index.d.ts"],"fileIdsList":[[412,610,653],[411,610,653],[610,653],[610,653,789,790,791],[610,653,792,796,797,808,809,810,811],[610,653,809],[610,653,796,797,808,809,810,811,812,813,814,815,816],[610,653,794,795,796,809],[610,653,794,809],[610,653,797,809],[610,653,792,797,808],[610,653,798,799,800,801,802,803,804,805,806,807],[610,653,666,794,809,817,819,886,887,888],[610,653,886],[610,653,818,889],[610,653,820,822],[610,653,823,850],[610,653,851,852],[610,653,665,695,850],[610,653,851],[610,653,822,837,842,844,850,853,886],[610,653,823,824,840],[610,653,823,840,841,844,845,847],[610,653,823,824,833,840,841,842,843,844,845,846,848],[610,653,824],[419,610,653,684,695,823,825,832,833,837,839],[610,653,840],[610,653,823],[419,610,653,670,695,823,833,837,838,840,841],[610,653,832,869],[610,653,824,833,838,839,840,841,843,846,847,848,849],[610,653,837,850],[610,653,850],[419,610,653,823,832,837,850],[610,653,823,832,837,850],[419,610,653,823,832,850],[419,610,653,823,850],[610,653,855,856,857,858,859,860,870,871,872,873,874,875,876,877,878,879,880],[419,610,653,837,850],[610,653,836],[419,610,653,666,684,695,823,832,837,842,850],[610,653,684,823,837,850,857],[419,610,653,823,837,850],[610,653,832,841,850,869],[610,653,823,832,850],[610,653,827],[610,653,823,827],[610,653,827,828,829,830,831],[610,653,826],[610,653,882],[610,653,883],[610,653,882,883,884],[610,653,832,861,863],[610,653,832,861],[610,653,862,864,865,866],[610,653,863,867,868],[610,653,823,825,832,850,854,869,881,885],[410,421,610,653],[259,419,610,653],[421,422,423,610,653],[410,419,610,653],[420,610,653],[424,610,653],[315,610,653],[410,610,653],[65,316,317,318,319,320,321,322,323,324,325,326,327,328,610,653],[268,302,610,653],[275,610,653],[265,315,410,610,653],[333,334,335,336,337,338,339,340,610,653],[270,610,653],[315,410,610,653],[329,332,341,610,653],[330,331,610,653],[306,610,653],[270,271,272,273,610,653],[343,610,653],[288,610,653],[343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364,610,653],[371,610,653],[366,367,610,653],[368,370,610,653,684],[64,274,315,342,365,370,372,379,402,407,409,610,653],[70,268,610,653],[69,610,653],[70,260,261,610,653,988,993],[260,268,610,653],[69,259,610,653],[268,381,610,653],[262,383,610,653],[259,263,610,653],[69,315,610,653],[267,268,610,653],[280,610,653],[282,283,284,285,286,610,653],[274,610,653],[274,275,290,294,610,653],[288,289,295,296,297,610,653],[66,67,68,69,70,260,261,262,263,264,265,266,267,268,269,275,280,281,287,294,298,299,300,302,310,311,312,313,314,610,653],[293,610,653],[276,277,278,279,610,653],[268,276,277,610,653],[268,274,275,610,653],[268,278,610,653],[268,306,610,653],[301,303,304,305,306,307,308,309,610,653],[66,268,610,653],[302,610,653],[66,268,301,305,307,610,653],[277,610,653],[303,610,653],[268,302,303,304,610,653],[292,610,653],[268,272,292,310,610,653],[290,291,293,610,653],[264,266,275,281,290,295,311,312,315,610,653],[70,264,266,269,311,312,610,653],[273,610,653],[259,610,653],[292,315,373,377,610,653],[377,378,610,653],[315,373,610,653],[315,373,374,610,653],[374,375,610,653],[374,375,376,610,653],[269,610,653],[394,395,610,653],[394,610,653],[395,396,397,398,399,400,610,653],[393,610,653],[385,395,610,653],[395,396,397,398,399,610,653],[269,394,395,398,610,653],[380,386,387,388,389,390,391,392,401,610,653],[269,315,386,610,653],[269,385,610,653],[269,385,410,610,653],[262,268,269,381,382,383,384,385,610,653],[259,315,381,382,403,610,653],[315,381,610,653],[405,610,653],[342,403,610,653],[403,404,406,610,653],[292,369,610,653],[301,610,653],[274,315,610,653],[408,610,653],[290,294,315,410,610,653],[610,653,957],[315,410,610,653,977,978],[610,653,959],[410,610,653,971,976,977],[610,653,981,982],[70,315,610,653,972,977,991],[410,610,653,958,984],[69,410,610,653,985,988],[315,610,653,972,977,979,990,992,996],[69,610,653,994,995],[610,653,985],[259,315,410,610,653,999],[315,410,610,653,972,977,979,991],[610,653,998,1000,1001],[315,610,653,977],[610,653,977],[315,410,610,653,999],[69,315,410,610,653],[315,410,610,653,971,972,977,997,999,1002,1005,1010,1011,1024,1025],[259,610,653,957],[610,653,984,987,1026],[610,653,1011,1023],[64,610,653,958,979,980,983,986,1018,1023,1027,1030,1034,1035,1036,1038,1040,1046,1048],[315,410,610,653,965,973,976,977],[315,610,653,969],[315,410,610,653,959,968,969,970,971,976,977,979,1049],[610,653,971,972,975,977,1013,1022],[315,410,610,653,964,976,977],[610,653,1012],[410,610,653,972,977],[410,610,653,965,972,976,1017],[315,410,610,653,959,964,976],[410,610,653,970,971,975,1015,1019,1020,1021],[410,610,653,965,972,973,974,976,977],[268,410,610,653],[315,610,653,959,972,975,977],[610,653,976],[610,653,961,962,963,972,976,977,1016],[610,653,968,1017,1028,1029],[410,610,653,959,977],[410,610,653,959],[610,653,960,961,962,963,966,968],[610,653,965],[610,653,967,968],[410,610,653,960,961,962,963,966,967],[610,653,1003,1004],[315,610,653,972,977,979,991],[610,653,1014],[299,610,653],[280,315,610,653,1031,1032],[610,653,1033],[315,610,653,979],[315,610,653,972,979],[293,315,410,610,653,965,972,973,974,976,977],[290,292,315,410,610,653,958,972,979,1017,1035],[293,294,410,610,653,957,1037],[610,653,1007,1008,1009],[410,610,653,1006],[610,653,1039],[410,610,653,682],[610,653,1042,1044,1045],[610,653,1041],[610,653,1043],[410,610,653,971,976,1042],[610,653,989],[315,410,610,653,959,972,976,977,979,1014,1015,1017,1018],[610,653,1047],[610,653,738,740,741,742,743],[610,653,739],[410,610,653,738],[410,610,653,739],[610,653,738,740],[610,653,744],[610,653,720,722,723,724,725,726],[410,610,653,720,721],[610,653,727],[290,294,315,410,610,653,668,670,957,1061,1062,1063],[610,653,1064],[610,653,1065,1067,1078],[610,653,1061,1062,1066],[410,610,653,668,670,712,1061,1062,1063],[610,653,668],[610,653,1074,1076,1077],[410,610,653,1068],[610,653,1069,1070,1071,1072,1073],[315,610,653,1068],[610,653,1075],[410,610,653,1075],[610,653,767],[610,653,768,769,770],[610,653,749],[610,653,750,771,773,774],[410,610,653,772],[610,653,775],[610,653,952,953,954,955,956,1050,1051,1052,1054,1055],[315,610,653,952,953],[610,653,951],[610,653,954],[410,610,653,952,953,954,1049],[410,610,653,951,954],[410,610,653,954],[410,610,653,952,954],[410,610,653,951,952,1053],[413,610,653],[610,653,668,702,710],[610,653,668,702],[610,653,1121,1124],[610,653,1121,1122,1123],[610,653,1124],[610,653,665,668,702,704,705,706],[610,653,707,709,711],[610,653,658,702],[610,653,759],[610,653,752],[610,653,751,753,755,756,760],[610,653,753,754,757],[610,653,751,754,757],[610,653,753,755,757],[610,653,751,752,754,755,756,757,758],[610,653,751,757],[610,653,753],[610,653,684,712],[610,653,668,695,702,1127,1128],[610,650,653],[610,652,653],[653],[610,653,658,687],[610,653,654,659,665,666,673,684,695],[610,653,654,655,665,673],[605,606,607,610,653],[610,653,656,696],[610,653,657,658,666,674],[610,653,658,684,692],[610,653,659,661,665,673],[610,652,653,660],[610,653,661,662],[610,653,663,665],[610,652,653,665],[610,653,665,666,667,684,695],[610,653,665,666,667,680,684,687],[610,648,653],[610,653,661,665,668,673,684,695],[610,653,665,666,668,669,673,684,692,695],[610,653,668,670,684,692,695],[608,609,610,649,650,651,652,653,654,655,656,657,658,659,660,661,662,663,664,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701],[610,653,665,671],[610,653,672,695,700],[610,653,661,665,673,684],[610,653,674],[610,653,675],[610,652,653,676],[610,650,651,652,653,654,655,656,657,658,659,660,661,662,663,665,666,667,668,669,670,671,672,673,674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,692,693,694,695,696,697,698,699,700,701],[610,653,678],[610,653,679],[610,653,665,680,681],[610,653,680,682,696,698],[610,653,665,684,685,687],[610,653,686,687],[610,653,684,685],[610,653,687],[610,653,688],[610,650,653,684,689],[610,653,665,690,691],[610,653,690,691],[610,653,658,673,684,692],[610,653,693],[610,653,673,694],[610,653,668,679,695],[610,653,658,696],[610,653,684,697],[610,653,672,698],[610,653,699],[610,653,665,667,676,684,687,695,698,700],[610,653,684,701],[610,653,668,695,702,707,712,793],[610,653,666,684,702,703],[610,653,668,702,704,708],[462,463,464,465,466,467,468,469,470,610,653],[610,653,1101],[610,653,1101,1103,1104,1105],[610,653,1101,1103,1106,1107,1108,1109,1110,1111,1112,1115,1116,1117,1118],[610,653,1101,1103,1106],[610,653,1106],[610,653,1101,1103,1105,1106],[610,653,1101,1103,1106,1113,1114],[417,610,653,1101,1102],[584,610,653],[586,587,588,589,590,591,592,610,653],[575,610,653],[576,584,585,593,610,653],[577,610,653],[571,610,653],[568,569,570,571,572,573,574,577,578,579,580,581,582,583,610,653],[576,578,610,653],[579,584,610,653],[433,610,653],[434,610,653],[433,434,439,610,653],[435,436,437,438,440,441,442,443,444,445,446,447,448,449,450,451,452,453,454,455,456,457,458,459,460,461,472,473,474,475,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529,530,531,532,533,534,535,536,537,538,539,540,541,542,543,544,545,546,547,548,549,550,551,552,553,554,555,556,557,558,610,653],[434,471,610,653],[434,511,610,653],[429,430,431,432,433,434,439,559,560,561,562,566,610,653],[439,610,653],[431,564,565,610,653],[433,563,610,653],[434,439,610,653],[429,430,610,653],[610,653,760,763,765,766],[610,653,760,765,766],[610,653,760,761,765],[610,653,654,760,762,763,764],[416,610,653],[415,610,653],[417,596,610,653],[417,597,610,653],[610,653,668,684,702],[510,610,653],[610,653,821],[610,653,665,702],[610,653,665,700,834,835],[71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,87,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,127,128,129,130,131,132,133,134,135,136,137,138,140,141,142,143,144,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,190,191,192,194,203,205,206,207,208,209,210,212,213,215,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,610,653],[116,610,653],[74,75,610,653],[71,72,73,75,610,653],[72,75,610,653],[75,116,610,653],[71,75,193,610,653],[73,74,75,610,653],[71,75,610,653],[75,610,653],[74,610,653],[71,74,116,610,653],[72,74,75,232,610,653],[74,75,232,610,653],[74,240,610,653],[72,74,75,610,653],[84,610,653],[107,610,653],[128,610,653],[74,75,116,610,653],[75,123,610,653],[74,75,116,134,610,653],[74,75,134,610,653],[75,175,610,653],[71,75,194,610,653],[200,202,610,653],[71,75,193,200,201,610,653],[193,194,202,610,653],[200,610,653],[71,75,200,201,202,610,653],[216,610,653],[211,610,653],[214,610,653],[72,74,194,195,196,197,610,653],[116,194,195,196,197,610,653],[194,196,610,653],[74,195,196,198,199,203,610,653],[71,74,610,653],[75,218,610,653],[76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,117,118,119,120,121,122,124,125,126,127,128,129,130,131,132,133,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,610,653],[204,610,653],[610,620,624,653,695],[610,620,653,684,695],[610,615,653],[610,617,620,653,692,695],[610,653,673,692],[610,653,702],[610,615,653,702],[610,617,620,653,673,695],[610,612,613,616,619,653,665,684,695],[610,620,627,653],[610,612,618,653],[610,620,641,642,653],[610,616,620,653,687,695,702],[610,641,653,702],[610,614,615,653,702],[610,620,653],[610,614,615,616,617,618,619,620,621,622,624,625,626,627,628,629,630,631,632,633,634,635,636,637,638,639,640,642,643,644,645,646,647,653],[610,620,635,653],[610,620,627,628,653],[610,618,620,628,629,653],[610,619,653],[610,612,615,620,653],[610,620,624,628,629,653],[610,624,653],[610,618,620,623,653,695],[610,612,617,620,627,653],[610,653,684],[610,615,620,641,653,700,702],[610,653,901,902,903,904,905,906,907,909,910,911,912,913,914,915,916],[610,653,901],[610,653,901,908],[410,610,653,716,718,732,733,735,736,737,778,787,940,945,950,1049,1056,1060,1083],[410,610,653,941,942,943],[410,610,653,716,737,943,944],[410,414,417,427,610,653,941,942],[610,653,728,941],[410,610,653,747],[410,610,653,716,745,747,748,776,777],[410,414,427,610,653,746],[410,427,610,653,776],[410,414,599,610,653,666,675,712,713,714,1079,1080,1081],[410,610,653,716,1081,1082],[410,610,653,654,666,675,696],[410,427,610,653],[414,610,653],[410,428,610,653,716],[410,414,427,610,653],[610,653,728,1087],[410,599,610,653,713,714,1057,1058],[410,610,653,716,1058,1059],[410,414,417,427,599,610,653,1057],[610,653,728,1090],[610,653,728,782],[410,610,653,781,782,783],[410,425,610,653,716,781,784,786],[259,410,414,417,425,427,600,601,610,653,779,780],[259,410,414,425,427,610,653,666,781,785],[410,414,599,604,610,653,712,713,714],[410,604,610,653,715,716,718,736],[410,414,417,418,426,427,603,610,653],[64,410,610,653,1049,1084],[410,418,426,610,653,712],[410,425,426,610,653,717,737],[259,410,418,419,425,604,610,653,658],[410,414,610,653],[610,653,728,946],[410,610,653,946,947,948],[410,610,653,735,737,778,940,945,948,949],[410,414,417,602,604,610,653,747,938,943,946,947],[414,567,594,610,653],[410,414,595,598,599,600,610,653,713,714],[410,600,610,653,716,731,732],[410,414,417,427,428,595,596,597,598,599,604,610,653],[610,653,719,728],[410,603,610,653,719,729],[410,603,610,653,716,730,733,735,737],[410,427,600,602,604,610,653],[410,414,601,602,610,653],[414,567,610,653],[410,428,602,610,653,716,732,734],[259,410,414,427,428,601,610,653],[600,602,610,653,747,781,786,891,894,897,898,899,900,918,920,922,923],[610,653,747,781,809,817,890,896],[416,417,600,610,653,781,817,890],[416,417,600,610,653,781,817,890,892,893],[600,610,653,809,817,890,896],[602,610,653,781,817,890,896,921],[416,417,602,610,653,781,817,890,892,895,896],[610,653,809,817,890,896],[417,601,602,610,653,781,817,890,896,919],[602,610,653,747,817,890,896],[602,610,653,747,936],[416,417,610,653,666,675,786,817,890,917],[600,603,610,653,817,890,896],[600,602,610,653,817,890,896,926,927,928,929],[600,602,610,653,809,817,890,896,926,927,928,929],[414,600,602,604,610,653,817,890,896],[602,604,610,653,747,809,817,890,896],[600,602,603,604,610,653,747,925,930,931,932,933],[610,653,1119],[259,410,599,610,653,713,714,938],[410,610,653,718,733,735,736,737,778,787,788,938,939],[410,414,426,600,602,603,604,610,653,667,675,747,781,786,788,809,817,890,924,934,935,937]],"fileInfos":[{"version":"69684132aeb9b5642cbcd9e22dff7818ff0ee1aa831728af0ecf97d3364d5546","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"092c2bfe125ce69dbb1223c85d68d4d2397d7d8411867b5cc03cec902c233763","affectsGlobalScope":true,"impliedFormat":1},{"version":"07f073f19d67f74d732b1adea08e1dc66b1b58d77cb5b43931dee3d798a2fd53","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7a3c8b952931daebdfc7a2897c53c0a1c73624593fa070e46bd537e64dcd20a","affectsGlobalScope":true,"impliedFormat":1},{"version":"80e18897e5884b6723488d4f5652167e7bb5024f946743134ecc4aa4ee731f89","affectsGlobalScope":true,"impliedFormat":1},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"936e80ad36a2ee83fc3caf008e7c4c5afe45b3cf3d5c24408f039c1d47bdc1df","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"fef8cfad2e2dc5f5b3d97a6f4f2e92848eb1b88e897bb7318cef0e2820bceaab","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"b5ce7a470bc3628408429040c4e3a53a27755022a32fd05e2cb694e7015386c7","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"3cbad9a1ba4453443026ed38e4b8be018abb26565fa7c944376463ad9df07c41","impliedFormat":1},{"version":"8d6d51a5118d000ed3bfe6e1dd1335bebfff3fef23cd2af2f84a24d30f90cc90","affectsGlobalScope":true,"impliedFormat":1},{"version":"6d8dedbec739bc79642c1e96e9bfc0b83b25b104a0486aebf016fc7b85b39f48","impliedFormat":1},{"version":"e89535c3ec439608bcd0f68af555d0e5ddf121c54abe69343549718bd7506b9c","impliedFormat":1},{"version":"622a984b60c294ffb2f9152cf1d4d12e91d2b733d820eec949cf54d63a3c1025","impliedFormat":1},{"version":"81aae92abdeaccd9c1723cef39232c90c1aed9d9cf199e6e2a523b7d8e058a11","impliedFormat":1},{"version":"a63a6c6806a1e519688ef7bd8ca57be912fc0764485119dbd923021eb4e79665","impliedFormat":1},{"version":"75b57b109d774acca1e151df21cf5cb54c7a1df33a273f0457b9aee4ebd36fb9","impliedFormat":1},{"version":"073ca26c96184db9941b5ec0ddea6981c9b816156d9095747809e524fdd90e35","impliedFormat":1},{"version":"e41d17a2ec23306d953cda34e573ed62954ca6ea9b8c8b74e013d07a6886ce47","impliedFormat":1},{"version":"241bd4add06f06f0699dcd58f3b334718d85e3045d9e9d4fa556f11f4d1569c1","impliedFormat":1},{"version":"2ae3787e1498b20aad1b9c2ee9ea517ec30e89b70d242d8e3e52d1e091039695","impliedFormat":1},{"version":"c7c72c4cffb1bc83617eefed71ed68cc89df73cab9e19507ccdecb3e72b4967e","affectsGlobalScope":true,"impliedFormat":1},{"version":"b8bff8a60af0173430b18d9c3e5c443eaa3c515617210c0c7b3d2e1743c19ecb","impliedFormat":1},{"version":"38b38db08e7121828294dec10957a7a9ff263e33e2a904b346516d4a4acca482","impliedFormat":1},{"version":"a76ebdf2579e68e4cfe618269c47e5a12a4e045c2805ed7f7ab37af8daa6b091","impliedFormat":1},{"version":"8a2aaea564939c22be05d665cc955996721bad6d43148f8fa21ae8f64afecd37","impliedFormat":1},{"version":"e59d36b7b6e8ba2dd36d032a5f5c279d2460968c8b4e691ca384f118fb09b52a","impliedFormat":1},{"version":"e96885c0684c9042ec72a9a43ef977f6b4b4a2728f4b9e737edcbaa0c74e5bf6","impliedFormat":1},{"version":"95950a187596e206d32d5d9c7b932901088c65ed8f9040e614aa8e321e0225ef","impliedFormat":1},{"version":"89e061244da3fc21b7330f4bd32f47c1813dd4d7f1dc3d0883d88943f035b993","impliedFormat":1},{"version":"e46558c2e04d06207b080138678020448e7fc201f3d69c2601b0d1456105f29a","impliedFormat":1},{"version":"71549375db52b1163411dba383b5f4618bdf35dc57fa327a1c7d135cf9bf67d1","impliedFormat":1},{"version":"7e6b2d61d6215a4e82ea75bc31a80ebb8ad0c2b37a60c10c70dd671e8d9d6d5d","impliedFormat":1},{"version":"78bea05df2896083cca28ed75784dde46d4b194984e8fc559123b56873580a23","impliedFormat":1},{"version":"5dd04ced37b7ea09f29d277db11f160df7fd73ba8b9dba86cb25552e0653a637","impliedFormat":1},{"version":"f74b81712e06605677ae1f061600201c425430151f95b5ef4d04387ad7617e6a","impliedFormat":1},{"version":"9a72847fcf4ac937e352d40810f7b7aec7422d9178451148296cf1aa19467620","impliedFormat":1},{"version":"3ae18f60e0b96fa1e025059b7d25b3247ba4dcb5f4372f6d6e67ce2adac74eac","impliedFormat":1},{"version":"2b9260f44a2e071450ae82c110f5dc8f330c9e5c3e85567ed97248330f2bf639","impliedFormat":1},{"version":"4f196e13684186bda6f5115fc4677a87cf84a0c9c4fc17b8f51e0984f3697b6d","impliedFormat":1},{"version":"61419f2c5822b28c1ea483258437c1faab87d00c6f84481aa22afb3380d8e9a4","impliedFormat":1},{"version":"64479aee03812264e421c0bf5104a953ca7b02740ba80090aead1330d0effe91","impliedFormat":1},{"version":"0521108c9f8ddb17654a0a54dae6ba9667c99eddccfd6af5748113e022d1c37a","impliedFormat":1},{"version":"c5570e504be103e255d80c60b56c367bf45d502ca52ee35c55dec882f6563b5c","impliedFormat":1},{"version":"ee764e6e9a7f2b987cc1a2c0a9afd7a8f4d5ebc4fdb66ad557a7f14a8c2bd320","impliedFormat":1},{"version":"0520b5093712c10c6ef23b5fea2f833bf5481771977112500045e5ea7e8e2b69","impliedFormat":1},{"version":"5c3cf26654cf762ac4d7fd7b83f09acfe08eef88d2d6983b9a5a423cb4004ca3","impliedFormat":1},{"version":"e60fa19cf7911c1623b891155d7eb6b7e844e9afdf5738e3b46f3b687730a2bd","impliedFormat":1},{"version":"b1fd72ff2bb0ba91bb588f3e5329f8fc884eb859794f1c4657a2bfa122ae54d0","impliedFormat":1},{"version":"6cf42a4f3cfec648545925d43afaa8bb364ac10a839ffed88249da109361b275","impliedFormat":1},{"version":"d7058e75920120b142a9d57be25562a3cd9a936269fd52908505f530105f2ec4","impliedFormat":1},{"version":"6df52b70d7f7702202f672541a5f4a424d478ee5be51a9d37b8ccbe1dbf3c0f2","impliedFormat":1},{"version":"0ca7f997e9a4d8985e842b7c882e521b6f63233c4086e9fe79dd7a9dc4742b5e","impliedFormat":1},{"version":"91046b5c6b55d3b194c81fd4df52f687736fad3095e9d103ead92bb64dc160ee","impliedFormat":1},{"version":"db5704fdad56c74dfc5941283c1182ed471bd17598209d3ac4a49faa72e43cfc","impliedFormat":1},{"version":"758e8e89559b02b81bc0f8fd395b17ad5aff75490c862cbe369bb1a3d1577c40","impliedFormat":1},{"version":"2ee64342c077b1868f1834c063f575063051edd6e2964257d34aad032d6b657c","impliedFormat":1},{"version":"6f6b4b3d670b6a5f0e24ea001c1b3d36453c539195e875687950a178f1730fa7","impliedFormat":1},{"version":"a472a1d3f25ce13a1d44911cd3983956ac040ce2018e155435ea34afb25f864c","impliedFormat":1},{"version":"b48b83a86dd9cfe36f8776b3ff52fcd45b0e043c0538dc4a4b149ba45fe367b9","impliedFormat":1},{"version":"792de5c062444bd2ee0413fb766e57e03cce7cdaebbfc52fc0c7c8e95069c96b","impliedFormat":1},{"version":"a79e3e81094c7a04a885bad9b049c519aace53300fb8a0fe4f26727cb5a746ce","impliedFormat":1},{"version":"93181bac0d90db185bb730c95214f6118ae997fe836a98a49664147fbcaf1988","impliedFormat":1},{"version":"8a4e89564d8ea66ad87ee3762e07540f9f0656a62043c910d819b4746fc429c5","impliedFormat":1},{"version":"b9011d99942889a0f95e120d06b698c628b0b6fdc3e6b7ecb459b97ed7d5bcc6","impliedFormat":1},{"version":"4d639cbbcc2f8f9ce6d55d5d503830d6c2556251df332dc5255d75af53c8a0e7","impliedFormat":1},{"version":"cdb48277f600ab5f429ecf1c5ea046683bc6b9f73f3deab9a100adac4b34969c","impliedFormat":1},{"version":"75be84956a29040a1afbe864c0a7a369dfdb739380072484eff153905ef867ee","impliedFormat":1},{"version":"b06b4adc2ae03331a92abd1b19af8eb91ec2bf8541747ee355887a167d53145e","impliedFormat":1},{"version":"c54166a85bd60f86d1ebb90ce0117c0ecb850b8a33b366691629fdf26f1bbbd8","impliedFormat":1},{"version":"0d417c15c5c635384d5f1819cc253a540fe786cc3fda32f6a2ae266671506a21","impliedFormat":1},{"version":"80f23f1d60fbed356f726b3b26f9d348dddbb34027926d10d59fad961e70a730","impliedFormat":1},{"version":"cb59317243a11379a101eb2f27b9df1022674c3df1df0727360a0a3f963f523b","impliedFormat":1},{"version":"cc20bb2227dd5de0aab0c8d697d1572f8000550e62c7bf5c92f212f657dd88c5","impliedFormat":1},{"version":"06b8a7d46195b6b3980e523ef59746702fd210b71681a83a5cf73799623621f9","impliedFormat":1},{"version":"860e4405959f646c101b8005a191298b2381af8f33716dc5f42097e4620608f8","impliedFormat":1},{"version":"f7e32adf714b8f25d3c1783473abec3f2e82d5724538d8dcf6f51baaaff1ca7a","impliedFormat":1},{"version":"d0da80c845999a16c24d0783033fb5366ada98df17867c98ad433ede05cd87fd","impliedFormat":1},{"version":"bfbf80f9cd4558af2d7b2006065340aaaced15947d590045253ded50aabb9bc5","impliedFormat":1},{"version":"fd9a991b51870325e46ebb0e6e18722d313f60cd8e596e645ec5ac15b96dbf4e","impliedFormat":1},{"version":"c3bd2b94e4298f81743d92945b80e9b56c1cdfb2bef43c149b7106a2491b1fc9","impliedFormat":1},{"version":"a246cce57f558f9ebaffd55c1e5673da44ea603b4da3b2b47eb88915d30a9181","impliedFormat":1},{"version":"d993eacc103c5a065227153c9aae8acea3a4322fe1a169ee7c70b77015bf0bb2","impliedFormat":1},{"version":"fc2b03d0c042aa1627406e753a26a1eaad01b3c496510a78016822ef8d456bb6","impliedFormat":1},{"version":"063c7ebbe756f0155a8b453f410ca6b76ffa1bbc1048735bcaf9c7c81a1ce35f","impliedFormat":1},{"version":"314e402cd481370d08f63051ae8b8c8e6370db5ee3b8820eeeaaf8d722a6dac6","impliedFormat":1},{"version":"9669075ac38ce36b638b290ba468233980d9f38bdc62f0519213b2fd3e2552ec","impliedFormat":1},{"version":"4d123de012c24e2f373925100be73d50517ac490f9ed3578ac82d0168bfbd303","impliedFormat":1},{"version":"656c9af789629aa36b39092bee3757034009620439d9a39912f587538033ce28","impliedFormat":1},{"version":"3ac3f4bdb8c0905d4c3035d6f7fb20118c21e8a17bee46d3735195b0c2a9f39f","impliedFormat":1},{"version":"1f453e6798ed29c86f703e9b41662640d4f2e61337007f27ac1c616f20093f69","impliedFormat":1},{"version":"af43b7871ff21c62bf1a54ec5c488e31a8d3408d5b51ff2e9f8581b6c55f2fc7","impliedFormat":1},{"version":"70550511d25cbb0b6a64dcac7fffc3c1397fd4cbeb6b23ccc7f9b794ab8a6954","impliedFormat":1},{"version":"af0fbf08386603a62f2a78c42d998c90353b1f1d22e05a384545f7accf881e0a","impliedFormat":1},{"version":"cefc20054d20b85b534206dbcedd509bb74f87f3d8bc45c58c7be3a76caa45e1","impliedFormat":1},{"version":"ad6eee4877d0f7e5244d34bc5026fd6e9cf8e66c5c79416b73f9f6ebf132f924","impliedFormat":1},{"version":"4888fd2bcfee9a0ce89d0df860d233e0cee8ee9c479b6bd5a5d5f9aae98342fe","impliedFormat":1},{"version":"f4749c102ced952aa6f40f0b579865429c4869f6d83df91000e98005476bee87","impliedFormat":1},{"version":"56654d2c5923598384e71cb808fac2818ca3f07dd23bb018988a39d5e64f268b","impliedFormat":1},{"version":"8b6719d3b9e65863da5390cb26994602c10a315aa16e7d70778a63fee6c4c079","impliedFormat":1},{"version":"05f56cd4b929977d18df8f3d08a4c929a2592ef5af083e79974b20a063f30940","impliedFormat":1},{"version":"547d3c406a21b30e2b78629ecc0b2ddaf652d9e0bdb2d59ceebce5612906df33","impliedFormat":1},{"version":"b3a4f9385279443c3a5568ec914a9492b59a723386161fd5ef0619d9f8982f97","impliedFormat":1},{"version":"3fe66aba4fbe0c3ba196a4f9ed2a776fe99dc4d1567a558fb11693e9fcc4e6ed","impliedFormat":1},{"version":"140eef237c7db06fc5adcb5df434ee21e81ee3a6fd57e1a75b8b3750aa2df2d8","impliedFormat":1},{"version":"0944ec553e4744efae790c68807a461720cff9f3977d4911ac0d918a17c9dd99","impliedFormat":1},{"version":"cb46b38d5e791acaa243bf342b8b5f8491639847463ac965b93896d4fb0af0d9","impliedFormat":1},{"version":"7c7d9e116fe51100ff766703e6b5e4424f51ad8977fe474ddd8d0959aa6de257","impliedFormat":1},{"version":"af70a2567e586be0083df3938b6a6792e6821363d8ef559ad8d721a33a5bcdaf","impliedFormat":1},{"version":"006cff3a8bcb92d77953f49a94cd7d5272fef4ab488b9052ef82b6a1260d870b","impliedFormat":1},{"version":"7d44bfdc8ee5e9af70738ff652c622ae3ad81815e63ab49bdc593d34cb3a68e5","impliedFormat":1},{"version":"339814517abd4dbc7b5f013dfd3b5e37ef0ea914a8bbe65413ecffd668792bc6","impliedFormat":1},{"version":"34d5bc0a6958967ec237c99f980155b5145b76e6eb927c9ffc57d8680326b5d8","impliedFormat":1},{"version":"9eae79b70c9d8288032cbe1b21d0941f6bd4f315e14786b2c1d10bccc634e897","impliedFormat":1},{"version":"18ce015ed308ea469b13b17f99ce53bbb97975855b2a09b86c052eefa4aa013a","impliedFormat":1},{"version":"5a931bc4106194e474be141e0bc1046629510dc95b9a0e4b02a3783847222965","impliedFormat":1},{"version":"5e5f371bf23d5ced2212a5ff56675aefbd0c9b3f4d4fdda1b6123ac6e28f058c","impliedFormat":1},{"version":"907c17ad5a05eecb29b42b36cc8fec6437be27cc4986bb3a218e4f74f606911c","impliedFormat":1},{"version":"ce60a562cd2a92f37a88f2ddd99a3abfbc5848d7baf38c48fb8d3243701fcb75","impliedFormat":1},{"version":"a726ad2d0a98bfffbe8bc1cd2d90b6d831638c0adc750ce73103a471eb9a891c","impliedFormat":1},{"version":"f44c0c8ce58d3dacac016607a1a90e5342d830ea84c48d2e571408087ae55894","impliedFormat":1},{"version":"75a315a098e630e734d9bc932d9841b64b30f7a349a20cf4717bf93044eff113","impliedFormat":1},{"version":"9131d95e32b3d4611d4046a613e022637348f6cebfe68230d4e81b691e4761a1","impliedFormat":1},{"version":"b03aa292cfdcd4edc3af00a7dbd71136dd067ec70a7536b655b82f4dd444e857","impliedFormat":1},{"version":"b6e2b0448ced813b8c207810d96551a26e7d7bb73255eea4b9701698f78846d6","impliedFormat":1},{"version":"8ae10cd85c1bd94d2f2d17c4cbd25c068a4b2471c70c2d96434239f97040747a","impliedFormat":1},{"version":"9ed5b799c50467b0c9f81ddf544b6bcda3e34d92076d6cab183c84511e45c39f","impliedFormat":1},{"version":"b4fa87cc1833839e51c49f20de71230e259c15b2c9c3e89e4814acc1d1ef10de","impliedFormat":1},{"version":"e90ac9e4ac0326faa1bc39f37af38ace0f9d4a655cd6d147713c653139cf4928","impliedFormat":1},{"version":"ea27110249d12e072956473a86fd1965df8e1be985f3b686b4e277afefdde584","impliedFormat":1},{"version":"8776a368617ce51129b74db7d55c3373dadcce5d0701e61d106e99998922a239","impliedFormat":1},{"version":"5666075052877fe2fdddd5b16de03168076cf0f03fbca5c1d4a3b8f43cba570c","impliedFormat":1},{"version":"9108ab5af05418f599ab48186193b1b07034c79a4a212a7f73535903ba4ca249","impliedFormat":1},{"version":"bb4e2cdcadf9c9e6ee2820af23cee6582d47c9c9c13b0dca1baaffe01fbbcb5f","impliedFormat":1},{"version":"6e30d0b5a1441d831d19fe02300ab3d83726abd5141cbcc0e2993fa0efd33db4","impliedFormat":1},{"version":"423f28126b2fc8d8d6fa558035309000a1297ed24473c595b7dec52e5c7ebae5","impliedFormat":1},{"version":"fb30734f82083d4790775dae393cd004924ebcbfde49849d9430bf0f0229dd16","impliedFormat":1},{"version":"2c92b04a7a4a1cd9501e1be338bf435738964130fb2ad5bd6c339ee41224ac4c","impliedFormat":1},{"version":"c5c5f0157b41833180419dacfbd2bcce78fb1a51c136bd4bcba5249864d8b9b5","impliedFormat":1},{"version":"02ae43d5bae42efcd5a00d3923e764895ce056bca005a9f4e623aa6b4797c8af","impliedFormat":1},{"version":"db6e01f17012a9d7b610ae764f94a1af850f5d98c9c826ad61747dca0fb800bd","impliedFormat":1},{"version":"8a44b424edee7bb17dc35a558cc15f92555f14a0441205613e0e50452ab3a602","impliedFormat":1},{"version":"24a00d0f98b799e6f628373249ece352b328089c3383b5606214357e9107e7d5","impliedFormat":1},{"version":"33637e3bc64edd2075d4071c55d60b32bdb0d243652977c66c964021b6fc8066","impliedFormat":1},{"version":"0f0ad9f14dedfdca37260931fac1edf0f6b951c629e84027255512f06a6ebc4c","impliedFormat":1},{"version":"16ad86c48bf950f5a480dc812b64225ca4a071827d3d18ffc5ec1ae176399e36","impliedFormat":1},{"version":"8cbf55a11ff59fd2b8e39a4aa08e25c5ddce46e3af0ed71fb51610607a13c505","impliedFormat":1},{"version":"d5bc4544938741f5daf8f3a339bfbf0d880da9e89e79f44a6383aaf056fe0159","impliedFormat":1},{"version":"97f9169882d393e6f303f570168ca86b5fe9aab556e9a43672dae7e6bb8e6495","impliedFormat":1},{"version":"7c9adb3fcd7851497818120b7e151465406e711d6a596a71b807f3a17853cb58","impliedFormat":1},{"version":"6752d402f9282dd6f6317c8c048aaaac27295739a166eed27e00391b358fed9a","impliedFormat":1},{"version":"9fd7466b77020847dbc9d2165829796bf7ea00895b2520ff3752ffdcff53564b","impliedFormat":1},{"version":"fbfc12d54a4488c2eb166ed63bab0fb34413e97069af273210cf39da5280c8d6","impliedFormat":1},{"version":"85a84240002b7cf577cec637167f0383409d086e3c4443852ca248fc6e16711e","impliedFormat":1},{"version":"84794e3abd045880e0fadcf062b648faf982aa80cfc56d28d80120e298178626","impliedFormat":1},{"version":"053d8b827286a16a669a36ffc8ccc8acdf8cc154c096610aa12348b8c493c7b8","impliedFormat":1},{"version":"3cce4ce031710970fe12d4f7834375f5fd455aa129af4c11eb787935923ff551","impliedFormat":1},{"version":"8f62cbd3afbd6a07bb8c934294b6bfbe437021b89e53a4da7de2648ecfc7af25","impliedFormat":1},{"version":"62c3621d34fb2567c17a2c4b89914ebefbfbd1b1b875b070391a7d4f722e55dc","impliedFormat":1},{"version":"c05ac811542e0b59cb9c2e8f60e983461f0b0e39cea93e320fad447ff8e474f3","impliedFormat":1},{"version":"8e7a5b8f867b99cc8763c0b024068fb58e09f7da2c4810c12833e1ca6eb11c4f","impliedFormat":1},{"version":"132351cbd8437a463757d3510258d0fa98fd3ebef336f56d6f359cf3e177a3ce","impliedFormat":1},{"version":"df877050b04c29b9f8409aa10278d586825f511f0841d1ec41b6554f8362092b","impliedFormat":1},{"version":"33d1888c3c27d3180b7fd20bac84e97ecad94b49830d5dd306f9e770213027d1","impliedFormat":1},{"version":"ee942c58036a0de88505ffd7c129f86125b783888288c2389330168677d6347f","impliedFormat":1},{"version":"a3f317d500c30ea56d41501632cdcc376dae6d24770563a5e59c039e1c2a08ec","impliedFormat":1},{"version":"eb21ddc3a8136a12e69176531197def71dc28ffaf357b74d4bf83407bd845991","impliedFormat":1},{"version":"0c1651a159995dfa784c57b4ea9944f16bdf8d924ed2d8b3db5c25d25749a343","impliedFormat":1},{"version":"aaa13958e03409d72e179b5d7f6ec5c6cc666b7be14773ae7b6b5ee4921e52db","impliedFormat":1},{"version":"0a86e049843ad02977a94bb9cdfec287a6c5a0a4b6b5391a6648b1a122072c5a","impliedFormat":1},{"version":"40f06693e2e3e58526b713c937895c02e113552dc8ba81ecd49cdd9596567ddb","impliedFormat":1},{"version":"4ed5e1992aedb174fb8f5aa8796aa6d4dcb8bd819b4af1b162a222b680a37fa0","impliedFormat":1},{"version":"d7f4bd46a8b97232ea6f8c28012b8d2b995e55e729d11405f159d3e00c51420a","impliedFormat":1},{"version":"d604d413aff031f4bfbdae1560e54ebf503d374464d76d50a2c6ded4df525712","impliedFormat":1},{"version":"e4f4f9cf1e3ac9fd91ada072e4d428ecbf0aa6dc57138fb797b8a0ca3a1d521c","impliedFormat":1},{"version":"12bfd290936824373edda13f48a4094adee93239b9a73432db603127881a300d","impliedFormat":1},{"version":"340ceb3ea308f8e98264988a663640e567c553b8d6dc7d5e43a8f3b64f780374","impliedFormat":1},{"version":"c5a769564e530fba3ec696d0a5cff1709b9095a0bdf5b0826d940d2fc9786413","impliedFormat":1},{"version":"7124ef724c3fc833a17896f2d994c368230a8d4b235baed39aa8037db31de54f","impliedFormat":1},{"version":"5de1c0759a76e7710f76899dcae601386424eab11fb2efaf190f2b0f09c3d3d3","impliedFormat":1},{"version":"9c5ee8f7e581f045b6be979f062a61bf076d362bf89c7f966b993a23424e8b0d","impliedFormat":1},{"version":"1a11df987948a86aa1ec4867907c59bdf431f13ed2270444bf47f788a5c7f92d","impliedFormat":1},{"version":"8018dd2e95e7ce6e613ddd81672a54532614dc745520a2f9e3860ff7fb1be0ca","impliedFormat":1},{"version":"b756781cd40d465da57d1fc6a442c34ae61fe8c802d752aace24f6a43fedacee","impliedFormat":1},{"version":"0fe76167c87289ea094e01616dcbab795c11b56bad23e1ef8aba9aa37e93432a","impliedFormat":1},{"version":"3a45029dba46b1f091e8dc4d784e7be970e209cd7d4ff02bd15270a98a9ba24b","impliedFormat":1},{"version":"032c1581f921f8874cf42966f27fd04afcabbb7878fa708a8251cac5415a2a06","impliedFormat":1},{"version":"69c68ed9652842ce4b8e495d63d2cd425862104c9fb7661f72e7aa8a9ef836f8","impliedFormat":1},{"version":"0e704ee6e9fd8b6a5a7167886f4d8915f4bc22ed79f19cb7b32bd28458f50643","impliedFormat":1},{"version":"06f62a14599a68bcde148d1efd60c2e52e8fa540cc7dcfa4477af132bb3de271","impliedFormat":1},{"version":"904a96f84b1bcee9a7f0f258d17f8692e6652a0390566515fe6741a5c6db8c1c","impliedFormat":1},{"version":"11f19ce32d21222419cecab448fa335017ebebf4f9e5457c4fa9df42fa2dcca7","impliedFormat":1},{"version":"2e8ee2cbb5e9159764e2189cf5547aebd0e6b0d9a64d479397bb051cd1991744","impliedFormat":1},{"version":"1b0471d75f5adb7f545c1a97c02a0f825851b95fe6e069ac6ecaa461b8bb321d","impliedFormat":1},{"version":"1d157c31a02b1e5cca9bc495b3d8d39f4b42b409da79f863fb953fbe3c7d4884","impliedFormat":1},{"version":"07baaceaec03d88a4b78cb0651b25f1ae0322ac1aa0b555ae3749a79a41cba86","impliedFormat":1},{"version":"619a132f634b4ebe5b4b4179ea5870f62f2cb09916a25957bff17b408de8b56d","impliedFormat":1},{"version":"f60fa446a397eb1aead9c4e568faf2df8068b4d0306ebc075fb4be16ed26b741","impliedFormat":1},{"version":"f3cb784be4d9e91f966a0b5052a098d9b53b0af0d341f690585b0cc05c6ca412","impliedFormat":1},{"version":"350f63439f8fe2e06c97368ddc7fb6d6c676d54f59520966f7dbbe6a4586014e","impliedFormat":1},{"version":"eba613b9b357ac8c50a925fa31dc7e65ff3b95a07efbaa684b624f143d8d34ba","impliedFormat":1},{"version":"45b74185005ed45bec3f07cac6e4d68eaf02ead9ff5a66721679fb28020e5e7c","impliedFormat":1},{"version":"0f6199602df09bdb12b95b5434f5d7474b1490d2cd8cc036364ab3ba6fd24263","impliedFormat":1},{"version":"c8ca7fd9ec7a3ec82185bfc8213e4a7f63ae748fd6fced931741d23ef4ea3c0f","impliedFormat":1},{"version":"5c6a8a3c2a8d059f0592d4eab59b062210a1c871117968b10797dee36d991ef7","impliedFormat":1},{"version":"ad77fd25ece8e09247040826a777dc181f974d28257c9cd5acb4921b51967bd8","impliedFormat":1},{"version":"795a08ae4e193f345073b49f68826ab6a9b280400b440906e4ec5c237ae777e6","impliedFormat":1},{"version":"8153df63cf65122809db17128e5918f59d6bb43a371b5218f4430c4585f64085","impliedFormat":1},{"version":"a8150bc382dd12ce58e00764d2366e1d59a590288ee3123af8a4a2cb4ef7f9df","impliedFormat":1},{"version":"5adfaf2f9f33957264ad199a186456a4676b2724ed700fc313ff945d03372169","impliedFormat":1},{"version":"d5c41a741cd408c34cb91f84468f70e9bda3dfeabf33251a61039b3cdb8b22d8","impliedFormat":1},{"version":"c91d3f9753a311284e76cdcb348cbb50bca98733336ec726b54d77b7361b34de","impliedFormat":1},{"version":"cbaf4a4aa8a8c02aa681c5870d5c69127974de29b7e01df570edec391a417959","impliedFormat":1},{"version":"c7135e329a18b0e712378d5c7bc2faec6f5ab0e955ea0002250f9e232af8b3e4","impliedFormat":1},{"version":"340a45cd77b41d8a6deda248167fa23d3dc67ec798d411bd282f7b3d555b1695","impliedFormat":1},{"version":"fae330f86bc10db6841b310f32367aaa6f553036a3afc426e0389ddc5566cd74","impliedFormat":1},{"version":"cf25d45c02d5fd5d7adb16230a0e1d6715441eef5c0a79a21bfeaa9bbc058939","impliedFormat":1},{"version":"54c3822eaf6436f2eddc92dd6e410750465aba218adbf8ce5d488d773919ec01","impliedFormat":1},{"version":"99d99a765426accf8133737843fb024a154dc6545fc0ffbba968a7c0b848959d","impliedFormat":1},{"version":"c782c5fd5fa5491c827ecade05c3af3351201dd1c7e77e06711c8029b7a9ee4d","impliedFormat":1},{"version":"883d2104e448bb351c49dd9689a7e8117b480b614b2622732655cef03021bf6d","impliedFormat":1},{"version":"d9b00ee2eca9b149663fdba1c1956331841ae296ee03eaaff6c5becbc0ff1ea8","impliedFormat":1},{"version":"09a7e04beb0547c43270b327c067c85a4e2154372417390731dfe092c4350998","impliedFormat":1},{"version":"eee530aaa93e9ec362e3941ee8355e2d073c7b21d88c2af4713e3d701dab8fef","impliedFormat":1},{"version":"28d47319b97dbeee9130b78eae03b2061d46dedbf92b0d9de13ed7ab8399ccd0","impliedFormat":1},{"version":"8b8b92781a6bf150f9ee83f3d8ee278b6cdb98b8308c7ab3413684fc5d9078ef","impliedFormat":1},{"version":"7a0e4cd92545ad03910fd019ae9838718643bd4dde39881c745f236914901dfa","impliedFormat":1},{"version":"c99ebd20316217e349004ee1a0bc74d32d041fb6864093f10f31984c737b8cad","impliedFormat":1},{"version":"6f622e7f054f5ab86258362ac0a64a2d6a27f1e88732d6f5f052f422e08a70e7","impliedFormat":1},{"version":"d62d2ef93ceeb41cf9dfab25989a1e5f9ca5160741aac7f1453c69a6c14c69be","impliedFormat":1},{"version":"1491e80d72873fc586605283f2d9056ee59b166333a769e64378240df130d1c9","impliedFormat":1},{"version":"c32c073d389cfaa3b3e562423e16c2e6d26b8edebbb7d73ccffff4aa66f2171d","impliedFormat":1},{"version":"eca72bf229eecadb63e758613c62fab13815879053539a22477d83a48a21cd73","impliedFormat":1},{"version":"633db46fd1765736409a4767bfc670861468dde60dbb9a501fba4c1b72f8644d","impliedFormat":1},{"version":"689390db63cb282e6d0e5ce9b8f1ec2ec0912d0e2e6dac7235699a15ad17d339","impliedFormat":1},{"version":"f2ee748883723aa9325e5d7f30fce424f6a786706e1b91a5a55237c78ee89c4a","impliedFormat":1},{"version":"d928324d17146fce30b99a28d1d6b48648feac72bbd23641d3ce5ac34aefdfee","impliedFormat":1},{"version":"142f5190d730259339be1433931c0eb31ae7c7806f4e325f8a470bd9221b6533","impliedFormat":1},{"version":"c33a88f2578e8df2fdf36c6a0482bbee615eb3234c8f084ba31a9a96bd306b7f","impliedFormat":1},{"version":"22cca068109eb0e6b4f8acc3fe638d1e6ac277e2044246438763319792b546a1","impliedFormat":1},{"version":"8776e64e6165838ac152fa949456732755b0976d1867ae5534ce248f0ccd7f41","impliedFormat":1},{"version":"66cd33c4151ea27f6e17c6071652eadde9da1b3637dae65fd060212211c695ce","impliedFormat":1},{"version":"5c4c5b49bbb01828402bb04af1d71673b18852c11b7e95bfd5cf4c3d80d352c8","impliedFormat":1},{"version":"7030df3d920343df00324df59dc93a959a33e0f4940af3fefef8c07b7ee329bf","impliedFormat":1},{"version":"a96bc00e0c356e29e620eaec24a56d6dd7f4e304feefcc99066a1141c6fe05a7","impliedFormat":1},{"version":"d12cc0e5b09943c4cd0848f787eb9d07bf78b60798e4588c50582db9d4decc70","impliedFormat":1},{"version":"53b094f1afe442490555eeeb0384fc1ceb487560c83e31f9c64fb934c2dccd94","impliedFormat":1},{"version":"19c3760af3cbc9da99d5b7763b9e33aaf8d018bc2ed843287b7ff4343adf4634","impliedFormat":1},{"version":"9d1e38aeb76084848d2fcd39b458ec88246de028c0f3f448b304b15d764b23d2","impliedFormat":1},{"version":"d406da1eccf18cec56fd29730c24af69758fe3ff49c4f94335e797119cbc0554","impliedFormat":1},{"version":"4898c93890a136da9156c75acd1a80a941a961b3032a0cf14e1fa09a764448b7","impliedFormat":1},{"version":"f5d7a845e3e1c6c27351ea5f358073d0b0681537a2da6201fab254aa434121d3","impliedFormat":1},{"version":"9ddf8e9069327faa75d20135cab675779844f66590249769c3d35dd2a38c2ba9","impliedFormat":1},{"version":"d7c30f0abfe9e197e376b016086cf66b2ffb84015139963f37301ed0da9d3d0d","impliedFormat":1},{"version":"ff75bba0148f07775bcb54bf4823421ed4ebdb751b3bf79cc003bd22e49d7d73","impliedFormat":1},{"version":"d40d20ac633703a7333770bfd60360126fc3302d5392d237bbb76e8c529a4f95","impliedFormat":1},{"version":"35a9867207c488061fb4f6fe4715802fbc164b4400018d2fa0149ad02db9a61c","impliedFormat":1},{"version":"91bf47a209ad0eae090023c3ebc1165a491cf9758799368ffcbee8dbe7448f33","impliedFormat":1},{"version":"0abe2cd72812bbfc509975860277c7cd6f6e0be95d765a9da77fee98264a7e32","impliedFormat":1},{"version":"13286c0c8524606b17a8d68650970bab896fb505f348f71601abf0f2296e8913","impliedFormat":1},{"version":"fc2a131847515b3dff2f0e835633d9a00a9d03ed59e690e27eec85b7b0522f92","impliedFormat":1},{"version":"90433c678bc26751eb7a5d54a2bb0a14be6f5717f69abb5f7a04afc75dce15a4","impliedFormat":1},{"version":"cd0565ace87a2d7802bf4c20ea23a997c54e598b9eb89f9c75e69478c1f7a0b4","impliedFormat":1},{"version":"738020d2c8fc9df92d5dee4b682d35a776eaedfe2166d12bc8f186e1ea57cc52","impliedFormat":1},{"version":"86dd7c5657a0b0bc6bee8002edcfd544458d3d3c60974555746eb9b2583dc35e","impliedFormat":1},{"version":"d97b96b6ecd4ee03f9f1170722c825ef778430a6a0d7aab03b8929012bf773cd","impliedFormat":1},{"version":"f61963dc02ef27c48fb0e0016a413b1e00bcb8b97a3f5d4473cedc7b44c8dc77","impliedFormat":1},{"version":"272dbfe04cfa965d6fff63fdaba415c1b5a515b1881ae265148f8a84ddeb318f","impliedFormat":1},{"version":"2035fb009b5fafa9a4f4e3b3fdb06d9225b89f2cbbf17a5b62413bf72cea721a","impliedFormat":1},{"version":"eefafec7c059f07b885b79b327d381c9a560e82b439793de597441a4e68d774a","impliedFormat":1},{"version":"72636f59b635c378dc9ea5246b9b3517b1214e340e468e54cb80126353053b2e","impliedFormat":1},{"version":"ebb79f267a3bf2de5f8edc1995c5d31777b539935fab8b7d863e8efb06c8e9ea","impliedFormat":1},{"version":"ada033e6a4c7f4e147e6d76bb881069dc66750619f8cc2472d65beeec1100145","impliedFormat":1},{"version":"0c04cc14a807a5dc0e3752d18a3b2655a135fefbf76ddcdabd0c5df037530d41","impliedFormat":1},{"version":"605d29d619180fbec287d1701e8b1f51f2d16747ec308d20aba3e9a0dac43a0f","impliedFormat":1},{"version":"67c19848b442d77c767414084fc571ce118b08301c4ddff904889d318f3a3363","impliedFormat":1},{"version":"c704ff0e0cb86d1b791767a88af21dadfee259180720a14c12baee668d0eb8fb","impliedFormat":1},{"version":"195c50e15d5b3ea034e01fbdca6f8ad4b35ad47463805bb0360bdffd6fce3009","impliedFormat":1},{"version":"da665f00b6877ae4adb39cd548257f487a76e3d99e006a702a4f38b4b39431cb","impliedFormat":1},{"version":"2b82adc9eead34b824a3f4dad315203fbfa56bee0061ccf9b485820606564f70","impliedFormat":1},{"version":"eb47aaa5e1b0a69388bb48422a991b9364a9c206a97983e0227289a9e1fca178","impliedFormat":1},{"version":"d7a4309673b06223537bc9544b1a5fe9425628e1c8ab5605f3c5ebc27ecb8074","impliedFormat":1},{"version":"db2108aea36e7faa83c38f6fe8225b9ad40835c0cba7fa38e969768299b83173","impliedFormat":1},{"version":"3eadfd083d40777b403f4f4eecfa40f93876f2a01779157cc114b2565a7afb51","impliedFormat":1},{"version":"cb6789ce3eba018d5a7996ccbf50e27541d850e9b4ee97fdcb3cbd8c5093691f","impliedFormat":1},{"version":"a3684ea9719122f9477902acd08cd363a6f3cff6d493df89d4dc12fa58204e27","impliedFormat":1},{"version":"2828dabf17a6507d39ebcc58fef847e111dcf2d51b8e4ff0d32732c72be032b3","impliedFormat":1},{"version":"c0c46113b4cd5ec9e7cf56e6dbfb3930ef6cbba914c0883eeced396988ae8320","impliedFormat":1},{"version":"118ea3f4e7b9c12e92551be0766706f57a411b4f18a1b4762cfde3cd6d4f0a96","impliedFormat":1},{"version":"2ad163aaddfa29231a021de6838f59378a210501634f125ed04cfa7d066ffc53","impliedFormat":1},{"version":"6305acbe492b9882ec940f8f0c8e5d1e1395258852f99328efcb1cf1683ca817","impliedFormat":1},{"version":"7619b1f6087a4e9336b2c42bd784b05aa4a2204a364b60171e5a628f817a381e","impliedFormat":1},{"version":"15be9120572c9fbcd3c267bd93b4140354514c9e70734e6fcca65ff4a246f83a","impliedFormat":1},{"version":"412482ab85893cec1d6f26231359474d1f59f6339e2743c08da1b05fc1d12767","impliedFormat":1},{"version":"858e2315e58af0d28fcd7f141a2505aba6a76fd10378ba0ad169b0336fee33fc","impliedFormat":1},{"version":"02da6c1b34f4ae2120d70cf5f9268bf1aedf62e55529d34f5974f5a93655ce38","impliedFormat":1},{"version":"3ecf179ef1cc28f7f9b46c8d2e496d50b542c176e94ed0147bab147b4a961cd6","impliedFormat":1},{"version":"b145da03ce7e174af5ced2cbbd16e96d3d5c2212f9a90d3657b63a5650a73b7f","impliedFormat":1},{"version":"c7aadab66a2bc90eeb0ab145ca4daebcbc038e24359263de3b40e7b1c7affba6","impliedFormat":1},{"version":"99518dc06286877a7b716e0f22c1a72d3c62be42701324b49f27bcc03573efff","impliedFormat":1},{"version":"f4575fd196a7e33c7be9773a71bcc5fbe7182a2152be909f6b8e8e7ba2438f06","impliedFormat":1},{"version":"05cba5acd77a4384389b9c62739104b5a1693efd66e6abac6c5ffc53280ae777","impliedFormat":1},{"version":"acacda82ebd929fe2fe9e31a37f193fc8498a7393a1c31dc5ceb656e2b45b708","impliedFormat":1},{"version":"1b13e7c5c58ab894fe65b099b6d19bb8afae6d04252db1bf55fe6ba95a0af954","impliedFormat":1},{"version":"4355d326c3129e5853b56267903f294ad03e34cc28b75f96b80734882dedac80","impliedFormat":1},{"version":"37139a8d45342c05b6a5aa1698a2e8e882d6dca5fb9a77aa91f05ac04e92e70b","impliedFormat":1},{"version":"e37191297f1234d3ae54edbf174489f9a3091a05fe959724db36f8e58d21fb17","impliedFormat":1},{"version":"3fca8fb3aab1bc7abb9b1420f517e9012fdddcbe18803bea2dd48fad6c45e92e","impliedFormat":1},{"version":"d0b0779e0cac4809a9a3c764ba3bd68314de758765a8e3b9291fe1671bfeb8a1","impliedFormat":1},{"version":"d2116b5f989aa68e585ae261b9d6d836be6ed1be0b55b47336d9f3db34674e86","impliedFormat":1},{"version":"d79a227dd654be16d8006eac8b67212679d1df494dfe6da22ea0bd34a13e010c","impliedFormat":1},{"version":"b9c89b4a2435c171e0a9a56668f510a376cb7991eaecef08b619e6d484841735","impliedFormat":1},{"version":"44a298a6c52a7dab8e970e95a6dabe20972a7c31c340842e0dc57f2c822826eb","impliedFormat":1},{"version":"6a79b61f57699de0a381c8a13f4c4bcd120556bfab0b4576994b6917cb62948b","impliedFormat":1},{"version":"c5133d7bdec65f465df12f0b507fbc0d96c78bfa5a012b0eb322cf1ff654e733","impliedFormat":1},{"version":"00b9ff040025f6b00e0f4ac8305fea1809975b325af31541bd9d69fa3b5e57b1","impliedFormat":1},{"version":"9f96b9fd0362a7bfe6a3aa70baa883c47ae167469c904782c99ccc942f62f0dc","impliedFormat":1},{"version":"54d91053dc6a2936bfd01a130cc3b524e11aa0349da082e8ac03a8bf44250338","impliedFormat":1},{"version":"89049878a456b5e0870bb50289ea8ece28a2abd0255301a261fa8ab6a3e9a07d","impliedFormat":1},{"version":"55ae9554811525f24818e19bdc8779fa99df434be7c03e5fc47fa441315f0226","impliedFormat":1},{"version":"24abac81e9c60089a126704e936192b2309413b40a53d9da68dadd1dd107684e","impliedFormat":1},{"version":"f13310c360ecffddb3858dcb33a7619665369d465f55e7386c31d45dfc3847bf","impliedFormat":1},{"version":"e7bde95a05a0564ee1450bc9a53797b0ac7944bf24d87d6f645baca3aa60df48","impliedFormat":1},{"version":"62e68ce120914431a7d34232d3eca643a7ddd67584387936a5202ae1c4dd9a1b","impliedFormat":1},{"version":"91d695bba902cc2eda7edc076cd17c5c9340f7bb254597deb6679e343effadbb","impliedFormat":1},{"version":"e1cb8168c7e0bd4857a66558fe7fe6c66d08432a0a943c51bacdac83773d5745","impliedFormat":1},{"version":"a464510505f31a356e9833963d89ce39f37a098715fc2863e533255af4410525","impliedFormat":1},{"version":"ebbe6765a836bfa7f03181bc433c8984ca29626270ca1e240c009851222cb8a7","impliedFormat":1},{"version":"ac10457b51ee4a3173b7165c87c795eadd094e024f1d9f0b6f0c131126e3d903","impliedFormat":1},{"version":"468df9d24a6e2bc6b4351417e3b5b4c2ca08264d6d5045fe18eb42e7996e58b4","impliedFormat":1},{"version":"954523d1f4856180cbf79b35bd754e14d3b2aea06c7efd71b254c745976086e9","impliedFormat":1},{"version":"a8af4739274959d70f7da4bfdd64f71cfc08d825c2d5d3561bc7baed760b33ef","impliedFormat":1},{"version":"090fda1107e7d4f8f30a2b341834ed949f01737b5ec6021bb6981f8907330bdb","impliedFormat":1},{"version":"cc32874a27100c32e3706d347eb4f435d6dd5c0d83e547c157352f977bbc6385","impliedFormat":1},{"version":"e45b069d58c9ac341d371b8bc3db4fa7351b9eee1731bffd651cfc1eb622f844","impliedFormat":1},{"version":"7f3c74caad25bfb6dfbf78c6fe194efcf8f79d1703d785fc05cd606fe0270525","impliedFormat":1},{"version":"54f3f7ff36384ca5c9e1627118b43df3014b7e0f62c9722619d19cdb7e43d608","impliedFormat":1},{"version":"2f346f1233bae487f1f9a11025fc73a1bf9093ee47980a9f4a75b84ea0bb7021","impliedFormat":1},{"version":"013444d0b8c1f7b5115462c31573a699fee7458381b0611062a0069d3ef810e8","impliedFormat":1},{"version":"0612b149cabbc136cb25de9daf062659f306b67793edc5e39755c51c724e2949","impliedFormat":1},{"version":"2579b150b86b5f644d86a6d58f17e3b801772c78866c34d41f86f3fc9eb523fe","impliedFormat":1},{"version":"0353e05b0d8475c10ddd88056e0483b191aa5cdea00a25e0505b96e023f1a2d9","impliedFormat":1},{"version":"8c4df93dafcf06adc42a63477cc38b352565a3ed0a19dd8ef7dfacc253749327","impliedFormat":1},{"version":"22a35275abc67f8aba44efc52b2f4b1abc2c94e183d36647fdab5a5e7c1bdf23","impliedFormat":1},{"version":"99193bafaa9ce112889698de25c4b8c80b1209bb7402189aea1c7ada708a8a54","impliedFormat":1},{"version":"70473538c6eb9494d53bf1539fe69df68d87c348743d8f7244dcb02ca3619484","impliedFormat":1},{"version":"c48932ab06a4e7531bdca7b0f739ace5fa273f9a1b9009bcd26902f8c0b851f0","impliedFormat":1},{"version":"df6c83e574308f6540c19e3409370482a7d8f448d56c65790b4ac0ab6f6fedd8","impliedFormat":1},{"version":"32f19b665839b1382b21afc41917cda47a56e744cd3df9986b13a72746d1c522","impliedFormat":1},{"version":"8db1ed144dd2304b9bd6e41211e22bad5f4ab1d8006e6ac127b29599f4b36083","impliedFormat":1},{"version":"843a5e3737f2abbbbd43bf2014b70f1c69a80530814a27ae1f8be213ae9ec222","impliedFormat":1},{"version":"6fc1be224ad6b3f3ec11535820def2d21636a47205c2c9de32238ba1ac8d82e6","impliedFormat":1},{"version":"5a44788293f9165116c9c183be66cefef0dc5d718782a04847de53bf664f3cc1","impliedFormat":1},{"version":"afd653ae63ce07075b018ba5ce8f4e977b6055c81cc65998410b904b94003c0a","impliedFormat":1},{"version":"9172155acfeb17b9d75f65b84f36cb3eb0ff3cd763db3f0d1ad5f6d10d55662f","impliedFormat":1},{"version":"71807b208e5f15feffb3ff530bec5b46b1217af0d8cc96dde00d549353bcb864","impliedFormat":1},{"version":"1a6eca5c2bc446481046c01a54553c3ffb856f81607a074f9f0256c59dd0ab13","impliedFormat":1},{"version":"561a66ee6f8a04275ccedaa8d41be10e1986af672b43a21476c778992918df09","impliedFormat":1},{"version":"f3cd79eae123f7ff3065bc353ec609ec11fc418af3b28e5074c3f8cd18840222","impliedFormat":1},{"version":"d5eb5865d4cbaa9985cc3cfb920b230cdcf3363f1e70903a08dc4baab80b0ce1","impliedFormat":1},{"version":"51ebca098538b252953b1ef83c165f25b52271bfb6049cd09d197dddd4cd43c5","impliedFormat":1},{"version":"73a0ee6395819b063df4b148211985f2e1442945c1a057204cf4cf6281760dc3","affectsGlobalScope":true,"impliedFormat":1},{"version":"d05d8c67116dceafc62e691c47ac89f8f10cf7313cd1b2fb4fe801c2bf1bb1a7","impliedFormat":1},{"version":"3c5bb5207df7095882400323d692957e90ec17323ccff5fd5f29a1ecf3b165d0","impliedFormat":1},"017ddb0d6ca0caea9b2d871c6d478a7f00227c6e90e7281595921474b99425a4",{"version":"1d7ee0c4eb734d59b6d962bc9151f6330895067cd3058ce6a3cd95347ef5c6e8","impliedFormat":99},{"version":"bfb309d2cf7c1d004b98eddc388db0f7b51e294f2af88569bd86e761c4305ba5","impliedFormat":1},{"version":"7d80d85fbd6b4e0fe11dde5fcc9aa875547f1ec1a499ca536a39b55d4e1ba803","impliedFormat":1},{"version":"f758fa994a025fefe33dcfcf68d89ed5209b53443285561e5bfe547f770ac381","impliedFormat":1},{"version":"f611b23dfebb4e4ba6fd4f519180526491a72aad2289f7bd8393556879b37502","impliedFormat":1},{"version":"3a93e73ecbb7a89241c58fcf30ecfbf788c3e98d01f5eab4573ce0f8635b6506","impliedFormat":1},{"version":"8f1241f5d9f0d3d72117768b3c974e462840fbd85026fb66685078945404cf2f","impliedFormat":1},{"version":"beae9637082f7005001dfd306422bdc1751ab265d99b2f2b2386bb599b74a0c1","signature":"0c86bf0e2b5929049300a1fea059c193b4cf299fcfe2c182a8cae94d87ecc5c3"},"9789aad7353079b4052b4edf323ef3fd03456f9da9b65798229b64808917d062","291b86666a8c01ef717a136ca23eca5d32a32168afb5de05e6a6d81ef90899e6",{"version":"cb5eaaa2a079305b1c5344af739b29c479746f7a7aefffc7175d23d8b7c8dbb0","impliedFormat":1},{"version":"bd324dccada40f2c94aaa1ebc82b11ce3927b7a2fe74a5ab92b431d495a86e6f","impliedFormat":1},{"version":"56749bf8b557c4c76181b2fd87e41bde2b67843303ae2eabb299623897d704d6","impliedFormat":1},{"version":"5a6fbec8c8e62c37e9685a91a6ef0f6ecaddb1ee90f7b2c2b71b454b40a0d9a6","impliedFormat":1},{"version":"e7435f2f56c50688250f3b6ef99d8f3a1443f4e3d65b4526dfb31dfd4ba532f8","impliedFormat":1},{"version":"6fc56a681a637069675b2e11b4aa105efe146f7a88876f23537e9ea139297cf9","impliedFormat":1},{"version":"33b7f4106cf45ae7ccbb95acd551e9a5cd3c27f598d48216bda84213b8ae0c7e","impliedFormat":1},{"version":"176d6f604b228f727afb8e96fd6ff78c7ca38102e07acfb86a0034d8f8a2064a","impliedFormat":1},{"version":"1b1a02c54361b8c222392054648a2137fc5983ad5680134a653b1d9f655fe43d","impliedFormat":1},{"version":"8bcb884d06860a129dbffa3500d51116d9d1040bb3bf1c9762eb2f1e7fd5c85c","impliedFormat":1},{"version":"e55c0f31407e1e4eee10994001a4f570e1817897a707655f0bbe4d4a66920e9e","impliedFormat":1},{"version":"a37c2194c586faa8979f50a5c5ca165b0903d31ee62a9fe65e4494aa099712c0","impliedFormat":1},{"version":"6602339ddc9cd7e54261bda0e70fb356d9cdc10e3ec7feb5fa28982f8a4d9e34","impliedFormat":1},{"version":"7ffaa736b8a04b0b8af66092da536f71ef13a5ef0428c7711f32b94b68f7c8c8","impliedFormat":1},{"version":"7b4930d666bbe5d10a19fcc8f60cfa392d3ad3383b7f61e979881d2c251bc895","impliedFormat":1},{"version":"46342f04405a2be3fbfb5e38fe3411325769f14482b8cd48077f2d14b64abcfb","impliedFormat":1},{"version":"8fa675c4f44e6020328cf85fdf25419300f35d591b4f56f56e00f9d52b6fbb3b","impliedFormat":1},{"version":"ba98f23160cfa6b47ee8072b8f54201f21a1ee9addc2ef461ebadf559fe5c43a","impliedFormat":1},{"version":"45a4591b53459e21217dc9803367a651e5a1c30358a015f27de0b3e719db816b","impliedFormat":1},{"version":"9ef22bee37885193b9fae7f4cad9502542c12c7fe16afe61e826cdd822643d84","impliedFormat":1},{"version":"b0451895b894c102eed19d50bd5fcb3afd116097f77a7d83625624fafcca8939","impliedFormat":1},{"version":"bce17120b679ff4f1be70f5fe5c56044e07ed45f1e555db6486c6ded8e1da1c8","impliedFormat":1},{"version":"7590477bfa2e309e677ff7f31cb466f377fcd0e10a72950439c3203175309958","impliedFormat":1},{"version":"3f9ebd554335d2c4c4e7dc67af342d37dc8f2938afa64605d8a93236022cc8a5","impliedFormat":1},{"version":"1c077c9f6c0bc02a36207994a6e92a8fbf72d017c4567f640b52bf32984d2392","impliedFormat":1},{"version":"600b42323925b32902b17563654405968aa12ee39e665f83987b7759224cc317","impliedFormat":1},{"version":"32c8f85f6b4e145537dfe61b94ddd98b47dbdd1d37dc4b7042a8d969cd63a1aa","impliedFormat":1},{"version":"2426ed0e9982c3d734a6896b697adf5ae93d634b73eb15b48da8106634f6d911","impliedFormat":1},{"version":"057431f69d565fb44c246f9f64eac09cf309a9af7afb97e588ebef19cc33c779","impliedFormat":1},{"version":"960d026ca8bf27a8f7a3920ee50438b50ec913d635aa92542ca07558f9c59eca","impliedFormat":1},{"version":"71f5d895cc1a8a935c40c070d3d0fade53ae7e303fd76f443b8b541dee19a90c","impliedFormat":1},{"version":"252eb4750d0439d1674ad0dc30d2a2a3e4655e08ad9e58a7e236b21e78d1d540","impliedFormat":1},{"version":"e344b4a389bb2dfa98f144f3f195387a02b6bdb69deed4a96d16cc283c567778","impliedFormat":1},{"version":"c6cdcd12d577032b84eed1de4d2de2ae343463701a25961b202cff93989439fb","impliedFormat":1},{"version":"203d75f653988a418930fb16fda8e84dea1fac7e38abdaafd898f257247e0860","impliedFormat":1},{"version":"c5b3da7e2ecd5968f723282aba49d8d1a2e178d0afe48998dad93f81e2724091","impliedFormat":1},{"version":"efd2860dc74358ffa01d3de4c8fa2f966ae52c13c12b41ad931c078151b36601","impliedFormat":1},{"version":"09acacae732e3cc67a6415026cfae979ebe900905500147a629837b790a366b3","impliedFormat":1},{"version":"f7b622759e094a3c2e19640e0cb233b21810d2762b3e894ef7f415334125eb22","impliedFormat":1},{"version":"99236ea5c4c583082975823fd19bcce6a44963c5c894e20384bc72e7eccf9b03","impliedFormat":1},{"version":"f6688a02946a3f7490aa9e26d76d1c97a388e42e77388cbab010b69982c86e9e","impliedFormat":1},{"version":"9f642953aba68babd23de41de85d4e97f0c39ef074cb8ab8aa7d55237f62aff6","impliedFormat":1},{"version":"4e171e0e0f32ea726e69fa33b816150d1886f0fa9fc2aa2584af85bf3e586bbc","impliedFormat":1},{"version":"2d2ec3235e01474f45a68f28cf826c2f5228b79f7d474d12ca3604cdcfdac80c","impliedFormat":1},{"version":"6dd249868034c0434e170ba6e0451d67a0c98e5a74fd57a7999174ee22a0fa7b","impliedFormat":1},{"version":"9716553c72caf4ff992be810e650707924ec6962f6812bd3fbdb9ac3544fd38f","impliedFormat":1},{"version":"506bc8f4d2d639bebb120e18d3752ddeee11321fd1070ad2ce05612753c628d6","impliedFormat":1},{"version":"053c51bbc32db54be396654ab5ecd03a66118d64102ac9e22e950059bc862a5e","impliedFormat":1},{"version":"1977f62a560f3b0fc824281fd027a97ce06c4b2d47b408f3a439c29f1e9f7e10","impliedFormat":1},{"version":"627570f2487bd8d899dd4f36ecb20fe0eb2f8c379eff297e24caba0c985a6c43","impliedFormat":1},{"version":"0f6e0b1a1deb1ab297103955c8cd3797d18f0f7f7d30048ae73ba7c9fb5a1d89","impliedFormat":1},{"version":"0a051f254f9a16cdde942571baab358018386830fed9bdfff42478e38ba641ce","impliedFormat":1},{"version":"17269f8dfc30c4846ab7d8b5d3c97ac76f50f33de96f996b9bf974d817ed025b","impliedFormat":1},{"version":"9e82194af3a7d314ccbc64bb94bfb62f4bfea047db3422a7f6c5caf2d06540a9","impliedFormat":1},{"version":"083d6f3547ccbf25dfa37b950c50bee6691ed5c42107f038cc324dbca1e173ae","impliedFormat":1},{"version":"952a9eab21103b79b7a6cca8ad970c3872883aa71273f540285cad360c35da40","impliedFormat":1},{"version":"8ba48776335db39e0329018c04486907069f3d7ee06ce8b1a6134b7d745271cc","impliedFormat":1},{"version":"e6d5809e52ed7ef1860d1c483e005d1f71bab36772ef0fd80d5df6db1da0e815","impliedFormat":1},{"version":"893e5cfbae9ed690b75b8b2118b140665e08d182ed8531e1363ec050905e6cb2","impliedFormat":1},{"version":"6ae7c7ada66314a0c3acfbf6f6edf379a12106d8d6a1a15bd35bd803908f2c31","impliedFormat":1},{"version":"e4b1e912737472765e6d2264b8721995f86a463a1225f5e2a27f783ecc013a7b","impliedFormat":1},{"version":"97146bbe9e6b1aab070510a45976faaf37724c747a42d08563aeae7ba0334b4f","impliedFormat":1},{"version":"c40d552bd2a4644b0617ec2f0f1c58618a25d098d2d4aa7c65fb446f3c305b54","impliedFormat":1},{"version":"09e64dea2925f3a0ef972d7c11e7fa75fec4c0824e9383db23eacf17b368532f","impliedFormat":1},{"version":"424ddba00938bb9ae68138f1d03c669f43556fc3e9448ed676866c864ca3f1d6","impliedFormat":1},{"version":"a0fe12181346c8404aab9d9a938360133b770a0c08b75a2fce967d77ca4b543f","impliedFormat":1},{"version":"3cc6eb7935ff45d7628b93bb6aaf1a32e8cb3b24287f9e75694b607484b377b3","impliedFormat":1},{"version":"ced02e78a2e10f89f4d70440d0a8de952a5946623519c54747bc84214d644bac","impliedFormat":1},{"version":"efd463021ccc91579ed8ae62584176baab2cd407c555c69214152480531a2072","impliedFormat":1},{"version":"29647c3b79320cfeecb5862e1f79220e059b26db2be52ea256df9cf9203fb401","impliedFormat":1},{"version":"e8cdefd2dc293cb4866ee8f04368e7001884650bb0f43357c4fe044cc2e1674f","impliedFormat":1},{"version":"582a3578ebba9238eb0c5d30b4d231356d3e8116fea497119920208fb48ccf85","impliedFormat":1},{"version":"185eae4a1e8a54e38f36cd6681cfa54c975a2fc3bc2ba6a39bf8163fac85188d","impliedFormat":1},{"version":"0c0a02625cf59a0c7be595ccc270904042bea523518299b754c705f76d2a6919","impliedFormat":1},{"version":"c44fc1bbdb5d1c8025073cb7c5eab553aa02c069235a1fc4613cd096d578ab80","impliedFormat":1},{"version":"cee72255e129896f0240ceb58c22e207b83d2cc81d8446190d1b4ef9b507ccd6","impliedFormat":1},{"version":"3b54670e11a8d3512f87e46645aa9c83ae93afead4a302299a192ac5458aa586","impliedFormat":1},{"version":"c2fc4d3a130e9dc0e40f7e7d192ef2494a39c37da88b5454c8adf143623e5979","impliedFormat":1},{"version":"2e693158fc1eedba3a5766e032d3620c0e9c8ad0418e4769be8a0f103fdb52cd","impliedFormat":1},{"version":"516275ccf3e66dc391533afd4d326c44dd750345b68bb573fc592e4e4b74545f","impliedFormat":1},{"version":"07c342622568693847f6cb898679402dd19740f815fd43bec996daf24a1e2b85","impliedFormat":1},{"version":"4d9bffaca7e0f0880868bab5fd351f9e4d57fcc6567654c4c330516fea7932aa","impliedFormat":1},{"version":"b42201db6adb94eeee965e8b8a5c24ce4a3fe78ebb89bbfd2d94bf2897af5134","impliedFormat":1},{"version":"89968316b7069339433bd42d53fe56df98b6990783dfe00c9513fb4bd01c2a1c","impliedFormat":1},{"version":"a4096686f982f6977433ee9759ecbef49da29d7e6a5d8278f0fbc7b9f70fce12","impliedFormat":1},{"version":"62e62a477c56cda719013606616dd856cfdc37c60448d0feb53654860d3113bb","impliedFormat":1},{"version":"207c107dd2bd23fa9febac2fe05c7c72cdac02c3f57003ab2e1c6794a6db0c05","impliedFormat":1},{"version":"55133e906c4ddabecdfcbc6a2efd4536a3ac47a8fa0a3fe6d0b918cac882e0d4","impliedFormat":1},{"version":"2147f8d114cf58c05106c3dccea9924d069c69508b5980ed4011d2b648af2ffe","impliedFormat":1},{"version":"2eb4012a758b9a7ba9121951d7c4b9f103fe2fc626f13bec3e29037bb9420dc6","impliedFormat":1},{"version":"fe61f001bd4bd0a374daa75a2ba6d1bb12c849060a607593a3d9a44e6b1df590","impliedFormat":1},{"version":"cfe8221c909ad721b3da6080570553dea2f0e729afbdbcf2c141252cf22f39b5","impliedFormat":1},{"version":"34e89249b6d840032b9acdec61d136877f84f2cd3e3980355b8a18f119809956","impliedFormat":1},{"version":"6f36ff8f8a898184277e7c6e3bf6126f91c7a8b6a841f5b5e6cb415cfc34820e","impliedFormat":1},{"version":"4b6378c9b1b3a2521316c96f5c777e32a1b14d05b034ccd223499e26de8a379c","impliedFormat":1},{"version":"07be5ae9bf5a51f3d98ffcfacf7de2fe4842a7e5016f741e9fad165bb929be93","impliedFormat":1},{"version":"cb1b37eda1afc730d2909a0f62cac4a256276d5e62fea36db1473981a5a65ab1","impliedFormat":1},{"version":"195f855b39c8a6e50eb1f37d8f794fbd98e41199dffbc98bf629506b6def73d7","impliedFormat":1},{"version":"471386a0a7e4eb88c260bdde4c627e634a772bf22f830c4ec1dad823154fd6f5","impliedFormat":1},{"version":"108314a60f3cb2454f2d889c1fb8b3826795399e5d92e87b2918f14d70c01e69","impliedFormat":1},{"version":"d75cc838286d6b1260f0968557cd5f28495d7341c02ac93989fb5096deddfb47","impliedFormat":1},{"version":"d531dc11bb3a8a577bd9ff83e12638098bfc9e0856b25852b91aac70b0887f2a","impliedFormat":1},{"version":"19968b998a2ab7dfd39de0c942fc738b2b610895843fec25477bc393687babd8","impliedFormat":1},{"version":"c0e6319f0839d76beed6e37b45ec4bb80b394d836db308ae9db4dea0fe8a9297","impliedFormat":1},{"version":"1a7b11be5c442dab3f4af9faf20402798fddf1d3c904f7b310f05d91423ba870","impliedFormat":1},{"version":"079d3f1ddcaf6c0ff28cfc7851b0ce79fcd694b3590afa6b8efa6d1656216924","impliedFormat":1},{"version":"2c817fa37b3d2aa72f01ce4d3f93413a7fbdecafe1b9fb7bd7baaa1bbd46eb08","impliedFormat":1},{"version":"682203aed293a0986cc2fccc6321d862742b48d7359118ac8f36b290d28920d2","impliedFormat":1},{"version":"7406d75a4761b34ce126f099eafe6643b929522e9696e5db5043f4e5c74a9e40","impliedFormat":1},{"version":"7e9c4e62351e3af1e5e49e88ebb1384467c9cd7a03c132a3b96842ccdc8045c4","impliedFormat":1},{"version":"ea1f9c60a912065c08e0876bd9500e8fa194738855effb4c7962f1bfb9b1da86","impliedFormat":1},{"version":"903f34c920e699dacbc483780b45d1f1edcb1ebf4b585a999ece78e403bb2db3","impliedFormat":1},{"version":"100ebfd0470433805c43be5ae377b7a15f56b5d7181c314c21789c4fe9789595","impliedFormat":1},{"version":"12533f60d36d03d3cf48d91dc0b1d585f530e4c9818a4d695f672f2901a74a86","impliedFormat":1},{"version":"21d9968dad7a7f021080167d874b718197a60535418e240389d0b651dd8110e7","impliedFormat":1},{"version":"2ef7349b243bce723d67901991d5ad0dfc534da994af61c7c172a99ff599e135","impliedFormat":1},{"version":"fa103f65225a4b42576ae02d17604b02330aea35b8aaf889a8423d38c18fa253","impliedFormat":1},{"version":"1b9173f64a1eaee88fa0c66ab4af8474e3c9741e0b0bd1d83bfca6f0574b6025","impliedFormat":1},{"version":"1b212f0159d984162b3e567678e377f522d7bee4d02ada1cc770549c51087170","impliedFormat":1},{"version":"46bd71615bdf9bfa8499b9cfce52da03507f7140c93866805d04155fa19caa1b","impliedFormat":1},{"version":"86cb49eb242fe19c5572f58624354ffb8743ff0f4522428ebcabc9d54a837c73","impliedFormat":1},{"version":"fc2fb9f11e930479d03430ee5b6588c3788695372b0ab42599f3ec7e78c0f6d5","impliedFormat":1},{"version":"bb1e5cf70d99c277c9f1fe7a216b527dd6bd2f26b307a8ab65d24248fb3319f5","impliedFormat":1},{"version":"817547eacf93922e22570ba411f23e9164544dead83e379c7ae9c1cfc700c2cf","impliedFormat":1},{"version":"a728478cb11ab09a46e664c0782610d7dd5c9db3f9a249f002c92918ca0308f7","impliedFormat":1},{"version":"9e91ef9c3e057d6d9df8bcbfbba0207e83ef9ab98aa302cf9223e81e32fdfe8d","impliedFormat":1},{"version":"66d30ef7f307f95b3f9c4f97e6c1a5e4c462703de03f2f81aca8a1a2f8739dbd","impliedFormat":1},{"version":"293ca178fd6c23ed33050052c6544c9d630f9d3b11d42c36aa86218472129243","impliedFormat":1},{"version":"90a4be0e17ba5824558c38c93894e7f480b3adf5edd1fe04877ab56c56111595","impliedFormat":1},{"version":"fadd55cddab059940934df39ce2689d37110cfe37cc6775f06b0e8decf3092d7","impliedFormat":1},{"version":"91324fe0902334523537221b6c0bef83901761cfd3bd1f140c9036fa6710fa2b","impliedFormat":1},{"version":"b4f3b4e20e2193179481ab325b8bd0871b986e1e8a8ed2961ce020c2dba7c02d","impliedFormat":1},{"version":"41744c67366a0482db029a21f0df4b52cd6f1c85cbc426b981b83b378ccb6e65","impliedFormat":1},{"version":"c3f3cf7561dd31867635c22f3c47c8491af4cfa3758c53e822a136828fc24e5d","impliedFormat":1},{"version":"a88ddea30fae38aa071a43b43205312dc5ff86f9e21d85ba26b14690dc19d95e","impliedFormat":1},{"version":"b5b2d0510e5455234016bbbaba3839ca21adbc715d1b9c3d6dede7d411a28545","impliedFormat":1},{"version":"5515f17f45c6aafe6459afa3318bba040cb466a8d91617041566808a5fd77a44","impliedFormat":1},{"version":"4df1f0c17953b0450aa988c9930061f8861b114e1649e1a16cfd70c5cbdf8d83","impliedFormat":1},{"version":"441104b363d80fe57eb79a50d495e0b7e3ebeb45a5f0d1a4067d71ef75e8fbfa","impliedFormat":1},{"version":"b6e995b5ef6661f5636ff738e67e4ec90150768ef119ad74b473c404304408a1","impliedFormat":1},{"version":"5d470930bf6142d7cbda81c157869024527dc7911ba55d90b8387ef6e1585aa1","impliedFormat":1},{"version":"074483fdbf20b30bd450e54e6892e96ea093430c313e61be5fdfe51588baa2d6","impliedFormat":1},{"version":"b7e6a6a3495301360edb9e1474702db73d18be7803b3f5c6c05571212acccd16","impliedFormat":1},{"version":"aa7527285c94043f21baf6e337bc60a92c20b6efaa90859473f6476954ac5f79","impliedFormat":1},{"version":"dd3be6d9dcd79e46d192175a756546630f2dc89dab28073823c936557b977f26","impliedFormat":1},{"version":"8d0566152618a1da6536c75a5659c139522d67c63a9ae27e8228d76ab0420584","impliedFormat":1},{"version":"ba06bf784edafe0db0e2bd1f6ecf3465b81f6b1819871bf190a0e0137b5b7f18","impliedFormat":1},{"version":"a0500233cb989bcb78f5f1a81f51eabc06b5c39e3042c560a7489f022f1f55a3","impliedFormat":1},{"version":"220508b3fb6b773f49d8fb0765b04f90ef15caacf0f3d260e3412ed38f71ef09","impliedFormat":1},{"version":"1ad113089ad5c188fec4c9a339cb53d1bcbb65682407d6937557bb23a6e1d4e5","impliedFormat":1},{"version":"e56427c055602078cbf0e58e815960541136388f4fc62554813575508def98b6","impliedFormat":1},{"version":"1f58b0676a80db38df1ce19d15360c20ce9e983b35298a5d0b4aa4eb4fb67e0f","impliedFormat":1},{"version":"3d67e7eb73c6955ee27f1d845cae88923f75c8b0830d4b5440eea2339958e8ec","impliedFormat":1},{"version":"11fec302d58b56033ab07290a3abc29e9908e29d504db9468544b15c4cd7670d","impliedFormat":1},{"version":"c66d6817c931633650edf19a8644eea61aeeb84190c7219911cefa8ddea8bd9a","impliedFormat":1},{"version":"ab1359707e4fc610c5f37f1488063af65cda3badca6b692d44b95e8380e0f6c2","impliedFormat":1},{"version":"37deda160549729287645b3769cf126b0a17e7e2218737352676705a01d5957e","impliedFormat":1},{"version":"d80ffdd55e7f4bc69cde66933582b8592d3736d3b0d1d8cc63995a7b2bcca579","impliedFormat":1},{"version":"c9b71952b2178e8737b63079dba30e1b29872240b122905cbaba756cb60b32f5","impliedFormat":1},{"version":"b596585338b0d870f0e19e6b6bcbf024f76328f2c4f4e59745714e38ee9b0582","impliedFormat":1},{"version":"e6717fc103dfa1635947bf2b41161b5e4f2fabbcaf555754cc1b4340ec4ca587","impliedFormat":1},{"version":"c36186d7bdf1f525b7685ee5bf639e4b157b1e803a70c25f234d4762496f771f","impliedFormat":1},{"version":"026726932a4964341ab8544f12b912c8dfaa388d2936b71cc3eca0cffb49cc1d","impliedFormat":1},{"version":"83188d037c81bd27076218934ba9e1742ddb69cd8cc64cdb8a554078de38eb12","impliedFormat":1},{"version":"7d82f2d6a89f07c46c7e3e9071ab890124f95931d9c999ba8f865fa6ef6cbf72","impliedFormat":1},{"version":"4fc523037d14d9bb6ddb586621a93dd05b6c6d8d59919a40c436ca3ac29d9716","impliedFormat":1},"f9944ba0510604ab1539d3e3e338db432fe17e0a2d676bcefcf68498574b10a2",{"version":"c868f50837eedd81fa9f61bd42de6665f74e7eb7a459135c6a14ac33ddc86798","impliedFormat":1},{"version":"56b2090352084289a1d572dfbddeed948906c0a0317a547ceb0ae6436ae44037","impliedFormat":1},"0bf72bb50c325bb7a34e3358d618586f6bec13b2e87f016a52ab4b5e5cba9199",{"version":"dc4632e1da925e1a3eeacd5db6e32082c107c7804860beb686c8b6e841635ca6","affectsGlobalScope":true},{"version":"b57c53cb106bd452d3732ec1a4b06b740ce838abc5520563fceefd021f24e271","signature":"fc296c707597de12bd3da7fe9b1a4686ac1ecb48a5d4af882e068b3cb5d78dfe"},"74fc94583f9e25f5ffba23bfc0a93da8331e4c4650da21e61e1511193054e68d","cb12b59fd4a2b55b79ec1e15f3ad88be23373d4f39036f8deb5bb40e97df2130",{"version":"12c2f266755c2466d4881d7c3b1320fe5dfacc86f28e3b8f7fdb3339cd63a69b","signature":"8cd66d5b093e5de755168c7e63768bc20946b3919982c03cbec317de9e9450b6"},{"version":"ac3ba230499e32e6f47cb73237b56a4c6ace5d8fa8b26e36eddec8bc8cc6ce39","signature":"65596c43be58182c06ad00a3a92ebf91420ed04b9e65b2efe3418747342e307c"},{"version":"70521b6ab0dcba37539e5303104f29b721bfb2940b2776da4cc818c07e1fefc1","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab41ef1f2cdafb8df48be20cd969d875602483859dc194e9c97c8a576892c052","affectsGlobalScope":true,"impliedFormat":1},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true,"impliedFormat":1},{"version":"21d819c173c0cf7cc3ce57c3276e77fd9a8a01d35a06ad87158781515c9a438a","impliedFormat":1},{"version":"a79e62f1e20467e11a904399b8b18b18c0c6eea6b50c1168bf215356d5bebfaf","affectsGlobalScope":true,"impliedFormat":1},{"version":"49a5a44f2e68241a1d2bd9ec894535797998841c09729e506a7cbfcaa40f2180","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e9c23ba78aabc2e0a27033f18737a6df754067731e69dc5f52823957d60a4b6","impliedFormat":1},{"version":"5929864ce17fba74232584d90cb721a89b7ad277220627cc97054ba15a98ea8f","impliedFormat":1},{"version":"763fe0f42b3d79b440a9b6e51e9ba3f3f91352469c1e4b3b67bfa4ff6352f3f4","impliedFormat":1},{"version":"25c8056edf4314820382a5fdb4bb7816999acdcb929c8f75e3f39473b87e85bc","impliedFormat":1},{"version":"c464d66b20788266e5353b48dc4aa6bc0dc4a707276df1e7152ab0c9ae21fad8","impliedFormat":1},{"version":"78d0d27c130d35c60b5e5566c9f1e5be77caf39804636bc1a40133919a949f21","impliedFormat":1},{"version":"c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","impliedFormat":1},{"version":"1d6e127068ea8e104a912e42fc0a110e2aa5a66a356a917a163e8cf9a65e4a75","impliedFormat":1},{"version":"5ded6427296cdf3b9542de4471d2aa8d3983671d4cac0f4bf9c637208d1ced43","impliedFormat":1},{"version":"7f182617db458e98fc18dfb272d40aa2fff3a353c44a89b2c0ccb3937709bfb5","impliedFormat":1},{"version":"cadc8aced301244057c4e7e73fbcae534b0f5b12a37b150d80e5a45aa4bebcbd","impliedFormat":1},{"version":"385aab901643aa54e1c36f5ef3107913b10d1b5bb8cbcd933d4263b80a0d7f20","impliedFormat":1},{"version":"9670d44354bab9d9982eca21945686b5c24a3f893db73c0dae0fd74217a4c219","impliedFormat":1},{"version":"0b8a9268adaf4da35e7fa830c8981cfa22adbbe5b3f6f5ab91f6658899e657a7","impliedFormat":1},{"version":"11396ed8a44c02ab9798b7dca436009f866e8dae3c9c25e8c1fbc396880bf1bb","impliedFormat":1},{"version":"ba7bc87d01492633cb5a0e5da8a4a42a1c86270e7b3d2dea5d156828a84e4882","impliedFormat":1},{"version":"4893a895ea92c85345017a04ed427cbd6a1710453338df26881a6019432febdd","impliedFormat":1},{"version":"c21dc52e277bcfc75fac0436ccb75c204f9e1b3fa5e12729670910639f27343e","impliedFormat":1},{"version":"13f6f39e12b1518c6650bbb220c8985999020fe0f21d818e28f512b7771d00f9","impliedFormat":1},{"version":"9b5369969f6e7175740bf51223112ff209f94ba43ecd3bb09eefff9fd675624a","impliedFormat":1},{"version":"4fe9e626e7164748e8769bbf74b538e09607f07ed17c2f20af8d680ee49fc1da","impliedFormat":1},{"version":"24515859bc0b836719105bb6cc3d68255042a9f02a6022b3187948b204946bd2","impliedFormat":1},{"version":"ea0148f897b45a76544ae179784c95af1bd6721b8610af9ffa467a518a086a43","impliedFormat":1},{"version":"24c6a117721e606c9984335f71711877293a9651e44f59f3d21c1ea0856f9cc9","impliedFormat":1},{"version":"dd3273ead9fbde62a72949c97dbec2247ea08e0c6952e701a483d74ef92d6a17","impliedFormat":1},{"version":"405822be75ad3e4d162e07439bac80c6bcc6dbae1929e179cf467ec0b9ee4e2e","impliedFormat":1},{"version":"0db18c6e78ea846316c012478888f33c11ffadab9efd1cc8bcc12daded7a60b6","impliedFormat":1},{"version":"e61be3f894b41b7baa1fbd6a66893f2579bfad01d208b4ff61daef21493ef0a8","impliedFormat":1},{"version":"bd0532fd6556073727d28da0edfd1736417a3f9f394877b6d5ef6ad88fba1d1a","impliedFormat":1},{"version":"89167d696a849fce5ca508032aabfe901c0868f833a8625d5a9c6e861ef935d2","impliedFormat":1},{"version":"615ba88d0128ed16bf83ef8ccbb6aff05c3ee2db1cc0f89ab50a4939bfc1943f","impliedFormat":1},{"version":"a4d551dbf8746780194d550c88f26cf937caf8d56f102969a110cfaed4b06656","impliedFormat":1},{"version":"8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","impliedFormat":1},{"version":"317e63deeb21ac07f3992f5b50cdca8338f10acd4fbb7257ebf56735bf52ab00","impliedFormat":1},{"version":"4732aec92b20fb28c5fe9ad99521fb59974289ed1e45aecb282616202184064f","impliedFormat":1},{"version":"2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","impliedFormat":1},{"version":"c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","impliedFormat":1},{"version":"bf67d53d168abc1298888693338cb82854bdb2e69ef83f8a0092093c2d562107","impliedFormat":1},{"version":"1ca84b44ad1d8e4576f24904d8b95dd23b94ea67e1575f89614ac90062fc67f4","affectsGlobalScope":true,"impliedFormat":1},{"version":"6d586db0a09a9495ebb5dece28f54df9684bfbd6e1f568426ca153126dac4a40","impliedFormat":1},{"version":"7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","impliedFormat":1},{"version":"8c0bcd6c6b67b4b503c11e91a1fb91522ed585900eab2ab1f61bba7d7caa9d6f","impliedFormat":1},{"version":"567b7f607f400873151d7bc63a049514b53c3c00f5f56e9e95695d93b66a138e","affectsGlobalScope":true,"impliedFormat":1},{"version":"f3e58c4c18a031cbb17abec7a4ad0bd5ae9fc70c1f4ba1e7fb921ad87c504aca","impliedFormat":1},{"version":"84c1930e33d1bb12ad01bcbe11d656f9646bd21b2fb2afd96e8e10615a021aef","impliedFormat":1},{"version":"35ec8b6760fd7138bbf5809b84551e31028fb2ba7b6dc91d95d098bf212ca8b4","affectsGlobalScope":true,"impliedFormat":1},{"version":"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a","impliedFormat":1},{"version":"4b87f767c7bc841511113c876a6b8bf1fd0cb0b718c888ad84478b372ec486b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d04e3640dd9eb67f7f1e5bd3d0bf96c784666f7aefc8ac1537af6f2d38d4c29","impliedFormat":1},{"version":"9d19808c8c291a9010a6c788e8532a2da70f811adb431c97520803e0ec649991","impliedFormat":1},{"version":"2bf469abae4cc9c0f340d4e05d9d26e37f936f9c8ca8f007a6534f109dcc77e4","impliedFormat":1},{"version":"4aacb0dd020eeaef65426153686cc639a78ec2885dc72ad220be1d25f1a439df","impliedFormat":1},{"version":"f0bd7e6d931657b59605c44112eaf8b980ba7f957a5051ed21cb93d978cf2f45","impliedFormat":1},{"version":"71450bbc2d82821d24ca05699a533e72758964e9852062c53b30f31c36978ab8","affectsGlobalScope":true,"impliedFormat":1},{"version":"0ada07543808f3b967624645a8e1ccd446f8b01ade47842acf1328aec899fed0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4c21aaa8257d7950a5b75a251d9075b6a371208fc948c9c8402f6690ef3b5b55","impliedFormat":1},{"version":"b5895e6353a5d708f55d8685c38a235c3a6d8138e374dee8ceb8ffde5aa8002a","impliedFormat":1},{"version":"b76cc102b903161a152821ed3e09c2a32d678b2a1d196dabc15cfb92c53a4fd0","impliedFormat":1},{"version":"de735eca2c51dd8b860254e9fdb6d9ec19fe402dfe597c23090841ce3937cfc5","impliedFormat":1},{"version":"4ff41188773cbf465807dd2f7059c7494cbee5115608efc297383832a1150c43","impliedFormat":1},{"version":"5650cf3dace09e7c25d384e3e6b818b938f68f4e8de96f52d9c5a1b3db068e86","impliedFormat":1},{"version":"1354ca5c38bd3fd3836a68e0f7c9f91f172582ba30ab15bb8c075891b91502b7","affectsGlobalScope":true,"impliedFormat":1},{"version":"5155da3047ef977944d791a2188ff6e6c225f6975cc1910ab7bb6838ab84cede","impliedFormat":1},{"version":"93f437e1398a4f06a984f441f7fa7a9f0535c04399619b5c22e0b87bdee182cb","impliedFormat":1},{"version":"afbe24ab0d74694372baa632ecb28bb375be53f3be53f9b07ecd7fc994907de5","impliedFormat":1},{"version":"e16d218a30f6a6810b57f7e968124eaa08c7bb366133ea34bbf01e7cd6b8c0ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb8692dea24c27821f77e397272d9ed2eda0b95e4a75beb0fdda31081d15a8ae","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e043a1bc8fbf2a255bccf9bf27e0f1caf916c3b0518ea34aa72357c0afd42ec","impliedFormat":1},{"version":"b4f70ec656a11d570e1a9edce07d118cd58d9760239e2ece99306ee9dfe61d02","impliedFormat":1},{"version":"3bc2f1e2c95c04048212c569ed38e338873f6a8593930cf5a7ef24ffb38fc3b6","impliedFormat":1},{"version":"8145e07aad6da5f23f2fcd8c8e4c5c13fb26ee986a79d03b0829b8fce152d8b2","impliedFormat":1},{"version":"f9d9d753d430ed050dc1bf2667a1bab711ccbb1c1507183d794cc195a5b085cc","impliedFormat":1},{"version":"9eece5e586312581ccd106d4853e861aaaa1a39f8e3ea672b8c3847eedd12f6e","impliedFormat":1},{"version":"5b6844ad931dcc1d3aca53268f4bd671428421464b1286746027aede398094f2","impliedFormat":1},{"version":"37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","impliedFormat":1},{"version":"125d792ec6c0c0f657d758055c494301cc5fdb327d9d9d5960b3f129aff76093","impliedFormat":1},{"version":"0dbcebe2126d03936c70545e96a6e41007cf065be38a1ce4d32a39fcedefead4","affectsGlobalScope":true,"impliedFormat":1},{"version":"1851a3b4db78664f83901bb9cac9e45e03a37bb5933cc5bf37e10bb7e91ab4eb","impliedFormat":1},{"version":"461e54289e6287e8494a0178ba18182acce51a02bca8dea219149bf2cf96f105","impliedFormat":1},{"version":"12ed4559eba17cd977aa0db658d25c4047067444b51acfdcbf38470630642b23","affectsGlobalScope":true,"impliedFormat":1},{"version":"f3ffabc95802521e1e4bcba4c88d8615176dc6e09111d920c7a213bdda6e1d65","impliedFormat":1},{"version":"e31e51c55800014d926e3f74208af49cb7352803619855c89296074d1ecbb524","impliedFormat":1},{"version":"ae56f65caf3be91108707bd8dfbccc2a57a91feb5daabf7165a06a945545ed26","impliedFormat":1},{"version":"a136d5de521da20f31631a0a96bf712370779d1c05b7015d7019a9b2a0446ca9","impliedFormat":1},{"version":"dfb96ba5177b68003deec9e773c47257da5c4c8a74053d8956389d832df72002","affectsGlobalScope":true,"impliedFormat":1},{"version":"92d3070580cf72b4bb80959b7f16ede9a3f39e6f4ef2ac87cfa4561844fdc69f","affectsGlobalScope":true,"impliedFormat":1},{"version":"d3dffd70e6375b872f0b4e152de4ae682d762c61a24881ecc5eb9f04c5caf76f","impliedFormat":1},{"version":"613deebaec53731ff6b74fe1a89f094b708033db6396b601df3e6d5ab0ec0a47","impliedFormat":1},{"version":"d91a7d8b5655c42986f1bdfe2105c4408f472831c8f20cf11a8c3345b6b56c8c","impliedFormat":1},{"version":"e56eb632f0281c9f8210eb8c86cc4839a427a4ffffcfd2a5e40b956050b3e042","affectsGlobalScope":true,"impliedFormat":1},{"version":"e8a979b8af001c9fc2e774e7809d233c8ca955a28756f52ee5dee88ccb0611d2","impliedFormat":1},{"version":"cac793cc47c29e26e4ac3601dcb00b4435ebed26203485790e44f2ad8b6ad847","impliedFormat":1},{"version":"d3f2d715f57df3f04bf7b16dde01dec10366f64fce44503c92b8f78f614c1769","impliedFormat":1},{"version":"b78cd10245a90e27e62d0558564f5d9a16576294eee724a59ae21b91f9269e4a","impliedFormat":1},{"version":"baac9896d29bcc55391d769e408ff400d61273d832dd500f21de766205255acb","impliedFormat":1},{"version":"2f5747b1508ccf83fad0c251ba1e5da2f5a30b78b09ffa1cfaf633045160afed","impliedFormat":1},{"version":"86ea91bfa7fef1eeb958056f30f1db4e0680bc9b5132e5e9d6e9cfd773c0c4fd","affectsGlobalScope":true,"impliedFormat":1},{"version":"b71c603a539078a5e3a039b20f2b0a0d1708967530cf97dec8850a9ca45baa2b","impliedFormat":1},{"version":"0e13570a7e86c6d83dd92e81758a930f63747483e2cd34ef36fcdb47d1f9726a","impliedFormat":1},{"version":"104c67f0da1bdf0d94865419247e20eded83ce7f9911a1aa75fc675c077ca66e","impliedFormat":1},{"version":"cc0d0b339f31ce0ab3b7a5b714d8e578ce698f1e13d7f8c60bfb766baeb1d35c","impliedFormat":1},{"version":"d26a79f97f25eb1c5fc36a8552e4decc7ad11104a016d31b1307c3afaf48feb1","impliedFormat":1},"ffe874e1471f6b4f5edbc5bc58333e4e56cf7d331f7f4a79bad767b30fb5735c","eb745172d0e9d4cf6249adf1f939f579686ba14a8d1eca1aa98c1885a85ce12c",{"version":"6bfddd55fdcddc427cefdeb66c5caf1aad7f7239f616af29ed240b6d6636d3a4","signature":"0025a2578091a2b8b055cf6e741489ab1153cb01850557d732a995e8014c157b"},"909c56e69bbee9ac086da0875f84c6dd68b360db0756b87a105678e9f060918b",{"version":"0dd07e31c41713d0e5210ebc9c1138ff41830156f749494f0db8bed15681b0ff","signature":"868c46e559354cab02a54d8cace495c98eee2f44f3ad60592480940309194106"},{"version":"05ddd0af615d783818d4a4d600957001bb2a90324508dd1cd130016bee52e407","signature":"49c69658182459e3189fb7d2b28280784f1bd17a55193a6fb9eb562886c125bb"},"42e448fbed271b101dcfe32376a425d3e7b8300bcdca710d0227f0978f85b424",{"version":"2bad09c4dc0810666ef5b6150aa910dd711051ce5f2184050c9859c708092a36","impliedFormat":1},{"version":"eece99a6cf69ff45c5d4f9e0bfb6450f5c57878d048ff01a6a6343cf87e98230","impliedFormat":1},{"version":"f7ab1fe738bbe7fdd1e9bc9887f55ac0d7eda0d234a7eb35c77304430f7d6715","impliedFormat":1},{"version":"7f8ae89a514a3b4634756f64f681d499bae5877a0fe5ed08993c5c88cdb11b3b","impliedFormat":1},{"version":"1a9c0db9d65449e9dbcbf23baa3b8bfa48806cddb2adc5e172eb8eff5afbb702","impliedFormat":1},{"version":"477cd964b00a7fdc34d22c81ca062572d9401bcd9540d954ab2bee4ae65e4605","impliedFormat":1},{"version":"6586eacd77a813c50d7d2be05e91295989365204d095463ca8c9dfb8caac222d","impliedFormat":1},{"version":"3f2b3c5d3f5fd9e254046b9bf83da37babd1935776c97a5ffc1acfce0da0081e","impliedFormat":1},{"version":"8f1241f5d9f0d3d72117768b3c974e462840fbd85026fb66685078945404cf2f","impliedFormat":1},"79394bc0251170c0860ab079e5f921ebe52464437377e1c52c88374b3fc654a8",{"version":"8409276031acc0f8b214efac3ba951c27025e1e617d338d1f7b1a840bdf6db89","signature":"d45b2588e6727acd6b8c59e7b1790b34761f9de9667a5155b74674a923c2479c"},{"version":"6b1417593fc5eb1050acd8fd6b11191b3ac3a7eb63c32b5ebb76c17f56ed29de","signature":"4935eec5faabb3529b23d1633ec3ec1925b83352532d92e89e9334ced3c0dfd8"},"2e8e41808d85097fc2c5e654de3d78e713d3d9310ec706e00257cdd4982302bb",{"version":"4f978d4f299c7d2014432d5c3244e77d54471ffff50371735bb0117baa2bd28c","signature":"0529292d9763ea410a482da3134375895e664a822e2bb200eaae1896d893b1a2"},"7878723b4f18c542f90079c6e07a43f3d599016f7e84aa909d998b9679230481","9dcb01340178544e5b9800334c4902d2612808c337849d267458782d2a6a19c0",{"version":"24ec3b9aa29470a3a262587ebc9dd28e6b2355c24f6f28f7607475ef6e5601ee","signature":"1df8600d2ec1a8a84891a07e9cb8b60f6b5d1e70aeb5d096023ac9ed4bfa8887"},{"version":"a91d6b685cb832dc446809d13a00489d9446e502b73ad83f5f05b0299c744b97","signature":"506bf8da86ce7adfa6b373b2924c84bc2f32c34ea3e6ce47c9b13b4e5cf958c3"},{"version":"abd6ccdaae9905ea2ec85488fdce744930862327633eebd40d429511f6a1d5da","impliedFormat":1},{"version":"4669b2a774cd3e5fbe0760dfe8b02b31f9301b5a3fefba896bca3cd4de334708","impliedFormat":1},{"version":"7c14e702387296711c1a829bc95052ff02f533d4aa27d53cc0186c795094a3a9","impliedFormat":1},{"version":"4c72d080623b3dcd8ebd41f38f7ac7804475510449d074ca9044a1cbe95517ae","impliedFormat":1},{"version":"579f8828da42ae02db6915a0223d23b0da07157ff484fecdbf8a96fffa0fa4df","impliedFormat":1},{"version":"279f097303c870a7ce213952224f7a66ae511741299e683e500f63646f6ebf08","impliedFormat":1},{"version":"3ae3b86c48ae3b092e5d5548acbf4416b427fed498730c227180b5b1a8aa86e3","impliedFormat":1},{"version":"8f1241f5d9f0d3d72117768b3c974e462840fbd85026fb66685078945404cf2f","impliedFormat":1},{"version":"a45ee7555d019a67fbe092898d1aef0b1d02a9f6679ab84461ff515b4460d706","impliedFormat":99},"348025391adedcf07651b7345347e8548250067f1bd215e7f9ff02cd3f49d83c","4d9e1808fa7ba5da68608dbc6903553fa889995ac4c1cedcebf236aed0a98c43",{"version":"953cbf62815703fa9970c9cfec3c8d033da04a90c2409af6070dcc6858cf6b98","impliedFormat":1},{"version":"68065ce3af3ef8599af8338068cf336be35249eff281ee393186a0ef40db3abf","impliedFormat":1},{"version":"5339f84dfcb7b04aa1c2b4d7713d6128039381447f07abc2e48d36685e2eef44","impliedFormat":1},{"version":"fb35a61a39c933d31b5b2549d906b2c932a1486622958586f662dbd4b2fe72e6","impliedFormat":1},{"version":"24e2728268be1ad2407bab004549d2753a49b2acb0f117a04c4e28ffb3ecdd4f","impliedFormat":1},{"version":"aff159b14eba59afe98a88fe6f57881ba02895fb9763512dda9083497bdcd0e6","impliedFormat":1},{"version":"b6bc775d112a7761a50594fc589aeaa8893c139ffe3db2b4999756e17f367a8d","impliedFormat":1},{"version":"79f8edca4c97e2fa77473df1d8fda43daf4501a4c721af66d389ab771dcff207","impliedFormat":1},{"version":"7ca4605ebe31b24536fbcda17567275c6355c64ef4ac8ed9ff9b19b59adeb2f2","impliedFormat":1},{"version":"26080058b725ac0b480241751255b4391f722263778e84e66a62068705aafd3c","impliedFormat":1},{"version":"46afbf46c3d62eac2afead3a2011d506637bf4f2c05e1fd64bbf7e2bb2947b7c","impliedFormat":1},{"version":"02f634f868780eaaff5e2d3fb4570dac8e7f018a8650bb9a0ac1deb4915df8d1","impliedFormat":1},{"version":"29723e0bc48036a127c3b8874f3abe9b695c56103f685f2b817fc532b8995e33","impliedFormat":1},{"version":"991cf4ed946cdf4c140ccaad45c61fc36a25b238a8fa95af51e93cb20c4b0503","impliedFormat":1},{"version":"81ef252ff5df76bccf7863bb355ccbb8af69f7d1064b3ef87b2b01c30fb2c1f4","impliedFormat":1},{"version":"0f17f5f14a5f53e5709404b5b59fe816eaad15a469412b73330e6f69834234e0","impliedFormat":1},{"version":"01edea77be9c2bef3a5f3fc46324c5e420e5bd72b499c5dec217c91866be5a99","impliedFormat":1},{"version":"39209d2b85d238810ef19ab3905c9498918343bc8f72a1dcae7fc0b08270d9a0","impliedFormat":1},{"version":"92a130d875262e78c581f98faa07c62f4510885df6d98213c72f3b83a1be93c1","impliedFormat":1},{"version":"81e5210420787a1b64b84fbcefe91f3f61e65a7c4221c525d923dd631ef20bd4","impliedFormat":1},{"version":"0aa14ffe353b8bab88046e64a92efa5cd039f095759fe884d188702956e2cba2","impliedFormat":1},{"version":"68d3eee1d509f45625e39ba325a72c6ce1d2116e3d5c3a40f513472e66622e02","impliedFormat":1},{"version":"4e5f1234308de112f09920e0a0b99f35a9780b3abbc13a84445f32a490d0bb87","impliedFormat":1},{"version":"12fdb04c89057414d5bf3a6167828cb745f4097765f416379c747961a4b57d69","impliedFormat":1},{"version":"1df2aba6907be6c325a309485e5417e327ba9afedb86ea493c0574fa3ea995a4","impliedFormat":1},{"version":"2ac33d7f6999e0fb363d1e483d80f087d3e7d712ff6fcc2b4f7b18b5dab92f37","impliedFormat":1},{"version":"0e00d55a00ecd78664a623d02a3cc73cd5cd5074fd0195be57ef1a1f5a9c9305","impliedFormat":1},{"version":"8f1241f5d9f0d3d72117768b3c974e462840fbd85026fb66685078945404cf2f","impliedFormat":1},"2dceeaf9a0db1a12ef4981892be77debe9562cf5409721e5b55bd1292a2c78cd","2cf3407161cb20d34761fa444592ce040125f1815a2d5ba353013050eaab7667",{"version":"4f11cd8d38c92ff4bc80daf537207130f4ed4e85242347b07012a476c0169792","impliedFormat":1},"b796060aa42aa5c5a75519415a8f81247ce287f24668ed182de48ac95e05d67c",{"version":"900493742352bf8650fc291a65206cace75c0db5307bfbaff9513ccf3c4a2485","signature":"cef0484ddec2c8bb71b556618fc354eba5aa822ccbf62492def34739eb47ac3d"},"a5a5c408417a5212521d6fbf414d75ccbd603269ba772c4ccba60286ededfbbf","c193db01e93c77e6c62ae7f889cf7d6ed356ae27eb1a68d75bf6270e58c996e3",{"version":"a3d18d5c5c238b3c2f7dffbdd4a49042356e49ce3ef10868bfb0a7e42b94378a","signature":"b637bae6bcf5a0e9219c36b94460c51e4f63c6ca3720c896f898f790546e0734"},"cb40058dfff280be6d312332b1aeb4aef8d740f78a15e119457ece7e9933c8f6",{"version":"94dfafdbe6b9679ae5bab52d339a8bced0408777beda2a377718b0ba07eb8de5","signature":"46837436ce45f78ac1812c9960710b43875d3fb971d2d9f36f93e4876dfb4f9f"},{"version":"b2cd960353355aea7f3c0c75fc4d78d8a1517c3bac9fc1d30080031ae61fc037","signature":"296a48c21a93a9bf40e95c63b755451d4c7c4cc2c2842a9bcd0b12a2f6299f40"},"30e3091c7063db81a99d2fc30b2e8468c8a6c3691401f62d903ee5ce4d393051",{"version":"8a5f0065bff877a89853ff71e2b4e3ad12d3f2517728a673f65f5b6af253b19e","impliedFormat":99},{"version":"8015bef79c3b9359820789b9d3fb7bddfb69b50c5c5ee2801e5818af7bebd97c","impliedFormat":99},{"version":"40641c8c28867972297488656296b456bef7d92149c8bb14249e1e243332b38a","impliedFormat":99},{"version":"62b75bd5e14483b0ed91fcdc9273f807186143cced5904cc66f4eac835007b6c","impliedFormat":99},{"version":"6d0908827e76226b58863b581e47b35c53e352f52ee33591270905a0fa9317f4","impliedFormat":1},{"version":"5a18afdc2d3a9bf47a847ae50feb2647a7c591d0045f8b2d6913495cfa3cf463","impliedFormat":1},{"version":"cf9c3b1bc4f6526701f5bea4ae96aa743833c114d79a4056d2cca63eafe13143","impliedFormat":99},{"version":"32d0cb37844d22572aa1f53eb8de77de931bf978ba017ffe1d9423494be5b265","impliedFormat":99},{"version":"2585fdbb62fb0eb41613083e25f921ff83d3a86b81e4d1b1f2af152bd845e1ba","impliedFormat":99},{"version":"7fcf8a656f292aeda817a97efa3ae714316342cb204bb6b5be9a986d20ed4cb7","impliedFormat":99},{"version":"4c4fccdb4966c33537dddfb6200384cf70f45776137598062417d9468e1165e2","impliedFormat":99},{"version":"0ca033e2a5c21492d2148602c7b0ec1534b13102c233115a750f9f1b997e3990","impliedFormat":99},{"version":"0c5c3d93f4fbd5f513381b375588ac9c6aa32820dcf3b7218b4057f84f940dac","impliedFormat":99},{"version":"802aa23c7b11a52ed83eede9f5cadf457799b1b2a58520bd0449aa8e5edf9c4f","impliedFormat":99},{"version":"5a03e64896ddba87ac233e62ed969c9d571ea58bef4568c074ef03723e8dd2a3","impliedFormat":99},{"version":"26c9d44a3014ff7f8c6a85caad9501e5c48d9e067a52a13c11399571e90b2dde","impliedFormat":99},{"version":"e6cdcbe74044f2c91d64a285671a7be1b4245a635e5c8690e599d5d77ea91a56","impliedFormat":99},{"version":"af3c7e7ac89254c7d3935649921317b393f922ab53ebd596c2ad8686ca0f1baa","impliedFormat":99},{"version":"6eccdf22807087923d69ed3566fc669c4d56cf782a058e8e55cdf76dbb360abd","impliedFormat":99},{"version":"8eb7fc1766116955d9a98a433cf5ab8cd27196bcec47aeb63e84b9f8deec9bf2","impliedFormat":99},{"version":"219d2c7fe5c5a075a39ba7d1a18fe47bc49afe8c39497f7e45dda98a98682bbc","impliedFormat":99},{"version":"017f8c0fdae93ed9071d748acabf9d8e8ebbb9cad88666379a63f19e8c9a4e5e","impliedFormat":99},{"version":"a1798410d801e54eece4a7d854b2bd782c7b9ac647b576ef82b592b5cf63213f","impliedFormat":99},{"version":"2fa4ffa7d85b63a422d45e2b48b5c6b01cb12796d391999cd0b1e78ecdba3498","impliedFormat":99},{"version":"9aef8937ea598953d56326cdd0240c624a12e88b2204fa8b6f6ad7ed11327af7","impliedFormat":99},{"version":"8e0fed6a5b18c2128361a0d1f2d0d139ffce2b58f8854f5622e8761a5ae5b5f8","impliedFormat":99},{"version":"85b68048526e1f218f8c52f2fe71618847825bf133cc3153613bb54da5c950e8","impliedFormat":99},{"version":"b9f9d553d788d6b2ac0ab01596d24c3c4457d543f8ba0c32aad53cd8fc5cb0a9","impliedFormat":99},{"version":"93ec40face5e0c6f87adc7bf0e955bb6bf445862ea0d45261d75477d9dd39db0","impliedFormat":99},{"version":"3ed746ed290306d0edf7039e5d1744155162e9e0b91433c9bc434a97ef868bdb","impliedFormat":99},{"version":"6f4e4e5a046171e70dfb4b1f3e6212de786bf2c1e2c4383ae0e61c4726fdd168","impliedFormat":1},{"version":"116b961153d86b304e788884c4a05630fe98423bcfc14c7a7ea8d542092aac10","impliedFormat":1},{"version":"84206a85be8e7e8f9307c1d5c087aedb4d389e05b755234aa8f37cc22f717aaf","impliedFormat":1},{"version":"45b1df23c0a6e5b45cb8fc998bd90fa9a6a79f2931f6bb1bd15cf8f7efd886d0","impliedFormat":1},{"version":"3c7f3496e7c431c737036336fda7a9bbed241447b2daa3bceb25a55f21828cf2","impliedFormat":1},{"version":"fe56d40fd418bb23a5661eb38064440d47b0d149ebcf16d8cd657c21ef6d6b1c","impliedFormat":1},{"version":"eb125712735e776a952dede560137f1e3e429bb0f31221f6e5ce093e6a25f127","impliedFormat":1},{"version":"0ec9c72e6c91fe719a231186062b60698e0baaa6d72d6fc5316e34f20987adf3","impliedFormat":1},{"version":"329934265ed8784d7f4219a40ebc0e1780f0d82d573b09ed8956a3c681c28645","impliedFormat":1},{"version":"3037aefea58bd42d98e3b7589c15006f33034bf268f9f8ad1e0bb104a88867a7","impliedFormat":1},{"version":"eace585126dafd40f81577254e18b654b4dd90452bcec25465f78a297f16912b","impliedFormat":1},{"version":"a58bf3a0569bd71d8767c3e72d2f7bbec2017d49ab7d99252737e8773ed56434","impliedFormat":1},{"version":"d638d08f20b300cd5fc53b310efbc1352d6953d2f7c92b7fc9f4c895051e0a76","impliedFormat":1},{"version":"1c9bded3b6c93ab190ae8ce202a3c7670fbb46ea0e3b97d18d61c4f4b7ebc917","impliedFormat":1},{"version":"368d7fdea9761d00c6aca5635d71bf3bb325ee4af573f9ba7ef500b46619777b","impliedFormat":1},{"version":"4fe80f12b1d5189384a219095c2eabadbb389c2d3703aae7c5376dbaa56061df","impliedFormat":1},{"version":"9eb1d2dceae65d1c82fc6be7e9b6b19cf3ca93c364678611107362b6ad4d2d41","impliedFormat":1},{"version":"cf1dc1d2914dd0f9462bc04c394084304dff5196cce7b725029c792e4e622a5b","impliedFormat":1},{"version":"87eb6cbb3ca53b22256d97c5839d1145ffd7f420411a4a9cc232c8aaaff87729","impliedFormat":1},{"version":"85bfab62abe8ac6ba4119d9900b2d5151fd44e43a111220abbd72e532490a275","impliedFormat":1},{"version":"cb4ed22af6018c73726e874976f77bda29ae2d1b374e738cb42559b1dd1970d5","impliedFormat":1},{"version":"0a518a2934ed7db17ab9a2767008e7d4b232c606113bea74b093a69386986b4e","impliedFormat":1},{"version":"bd74948c045cfbf9fbed1f69691f2c7a593e069081177665e026639f54427460","impliedFormat":1},{"version":"ff281735449be3e11b6297b79b2806b054e8e8aabbd19464c5e7bd0c8646d7f7","impliedFormat":1},{"version":"87835f17a3c4f733e3b413f4d0f0c593896168cfe64fdc3913298c508af53394","impliedFormat":1},{"version":"03eb8cdaaf7e6e8654859dfb2876204f6f3c2c99942b81746fbb4cd91ee7e78b","impliedFormat":1},{"version":"faf766a0b271fdcafe4d57a0831b7c15539cfdd18b12d715fc4e8ef120a75bf6","impliedFormat":1},{"version":"f77a3db2fb02b7bd1fd5421bfb49d035987fea08b9dffe17a52e0a5cd30a678d","impliedFormat":1},{"version":"87feb0ce62dda4191bbb5d4e1cb53a29a702ce9f71562da9c46a709b2d590a1c","impliedFormat":1},{"version":"347481ab46881f5f20f2fe690be110cd2354b76e3fd59b4fcc2869fb8b599568","impliedFormat":1},{"version":"83fac95fe9bb824dc5b68b61af56c06281070c5e6277e87643556b8e0743a2ae","impliedFormat":1},{"version":"60f200789d4d5ff17d4ea198d84cb6aa08c1e4f83509609b26ffff3449f164d1","impliedFormat":1},{"version":"891b88342c4aa5dd40206117cc96c173aa99b8b286a48385d933300fdcc3c914","impliedFormat":1},{"version":"c4eef33aa3436f11402f577e8b750698ae512214df705513bb0c5e1ac4c40ec5","impliedFormat":1},{"version":"5048f784331f813475a7f254a4855d5a041ab25d66d7d61a5f7310b22e47e50b","impliedFormat":1},{"version":"024e9190307fcb969dce6522916983a11663a6e4dc9cd5215b1b2c5ad5cdaecd","impliedFormat":1},{"version":"12467a6fc17ce64029f764c4878b6d36a13602f588f8d535720cd544c1bb6db3","impliedFormat":1},{"version":"961dc485cc641e42066a3f077256ac71375c654f06f25002f7c2fa906f23145b","impliedFormat":1},{"version":"7ab71ae8718b9d20e9233d996c972946300c1cfed52149c57c04bf5315248a77","impliedFormat":1},{"version":"1b9237dfac23527451cb75941be63acd4327426cd38627607e7d740c3a3d2f54","impliedFormat":1},{"version":"763f0d17744e0183fbc8bf92d3c3e737d50e2dff543b6224c87303a3d62f959e","impliedFormat":1},{"version":"861113d5b0fe6a863aefd42a01c938a1e386ee7cf2c5c90993040683a2564772","impliedFormat":1},{"version":"c0e4baf40da6963266a0a8fcfefcaf88a40bee9d9da0826d05d0e928c3bba18e","impliedFormat":1},{"version":"61c2816f77df7cdd7a001445d61cf8366fb95ef7ce8c2cbb9cadb46900c3604c","impliedFormat":1},{"version":"d4e81b5fcb7e4a6d4e9574a008ea7deea98d7c7e1fea9d78a66baca44466593b","impliedFormat":1},{"version":"2a59a920139de706564c7358b62fb8e74544aec1a9d18f4c30d0e7b00517cf08","impliedFormat":1},{"version":"4971de10f42d10bbc1e64bfc09fbbb6f9186f21d104f0ab53aa1317bbf304bc0","impliedFormat":1},{"version":"414edcc979fe0ea2370878b6a4fd6155de990676ee28521a10f4936378b11d83","impliedFormat":1},{"version":"7aad6aba607d3a577bbdff7c9183e9b146ca8952f6200ef50feadfd442aa0b30","impliedFormat":1},{"version":"5240251eb23c491f7055457a08e6e8c80c0d08cb3c72cca683720724fd68f969","impliedFormat":1},{"version":"3087194a9fe1cf6a63b68030ff1239c58652b4f946efbdc2eb669521f11d7164","impliedFormat":1},{"version":"cd797e2e7fc54fc8c6784eabd69ce86ad4df08314a894e6402d1bda5c657e781","impliedFormat":1},{"version":"74d364c79625574c332e08ade324ff1698369c4a651fbf491ffaec407189bb01","impliedFormat":1},{"version":"5199e72c79c9a3f9ade23cd467f916ae77dacee05fee8ac5630fdc53f87aa8e4","impliedFormat":1},{"version":"1cdddff8ba2368f0a5e2c6b643ebf9cc8743dbd083be788d4c5c4551dee34b64","impliedFormat":1},{"version":"2561f493a2ae9b2152f8ea38752713767f5df6322881f4840682f43cce47160b","impliedFormat":1},{"version":"59e2e225b4248e7aba2b6e7004b2a9eafc2c708c6682b2263812b0d42bc84684","impliedFormat":1},{"version":"84110329752138a46cd3cf8bb5496c58d18f9cfbae4acd1839a01a1e262ba18a","impliedFormat":1},{"version":"f0e25458ac825651e3bff56da122271fe4326916eb400c860b3193f6f99fddcb","impliedFormat":1},{"version":"6488f033e8f8cf6225c200d7888e45f2e0ad3927aef34536ef6017076532b191","impliedFormat":1},{"version":"833babc49a59842ec7f2f3a1b68eef80c0e5d0f1f97e7a24c195f478d685c8dd","impliedFormat":1},{"version":"1dabaf844b988062940800606f036961926c10c9df58db1455b5c16bfdd20e45","impliedFormat":1},{"version":"9fd62eea2dfb48942042189e53cb144f992c4996d1dc82f28ca76841da724488","impliedFormat":1},{"version":"a541265139060da43c982b6281980c10c5c70d3bf8f0e13286f09d85d38b7c12","impliedFormat":1},{"version":"906cb63cff0763086bcc49ed33a4e424cd4fa6ca46d04e5909245a759c39d5bb","impliedFormat":1},{"version":"9ed2f3cfafc0110bd4b040f57dba5472945a6750df4bcd65a15f7006298ad204","impliedFormat":1},{"version":"62050319381557ba4c64875ca5de9167e08b9f37203d3cbb6db63bcadca713bf","impliedFormat":1},{"version":"a798a06d65dbbbd5aff1ae166b18c101ca26fb81ad76091102102fce23d7db79","impliedFormat":1},{"version":"037ce90379694c635b0fc3ac0dc0fcbe2b9fd5674044d0ac4abb3ff9dd732a51","impliedFormat":99},{"version":"33b03f5274a8e93e0c27a5bc7a1c914e28254a2e9c5de09b13c81f41019075e5","impliedFormat":99},{"version":"7f8be7331c0a559643adcad96760ea17702fa652edc09da97838f30a656295b0","impliedFormat":99},{"version":"c940321bb58bafba400fd595b2d67f4049abeeb3d35c514ca523c5079299883b","impliedFormat":99},{"version":"116172fb9d0bede12b4551d51857f01e5e07ffc338a038ca1e9ff7604e7db5b5","signature":"2d834a8d4c0e18e086cbf5d5980bd6278c996294b699c18acce3b17b4c7be798"},"611450efed7eb7885c611e1af29db1b0bbf9d85d123af69ab2255bb9357fd5fd","03a53e50a975cd9aabacb689e2a5349161d4aefd51a65bcd8e0ac26a8b7fa683",{"version":"bd6ac6869f4e6ad30e69de890cc6083be653f54fa28082a593811d7fb787da9f","signature":"3eafd79b8de296aeaa08d3a856b7dcb3886bee55af82f0aa2585bd0a761c76e3"},"60f50b2ac42adc9a1f38aa3b486eb397dec1059096e2171c8cbe3cc1ad07478d","bb8c0a2cb832b055e34c50d7000e8ebceb1c15700615ff032545566eb85f9f75",{"version":"3fcd8c44aa6939771092a4763ab2bfafb252bf67658e58f77f72cee3740fda80","signature":"b37a76a8d82a691d782abeadeae0a70273b01174a761f93506fee951b0a9dfec"},"9b56109d6f425e3bf86b15398863f97ae11b6c7cf1598a94482409b6be07aa69",{"version":"67a95ab694ebeb1e33185f3dffd1de9516d49bcfdd8ffa277ec68b716cadf3ff","signature":"159cb0a765a7c790055750584a22fa381b20b7d988de0358dc6dfa0209e7e36c"},{"version":"ce0d4fd59ce0f4f1a3a4b538b81dccbf9e8800d7c401a88d398692eac7cb0749","signature":"ed47c4fde049c83a7f144a6e653f53b24a294c1ee53ea2391f71b1b3f399176c"},{"version":"cff399d99c68e4fafdd5835d443a980622267a39ac6f3f59b9e3d60d60c4f133","impliedFormat":1},{"version":"6ada175c0c585e89569e8feb8ff6fc9fc443d7f9ca6340b456e0f94cbef559bf","impliedFormat":1},{"version":"e56e4d95fad615c97eb0ae39c329a4cda9c0af178273a9173676cc9b14b58520","impliedFormat":1},{"version":"73e8dfd5e7d2abc18bdb5c5873e64dbdd1082408dd1921cad6ff7130d8339334","impliedFormat":1},{"version":"fc820b2f0c21501f51f79b58a21d3fa7ae5659fc1812784dbfbb72af147659ee","impliedFormat":1},{"version":"4f041ef66167b5f9c73101e5fd8468774b09429932067926f9b2960cc3e4f99d","impliedFormat":1},{"version":"31501b8fc4279e78f6a05ca35e365e73c0b0c57d06dbe8faecb10c7254ce7714","impliedFormat":1},{"version":"7bc76e7d4bbe3764abaf054aed3a622c5cdbac694e474050d71ce9d4ab93ea4b","impliedFormat":1},{"version":"ff4e9db3eb1e95d7ba4b5765e4dc7f512b90fb3b588adfd5ca9b0d9d7a56a1ae","impliedFormat":1},{"version":"f205fd03cd15ea054f7006b7ef8378ef29c315149da0726f4928d291e7dce7b9","impliedFormat":1},{"version":"d683908557d53abeb1b94747e764b3bd6b6226273514b96a942340e9ce4b7be7","impliedFormat":1},{"version":"7c6d5704e2f236fddaf8dbe9131d998a4f5132609ef795b78c3b63f46317f88a","impliedFormat":1},{"version":"d05bd4d28c12545827349b0ac3a79c50658d68147dad38d13e97e22353544496","impliedFormat":1},{"version":"b6436d90a5487d9b3c3916b939f68e43f7eaca4b0bb305d897d5124180a122b9","impliedFormat":1},{"version":"04ace6bedd6f59c30ea6df1f0f8d432c728c8bc5c5fd0c5c1c80242d3ab51977","impliedFormat":1},{"version":"57a8a7772769c35ba7b4b1ba125f0812deec5c7102a0d04d9e15b1d22880c9e8","impliedFormat":1},{"version":"badcc9d59770b91987e962f8e3ddfa1e06671b0e4c5e2738bbd002255cad3f38","impliedFormat":1},{"version":"f8b2c7dba8b974bd96d2cd0a5c3bbd6d900b2a95c989a49554fbb2f6baf70ba8","signature":"26ff547ea6bab78b548e658dcff7ae1870b3c053193dc261a864da10a758ebef"},"11ba1da39bb1b7578e72f46269e9488d76ef53f5e64c8e40620feca273636a9c",{"version":"15e2321559ee7da4f3fde12026d79b12d6a8643e70fbd28f0230f9431a5033c1","signature":"e6e74b6ebae979eb0ee810e349c9df66335169aff398d590a29405fb8496965b"},"2c7fc28dafcbd22258b39e684db83599ff96428f01440d7fad8eb6e976aa7368",{"version":"7599bdaed096e138a374c5726948c69339693b377bc7ace4729de58c8abfd2e7","signature":"1f8801573d36932d41a595aa2b88656d209ae693ebf799cb7ae9013bef10de30"},"76e6ee07bb371747d8d65a557b806c010d844d4f3d7d288740a85be29e250558",{"version":"b0a7c36cca4c92471a780b098d8ccd92533ce8786827ed1e73360fde20d43d74","signature":"ce3cdc4d36491b37a849b257264f586eb977dc4345757370eb30cc75622afb95"},{"version":"72de772eec66c78af307119a1b1a8167d363cf6b91e9920ba766b36c6421a777","signature":"916f900e308cee26cb0a3d3b42dd9070ed9826aafbaf8dd91be0bc3d69ad8abb"},"5cb40cc19985c6a3c601e6f090713cffebb43d57026e7cedc933cbd97ff9886e","cdb4c37ed670cc71d6ccddfaac42b87e64110fcdc5707566e02148602c0eddfc","5c5edf2cc5dd23ed2a4dfd4b02fd3947431e8c33b330be0ec9ace7a6bbdcbde9","ae15143a15fb56910b3aafd072f8e55d1388648eb9f23d65a7d710536db52d1c",{"version":"577fd7517813e5a9c135cca325a0942330153773623ed5f14ca827cb5a1a531c","signature":"3dcf6effd044310b5522f3177c353d884690a69ae460799fd9cf26678d1fa511"},{"version":"361bc4ea2d2d800b713c3d0433970e5c1ab598e313cff49a1370c6e07518eacf","signature":"cb70814a82ad8013fd44c5432641c1c2fe0ec352802dce4accafeea93a346196"},{"version":"7177eec91c80bcbf891e995fee97aaf06baf5ac328b94f23b34e2e4215c799e3","signature":"a38452e417b3d5a6bef1f2931ba732118fd2af7a060d7c29ec902f17d7390ee0"},{"version":"47fbc5cc6fd29462dd86425917f8e2f0d93fddf772a49be57c588f89b7e89b8d","signature":"62c2a2c4849eea7b7d20be6f081df6dcdac7f5f36c6709b7be9e57d7cd1718f7"},{"version":"830e23fa31969b1a51bb9c3c3078ec421fb46744aaf313849253d70280334389","signature":"abbd175f6ff7890cb99298a682ea25d8d74a5b7113950789f17ed4dfa94803b5"},"52a8e3620c9bdb657289da7a633af7c877e78933cc10d5081e9aa6ade0e7c938","97eebc0cfb242ee9beed87794119c6177dfac876250bc7e3e7a78be20bae998a","ad2996c286ab57bd70613d9c9eef77259b0f52d7999a6eefd4c03b4e9a97936e",{"version":"09b0217bd5ce61d88eb254f89204aad9d687ee693b709b2f64c1c3c4292fa177","signature":"f870f748503faacdd11540e67f6ea59f4688ba1641b3cab85f64d5b7c37c4a11"},"540d6f05dfc63e8a26a03210f4fe24154582beb97473292da3a0bf6b24a13bbc",{"version":"c78861eb54c84167324b1583339721259bd255e0bb8d6ed757e5380f4326c1b2","signature":"bf5649a304c6f61cad612c23be0cf2ac02c757636044808d043c5a6751dcced6"},"556fe5d7528b19e2421cc80ae5602449cc0b25dc362291f02f6f386303537a9a","b69883a2e25b3df16bd0dfab245cc4fb6d2ab91bacbcbd738ebd8bb1b1ba92e7","77064783c7c9e86a3d7fdf2eb564b6a5b0553a0cab33ba8a17ebf33854a6b958","4c0d0732df7648dc3447a2ee7b577787c62ba05278392a5895f66c9c3d68d713",{"version":"922a73684d40e27cd6e50c40862163f01a53766a571877cb47240155c5cabb91","signature":"331b12866ba4245fb81a46ac507898d826a4c61bd3c2b0569842b17815cd723a"},"72d12fa4956f094077068397922211077d6ee88b409759448dc4249bda1648e8","735ebb194abbf2c7cdf588474f2910c1ce5e718b49b347c9393cfe7c4e40e129",{"version":"b9bdee53a82e439fdbde6141b9a608c544c08bc33f991a313c7f663dd480de6a","signature":"ac611b6f98c4760d6d0b5893510c69e7f3e599d4d6cd8a8e2efe87080677876d"},"3be03b43ed3cf8922d624fa8063ae3fc684ecab3e0d243bf6391dc87f2b32035",{"version":"effca63c1686bbb7704a1e99186d53f316f50b8c3c9a00aafc3873b325d196fd","signature":"e881c62ec7521c705506226859479c3a2ea921c727b219833758e4f4b5c9dcb7"},{"version":"2e19656c513ded3efe9d292e55d3661b47f21f48f9c7b22003b8522d6d78e42f","impliedFormat":1},{"version":"ddecf238214bfa352f7fb8ed748a7ec6c80f1edcb45053af466a4aa6a2b85ffe","impliedFormat":1},{"version":"896eec3b830d89bc3fb20a38589c111bbe4183dd422e61c6c985d6ccec46a1e9","impliedFormat":1},{"version":"c8aa3e763e4aeca4f0be3f1f2a0b8d660f92f84e9ed699a2b5e8611719abd73d","impliedFormat":1},{"version":"8629340be5692664c52a0e242705616c92b21330cb20acf23425fff401ac771f","impliedFormat":1},{"version":"81477bb2c9b97a9dd5ce7750ab4ae655e74172f0d536d637be345ba76b41cd92","impliedFormat":1},{"version":"b8ad793dc17938bc462812e3522bbd3d62519d91d9b4a6422bed1383c2d3eb42","impliedFormat":1},{"version":"8b0b6a4c032a56d5651f7dd02ba3f05fbfe4131c4095093633cda3cae0991972","impliedFormat":1},{"version":"ff3c48a17bf10dfbb62448152042e4a48a56c9972059997ab9e7ed03b191809b","impliedFormat":1},{"version":"192a0c215bffe5e4ac7b9ff1e90e94bf4dfdad4f0f69a5ae07fccc36435ebb87","impliedFormat":1},{"version":"3ef8565e3d254583cced37534f161c31e3a8f341ff005c98b582c6d8c9274538","impliedFormat":1},{"version":"d7e42a3800e287d2a1af8479c7dd58c8663e80a01686cb89e0068be6c777d687","impliedFormat":1},{"version":"1098034333d3eb3c1d974435cacba9bd5a625711453412b3a514774fec7ca748","impliedFormat":1},{"version":"f2388b97b898a93d5a864e85627e3af8638695ebfa6d732ecd39d382824f0e63","impliedFormat":1},{"version":"6c6bd91368169cfa94b4f8cc64ebca2b050685ec76bc4082c44ce125b5530cca","impliedFormat":1},{"version":"f477375e6f0bf2a638a71d4e7a3da8885e3a03f3e5350688541d136b10b762a6","impliedFormat":1},{"version":"a44d6ea4dc70c3d789e9cef3cc42b79c78d17d3ce07f5fd278a7e1cbe824da56","impliedFormat":1},{"version":"272af80940fcc0c8325e4a04322c50d11f8b8842f96ac66cbd440835e958dd14","impliedFormat":1},{"version":"1803e48a3ec919ccafbcafeef5e410776ca0644ae8c6c87beca4c92d8a964434","impliedFormat":1},{"version":"875c43c5409e197e72ee517cb1f8fd358406b4adf058dbdc1e50c8db93d68f26","impliedFormat":1},{"version":"8854713984b9588eac1cab69c9e2a6e1a33760d9a2d182169059991914dd8577","impliedFormat":1},{"version":"e333d487ca89f26eafb95ea4b59bea8ba26b357e9f2fd3728be81d999f9e8cf6","impliedFormat":1},{"version":"2f554c6798b731fc39ff4e3d86aadc932fdeaa063e3cbab025623ff5653c0031","impliedFormat":1},{"version":"fe4613c6c0d23edc04cd8585bdd86bc7337dc6265fb52037d11ca19eeb5e5aaf","impliedFormat":1},{"version":"53b26fbee1a21a6403cf4625d0e501a966b9ccf735754b854366cee8984b711c","impliedFormat":1},{"version":"c503be3ddb3990ab27ca20c6559d29b547d9f9413e05d2987dd7c4bcf52f3736","impliedFormat":1},{"version":"598b15f0ae9a73082631d14cb8297a1285150ca325dbce98fc29c4f0b7079443","impliedFormat":1},{"version":"8c59d8256086ed17676139ee43c1155673e357ab956fb9d00711a7cac73e059d","impliedFormat":1},{"version":"cfe88132f67aa055a3f49d59b01585fa8d890f5a66a0a13bb71973d57573eee7","impliedFormat":1},{"version":"53ce488a97f0b50686ade64252f60a1e491591dd7324f017b86d78239bd232ca","impliedFormat":1},{"version":"50fd11b764194f06977c162c37e5a70bcf0d3579bf82dd4de4eee3ac68d0f82f","impliedFormat":1},{"version":"e0ceb647dcdf6b27fd37e8b0406c7eafb8adfc99414837f3c9bfd28ffed6150a","impliedFormat":1},{"version":"99579aa074ed298e7a3d6a47e68f0cd099e92411212d5081ce88344a5b1b528d","impliedFormat":1},{"version":"c94c1aa80687a277396307b80774ca540d0559c2f7ba340168c2637c82b1f766","impliedFormat":1},{"version":"ce7dbf31739cc7bca35ca50e4f0cbd75cd31fd6c05c66841f8748e225dc73aaf","impliedFormat":1},{"version":"942ab34f62ac3f3d20014615b6442b6dc51815e30a878ebc390dd70e0dec63bf","impliedFormat":1},{"version":"7a671bf8b4ad81b8b8aea76213ca31b8a5de4ba39490fbdee249fc5ba974a622","impliedFormat":1},{"version":"8e07f13fb0f67e12863b096734f004e14c5ebfd34a524ed4c863c80354c25a44","impliedFormat":1},{"version":"6f6bdb523e5162216efc36ebba4f1ef8e845f1a9e55f15387df8e85206448aee","impliedFormat":1},{"version":"aa2d6531a04d6379318d29891de396f61ccc171bfd2f8448cc1649c184becdf2","impliedFormat":1},{"version":"d422f0c340060a53cb56d0db24dd170e31e236a808130ab106f7ab2c846f1cdb","impliedFormat":1},{"version":"424403ef35c4c97a7f00ea85f4a5e2f088659c731e75dbe0c546137cb64ef8d8","impliedFormat":1},{"version":"16900e9a60518461d7889be8efeca3fe2cbcd3f6ce6dee70fea81dfbf8990a76","impliedFormat":1},{"version":"6daf17b3bd9499bd0cc1733ab227267d48cd0145ed9967c983ccb8f52eb72d6e","impliedFormat":1},{"version":"e4177e6220d0fef2500432c723dbd2eb9a27dcb491344e6b342be58cc1379ec0","impliedFormat":1},{"version":"ab710f1ee2866e473454a348cffd8d5486e3c07c255f214e19e59a4f17eece4d","impliedFormat":1},{"version":"db7ff3459e80382c61441ea9171f183252b6acc82957ecb6285fff4dca55c585","impliedFormat":1},{"version":"4a168e11fe0f46918721d2f6fcdb676333395736371db1c113ae30b6fde9ccd2","impliedFormat":1},{"version":"2a899aef0c6c94cc3537fe93ec8047647e77a3f52ee7cacda95a8c956d3623fb","impliedFormat":1},{"version":"ef2c1585cad462bdf65f2640e7bcd75cd0dbc45bae297e75072e11fe3db017fa","impliedFormat":1},{"version":"6a52170a5e4600bbb47a94a1dd9522dca7348ce591d8cdbb7d4fe3e23bbea461","impliedFormat":1},{"version":"6f6eadb32844b0ec7b322293b011316486894f110443197c4c9fbcba01b3b2fa","impliedFormat":1},{"version":"a51e08f41e3e948c287268a275bfe652856a10f68ddd2bf3e3aaf5b8cdb9ef85","impliedFormat":1},{"version":"16c144a21cd99926eeba1605aec9984439e91aa864d1c210e176ca668f5f586a","impliedFormat":1},{"version":"af48a76b75041e2b3e7bd8eed786c07f39ea896bb2ff165e27e18208d09b8bee","impliedFormat":1},{"version":"fd4107bd5c899165a21ab93768904d5cfb3e98b952f91fbf5a12789a4c0744e6","impliedFormat":1},{"version":"deb092bc337b2cb0a1b14f3d43f56bc663e1447694e6d479d6df8296bdd452d6","impliedFormat":1},{"version":"041bc1c3620322cb6152183857601707ef6626e9d99f736e8780533689fb1bf9","impliedFormat":1},{"version":"77165b117f552be305d3bc2ef83424ff1e67afb22bfabd14ebebb3468c21fcaa","impliedFormat":1},{"version":"128e7c2ffd37aa29e05367400d718b0e4770cefb1e658d8783ec80a16bc0643a","impliedFormat":1},{"version":"076ac4f2d642c473fa7f01c8c1b7b4ef58f921130174d9cf78430651f44c43ec","impliedFormat":1},{"version":"396c1e5a39706999ec8cc582916e05fcb4f901631d2c192c1292e95089a494d9","impliedFormat":1},{"version":"89df75d28f34fc698fe261f9489125b4e5828fbd62d863bbe93373d3ed995056","impliedFormat":1},{"version":"8ccf5843249a042f4553a308816fe8a03aa423e55544637757d0cfa338bb5186","impliedFormat":1},{"version":"93b44aa4a7b27ba57d9e2bad6fb7943956de85c5cc330d2c3e30cd25b4583d44","impliedFormat":1},{"version":"a0c6216075f54cafdfa90412596b165ff85e2cadd319c49557cc8410f487b77c","impliedFormat":1},{"version":"3c359d811ec0097cba00fb2afd844b125a2ddf4cad88afaf864e88c8d3d358bd","impliedFormat":1},{"version":"d8ec19be7d6d3950992c3418f3a4aa2bcad144252bd7c0891462b5879f436e4e","impliedFormat":1},{"version":"db37aa3208b48bdcbc27c0c1ae3d1b86c0d5159e65543e8ab79cbfb37b1f2f34","impliedFormat":1},{"version":"d62f09256941e92a95b78ae2267e4cf5ff2ca8915d62b9561b1bc85af1baf428","impliedFormat":1},{"version":"e6223b7263dd7a49f4691bf8df2b1e69f764fb46972937e6f9b28538d050b1ba","impliedFormat":1},{"version":"2daf06d8e15cbca27baa6c106253b92dad96afd87af9996cf49a47103b97dc95","impliedFormat":1},{"version":"1db014db736a09668e0c0576585174dbcfd6471bb5e2d79f151a241e0d18d66b","impliedFormat":1},{"version":"8a153d30edde9cefd102e5523b5a9673c298fc7cf7af5173ae946cbb8dd48f11","impliedFormat":1},{"version":"abaaf8d606990f505ee5f76d0b45a44df60886a7d470820fcfb2c06eafa99659","impliedFormat":1},{"version":"8109e0580fc71dbefd6091b8825acf83209b6c07d3f54c33afeafab5e1f88844","impliedFormat":1},{"version":"d92a80c2c05cf974704088f9da904fe5eadc0b3ad49ddd1ef70ca8028b5adda1","impliedFormat":1},{"version":"fbd7450f20b4486c54f8a90486c395b14f76da66ba30a7d83590e199848f0660","impliedFormat":1},{"version":"ece5b0e45c865645ab65880854899a5422a0b76ada7baa49300c76d38a530ee1","impliedFormat":1},{"version":"62d89ac385aeab821e2d55b4f9a23a277d44f33c67fefe4859c17b80fdb397ea","impliedFormat":1},{"version":"f4dee11887c5564886026263c6ee65c0babc971b2b8848d85c35927af25da827","impliedFormat":1},{"version":"fb8dd49a4cd6d802be4554fbab193bb06e2035905779777f32326cb57cf6a2c2","impliedFormat":1},{"version":"df29ade4994de2d9327a5f44a706bbe6103022a8f40316839afa38d3e078ee06","impliedFormat":1},{"version":"82d3e00d56a71fc169f3cf9ec5f5ffcc92f6c0e67d4dfc130dafe9f1886d5515","impliedFormat":1},{"version":"d38f45cb868a830d130ac8b87d3f7e8caff4961a3a1feae055de5e538e20879a","impliedFormat":1},{"version":"4c30a5cb3097befb9704d16aa4670e64e39ea69c5964a1433b9ffd32e1a5a3a1","impliedFormat":1},{"version":"1b33478647aa1b771314745807397002a410c746480e9447db959110999873ce","impliedFormat":1},{"version":"7b3a5e25bf3c51af55cb2986b89949317aa0f6cbfb5317edd7d4037fa52219a9","impliedFormat":1},{"version":"3cd50f6a83629c0ec330fc482e587bfa96532d4c9ce85e6c3ddf9f52f63eee11","impliedFormat":1},{"version":"9fac6ebf3c60ced53dd21def30a679ec225fc3ff4b8d66b86326c285a4eebb5a","impliedFormat":1},{"version":"8cb83cb98c460cd716d2a98b64eb1a07a3a65c7362436550e02f5c2d212871d1","impliedFormat":1},{"version":"07bc8a3551e39e70c38e7293b1a09916867d728043e352b119f951742cb91624","impliedFormat":1},{"version":"e47adc2176f43c617c0ab47f2d9b2bb1706d9e0669bf349a30c3fe09ddd63261","impliedFormat":1},{"version":"7fec79dfd7319fec7456b1b53134edb54c411ba493a0aef350eee75a4f223eeb","impliedFormat":1},{"version":"189c489705bb96a308dcde9b3336011d08bfbca568bcaf5d5d55c05468e9de7a","impliedFormat":1},{"version":"98f4b1074567341764b580bf14c5aabe82a4390d11553780814f7e932970a6f7","impliedFormat":1},{"version":"dadfa5fd3d5c511ca6bfe240243b5cf2e0f87e44ea63e23c4b2fce253c0d4601","impliedFormat":1},{"version":"2e252235037a2cd8feebfbf74aa460f783e5d423895d13f29a934d7655a1f8be","impliedFormat":1},{"version":"763f4ac187891a6d71ae8821f45eef7ff915b5d687233349e2c8a76c22b3bf2a","impliedFormat":1},{"version":"0f351c79ab4459a3671da2f77f4e4254e2eca45bcdb9f79f7dbb6e48e39fd8fe","impliedFormat":1},{"version":"b7d85dc2de8db4ca983d848c8cfad6cf4d743f8cb35afe1957bedf997c858052","impliedFormat":1},{"version":"83daad5d7ae60a0aede88ea6b9e40853abcbe279c10187342b25e96e35bc9f78","impliedFormat":1},{"version":"3a4e276e678bae861d453944cf92178deaf9b6dcd363c8d10d5dd89d81b74a0c","impliedFormat":1},{"version":"db9661c9bca73e5be82c90359e6217540fd3fd674f0b9403edf04a619a57d563","impliedFormat":1},{"version":"f7a5ab7b54bdc6a13cf1015e1b5d6eeb31d765d54045281bfeefcdfcc982a37c","impliedFormat":1},{"version":"ec99a3d23510a4cb5bdc996b9f2170c78cde2bfa89a5aee4ca2c009a5f122310","impliedFormat":1},"3bf7a6cc82ecc9fc89f497eebbe2169ede1dead667a3e6cd895a5b05b9ca310b","f7c5212ec4152b071b7c09cad7ff0bcc49ade932683aed5270b92dfc680a6191","9cc77e771b62559ff8fd0ee46aba430f9aeb55d8a42331cbf409971faf5a2c78","d66131edf8f3d1df1503c10ac72aca2493f286a45183c945efcde30fed4debdf",{"version":"25e5c8b73c6ad21f39e8e72f954090f30b431a993252bccea5bdad4a3d93c760","impliedFormat":1},{"version":"5bf595f68b7c1d46ae8385e3363c6e0d4695b6da58a84c6340489fc07ffc73f8","impliedFormat":1},{"version":"b87682ddc9e2c3714ca66991cdd86ff7e18cae6fd010742a93bd612a07d19697","impliedFormat":1},{"version":"87d3ab3f2edb68849714195c008bf9be6067b081ef5a199c9c32f743c6871522","impliedFormat":1},{"version":"86bf2bfe29d0bc3fbc68e64c25ea6eab9bcb3c518ae941012ed75b1e87d391ae","impliedFormat":1},{"version":"8d9c4957c4feed3de73c44eb472f5e44dfb0f0cb75db6ea00f38939bd77f6e84","impliedFormat":1},{"version":"00b4f8b82e78f658b7e269c95d07e55d391235ce34d432764687441177ae7f64","impliedFormat":1},{"version":"57880096566780d72e02a5b34d8577e78cdf072bfd624452a95d65bd8f07cbe0","impliedFormat":1},{"version":"10ac50eaf9eb62c048efe576592b14830a757f7ea7ed28ee8deafc19c9845297","impliedFormat":1},{"version":"e75af112e5487476f7c427945fbd76ca46b28285586ad349a25731d196222d56","impliedFormat":1},{"version":"e91adad3da69c366d57067fcf234030b8a05bcf98c25a759a7a5cd22398ac201","impliedFormat":1},{"version":"d7d6e1974124a2dad1a1b816ba2436a95f44feeda0573d6c9fb355f590cf9086","impliedFormat":1},{"version":"464413fcd7e7a3e1d3f2676dc5ef4ebe211c10e3107e126d4516d79439e4e808","impliedFormat":1},{"version":"18f912e4672327b3dd17d70e91da6fcd79d497ba01dde9053a23e7691f56908c","impliedFormat":1},{"version":"2974e2f06de97e1d6e61d1462b54d7da2c03b3e8458ee4b3dc36273bc6dda990","impliedFormat":1},{"version":"d8c1697db4bb3234ff3f8481545284992f1516bc712421b81ee3ef3f226ae112","impliedFormat":1},{"version":"59b6cce93747f7eb2c0405d9f32b77874e059d9881ec8f1b65ff6c068fcce6f2","impliedFormat":1},{"version":"e2c3c3ca3818d610599392a9431e60ec021c5d59262ecd616538484990f6e331","impliedFormat":1},{"version":"e3cd60be3c4f95c43420be67eaa21637585b7c1a8129f9b39983bbd294f9513c","impliedFormat":1},{"version":"d57be402cf1a3f1bd1852fc71b31ff54da497f64dcdcf8af9ad32435e3f32c1f","affectsGlobalScope":true,"impliedFormat":1},"730d000c551905046fd12934473976f2bc3c3b760a139d619ba3fe0c3569c0a8","6439caf7d70d6a80c9a24591279e4a45e5d7cabb978fbd09166f331a250766ef","5733f6545866b375560b3934945b84062b012469e7b41d705b1f50073b407b6d",{"version":"2474cfad8fd85951b082e8558cf82f985a1d5ec9a83fcf8aa0a95e4b3749f415","signature":"b82491e2990291580288c5602d4c017238977749d52b17391f0e45d9a29be644"},"7f54cbce2e5e15f54a30f299be5fc423efb5be0b4a5ca8dac60e3c24af2a95d0","b83399f1b07f2cf2170e1bf6b794bc41ba7928c7d3d3c7abf2d91a18bd0bd5d8","02f74524788b18a07fd871b06231ebc8d0472ccf910098b75e231270ccd999b3","681fadfba2f439d391fb01aef39baadf2088abf30d22b105c0c7d49825b70256","f4d08744d955acea62d65986fee0b872bec5caef8cc0cf5fc66d55507aec0278","b1cd484d441d071f7aebe0d937f5dad292d209c3f6c984e03e93cd30bf005cfc","982f707b19ee166cc1d5bec58b8c8b19065ea1c0229479e42c8d127e1a922d37","ee2de2f01ca6e86be7118dc603ad39f51101155d8d3b36d063a10e34e157ce18","5c266b9fb91d02db113c94bd22b4b94aeda71d69085ab70b38b8eaa2a0c28635","697d372ac6f99653d9e188354f7a17c9e30f4a8719cc5614221dfa84dfa04c18","864b07966a5539e732022095f85811500c820e89801d77078f6586be8630f296","a6f0030997968c4dc21e3d27f998588829cba7aaeb12b3e1d6c81227a6ac5ca0","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","5b583af797873b576920816b41bff7e082e14b97acebe08f2ad95fa18756b5d4","822f64ae36e6acef66c7a7950383d63fa53757c190cbe39494655bd7437b25fb",{"version":"58086bfb315e327e2d3144553ab86d32ce42044d2f61ac849e6c6d7c2767cb34","impliedFormat":99},{"version":"262eff58f4881a7e629b218cdb90d9b3ba8f98286393e2c9bea70e41668d7ba8","impliedFormat":99},{"version":"07cbb6c90662639f69951d5b18d5b89cfa1a1aa4b7c647d5cd572e9743ba7c1d","impliedFormat":99},{"version":"0e882665711bbc4138dd0466cc3fcfbff9a370d6b2335801b9496dc96c5a62e8","impliedFormat":99},{"version":"2f39d9c725a4dd1f26c2f5d6af77de6825c3b001e659a19f8c5709ab4dfffbc2","impliedFormat":99},{"version":"3249978af88001a58011c3173f6f9b481623774b521e61771d0ea505858f8c0c","impliedFormat":99},{"version":"357acf3f929fb414980bdba75b3616589e97b193f82b20c4f4ee57b1d92cff78","impliedFormat":99},{"version":"51cfee533df6cb5f5702b8552c36579c0c20af8f2802fa594bdc07a068d81312","impliedFormat":99},{"version":"51cfee533df6cb5f5702b8552c36579c0c20af8f2802fa594bdc07a068d81312","impliedFormat":99},{"version":"1a7455947818b4bcd9197f667223bd5cf863180590db6acec69dcc245fd926ca","impliedFormat":99},{"version":"51cfee533df6cb5f5702b8552c36579c0c20af8f2802fa594bdc07a068d81312","impliedFormat":99},{"version":"51cfee533df6cb5f5702b8552c36579c0c20af8f2802fa594bdc07a068d81312","impliedFormat":99},{"version":"a5fb5ce40e0e5784a1f1ee448fe3a22e3da2e15fb1d4a4c7ee327e87c71f63fa","impliedFormat":99},{"version":"ea8d4e74ed1d1afa079928b6111a79c4f280b235d939b582891b60d5d78eeddc","impliedFormat":99},{"version":"1414d676ead5662c2478739618fe5d9e59511ea6e855b4a74eae6f99cf84521a","impliedFormat":99},{"version":"1a7455947818b4bcd9197f667223bd5cf863180590db6acec69dcc245fd926ca","impliedFormat":99},{"version":"51cfee533df6cb5f5702b8552c36579c0c20af8f2802fa594bdc07a068d81312","impliedFormat":99},{"version":"21a1e454b803f024e69b46be8e4559c639120197cd9727cfe030d1bb7b1579ef","impliedFormat":99},{"version":"25a35008dfcd38563e6bc893f7979c8d4dfdc12ec37a0b1dae9877dea5d6551f","impliedFormat":99},"4cb44a264a70e1939e3f3e0ef7102468c7cc8efa92816e238db107af3fdca6e3",{"version":"151ff381ef9ff8da2da9b9663ebf657eac35c4c9a19183420c05728f31a6761d","impliedFormat":1},{"version":"f3d8c757e148ad968f0d98697987db363070abada5f503da3c06aefd9d4248c1","impliedFormat":1},{"version":"a4a39b5714adfcadd3bbea6698ca2e942606d833bde62ad5fb6ec55f5e438ff8","impliedFormat":1},{"version":"bbc1d029093135d7d9bfa4b38cbf8761db505026cc458b5e9c8b74f4000e5e75","impliedFormat":1},{"version":"1f68ab0e055994eb337b67aa87d2a15e0200951e9664959b3866ee6f6b11a0fe","impliedFormat":1},{"version":"0e60e0cbf2283adfd5a15430ae548cd2f662d581b5da6ecd98220203e7067c70","impliedFormat":1},{"version":"736097ddbb2903bef918bb3b5811ef1c9c5656f2a73bd39b22a91b9cc2525e50","impliedFormat":1},{"version":"4340936f4e937c452ae783514e7c7bbb7fc06d0c97993ff4865370d0962bb9cf","impliedFormat":1},{"version":"b70c7ea83a7d0de17a791d9b5283f664033a96362c42cc4d2b2e0bdaa65ef7d1","impliedFormat":1}],"root":[418,[426,428],595,[598,604],[713,719],[729,737],747,748,777,778,[780,788],[891,900],[918,950],[1057,1060],[1081,1100],1120],"options":{"emitDecoratorMetadata":true,"esModuleInterop":true,"experimentalDecorators":true,"module":1,"skipLibCheck":true,"sourceMap":true,"strict":true,"target":9},"referencedMap":[[413,1],[412,2],[789,3],[791,3],[792,4],[790,3],[812,5],[796,6],[810,3],[817,7],[813,3],[811,6],[814,6],[815,6],[797,8],[795,9],[816,10],[809,11],[798,3],[806,3],[805,3],[799,3],[804,3],[807,3],[800,6],[801,3],[808,12],[802,3],[803,3],[889,13],[887,14],[890,15],[888,6],[818,3],[823,16],[825,17],[853,18],[851,19],[852,20],[854,21],[841,22],[843,3],[848,23],[824,3],[847,24],[833,25],[844,3],[845,3],[840,26],[849,27],[838,28],[839,29],[846,25],[861,30],[850,31],[875,32],[876,33],[873,34],[860,33],[856,35],[879,32],[855,36],[872,37],[881,38],[878,39],[837,40],[874,3],[857,41],[858,42],[871,35],[880,43],[870,44],[877,33],[859,45],[826,3],[829,46],[828,46],[830,47],[832,48],[831,3],[827,49],[883,50],[882,3],[884,51],[885,52],[864,53],[862,54],[866,54],[865,54],[867,55],[868,53],[863,3],[869,56],[886,57],[779,3],[842,3],[422,58],[423,59],[424,60],[420,61],[421,62],[425,63],[959,3],[327,3],[65,3],[316,64],[317,64],[318,3],[319,65],[329,66],[320,3],[321,67],[322,3],[323,3],[324,64],[325,64],[326,64],[328,68],[336,69],[338,3],[335,3],[341,70],[339,3],[337,3],[333,71],[334,72],[340,3],[342,73],[330,3],[332,74],[331,75],[271,3],[274,76],[270,3],[1006,3],[272,3],[273,3],[359,77],[344,77],[351,77],[348,77],[361,77],[352,77],[358,77],[343,78],[362,77],[365,79],[356,77],[346,77],[364,77],[349,77],[347,77],[357,77],[353,77],[363,77],[350,77],[360,77],[345,77],[355,77],[354,77],[372,80],[368,81],[367,3],[366,3],[371,82],[410,83],[66,3],[67,3],[68,3],[988,84],[70,85],[994,86],[993,87],[260,88],[261,85],[381,3],[290,3],[291,3],[382,89],[262,3],[383,3],[384,90],[69,3],[264,91],[265,3],[263,92],[266,91],[267,3],[269,93],[281,94],[282,3],[287,95],[283,3],[284,3],[285,3],[286,3],[288,3],[289,96],[295,97],[298,98],[296,3],[297,3],[315,99],[299,3],[300,3],[1037,100],[280,101],[278,102],[276,103],[277,104],[279,3],[307,105],[301,3],[310,106],[303,107],[308,108],[306,109],[309,110],[304,111],[305,112],[293,113],[311,114],[294,115],[313,116],[314,117],[302,3],[268,3],[275,118],[312,119],[378,120],[373,3],[379,121],[374,122],[375,123],[376,124],[377,125],[380,126],[396,127],[395,128],[401,129],[393,3],[394,130],[397,127],[398,131],[400,132],[399,133],[402,134],[387,135],[388,136],[391,137],[390,137],[389,136],[392,136],[386,138],[404,139],[403,140],[406,141],[405,142],[407,143],[369,113],[370,144],[292,3],[408,145],[385,146],[409,147],[957,148],[958,149],[979,150],[980,151],[981,3],[982,152],[983,153],[992,154],[985,155],[989,156],[997,157],[995,65],[996,158],[986,159],[998,3],[1000,160],[1001,161],[1002,162],[991,163],[987,164],[1011,165],[999,166],[1026,167],[984,168],[1027,169],[1024,170],[1025,65],[1049,171],[974,172],[970,173],[972,174],[1023,175],[965,176],[1013,177],[1012,3],[973,178],[1020,179],[977,180],[1021,3],[1022,181],[975,182],[969,183],[976,184],[971,185],[964,3],[1017,186],[1030,187],[1028,65],[960,65],[1016,188],[961,72],[962,151],[963,189],[967,190],[966,191],[1029,192],[968,193],[1005,194],[1003,160],[1004,195],[1014,72],[1015,196],[1018,197],[1033,198],[1034,199],[1031,200],[1032,201],[1035,202],[1036,203],[1038,204],[1010,205],[1007,206],[1008,64],[1009,195],[1040,207],[1039,208],[1046,209],[978,65],[1042,210],[1041,65],[1044,211],[1043,3],[1045,212],[990,213],[1019,214],[1048,215],[1047,65],[744,216],[740,217],[739,218],[741,3],[742,219],[743,220],[745,221],[727,222],[722,223],[720,65],[723,223],[724,223],[725,223],[726,65],[721,3],[728,224],[1064,225],[1065,226],[1079,227],[1067,228],[1066,229],[1061,230],[1062,3],[1063,3],[1078,231],[1069,232],[1070,232],[1071,232],[1072,232],[1074,233],[1073,232],[1075,234],[1076,235],[1068,3],[1077,236],[768,237],[771,238],[769,3],[770,3],[749,3],[750,239],[775,240],[772,3],[773,241],[774,237],[776,242],[1056,243],[954,244],[1053,3],[951,3],[952,245],[955,246],[956,65],[1050,247],[953,248],[1051,249],[1052,250],[1054,251],[1055,3],[414,252],[411,3],[711,253],[710,254],[1125,255],[1124,256],[1123,257],[1121,3],[707,258],[712,259],[708,3],[1122,3],[738,260],[1126,3],[760,261],[753,262],[757,263],[755,264],[758,265],[756,266],[759,267],[754,3],[752,268],[751,269],[703,3],[1080,270],[1128,3],[1129,271],[650,272],[651,272],[652,273],[610,274],[653,275],[654,276],[655,277],[605,3],[608,278],[606,3],[607,3],[656,279],[657,280],[658,281],[659,282],[660,283],[661,284],[662,284],[664,3],[663,285],[665,286],[666,287],[667,288],[649,289],[609,3],[668,290],[669,291],[670,292],[702,293],[671,294],[672,295],[673,296],[674,297],[675,298],[676,299],[677,300],[678,301],[679,302],[680,303],[681,303],[682,304],[683,3],[684,305],[686,306],[685,307],[687,308],[688,309],[689,310],[690,311],[691,312],[692,313],[693,314],[694,315],[695,316],[696,317],[697,318],[698,319],[699,320],[700,321],[701,322],[794,323],[705,3],[706,3],[704,324],[709,325],[793,3],[471,326],[462,3],[463,3],[464,3],[465,3],[466,3],[467,3],[468,3],[469,3],[470,3],[419,3],[611,3],[1102,327],[1106,328],[1104,3],[1119,329],[1108,330],[1105,331],[1107,332],[1117,330],[1109,330],[1110,330],[1112,330],[1111,330],[1116,330],[1118,330],[1114,330],[1113,330],[1115,333],[1103,334],[1101,3],[585,335],[586,335],[587,335],[593,336],[588,335],[589,335],[590,335],[591,335],[592,335],[576,337],[575,3],[594,338],[582,3],[578,339],[569,3],[568,3],[570,3],[571,335],[572,340],[584,341],[573,335],[574,335],[579,342],[580,343],[581,335],[577,3],[583,3],[432,3],[434,344],[551,345],[555,345],[554,345],[552,345],[553,345],[556,345],[435,345],[447,345],[436,345],[449,345],[451,345],[444,345],[445,345],[446,345],[450,345],[452,345],[437,345],[448,345],[438,345],[440,346],[441,345],[442,345],[443,345],[459,345],[458,345],[559,347],[453,345],[455,345],[454,345],[456,345],[457,345],[558,345],[557,345],[460,345],[472,348],[473,348],[475,345],[520,345],[519,345],[540,345],[476,348],[517,345],[521,345],[477,345],[478,345],[479,348],[522,345],[516,348],[474,348],[523,345],[480,348],[524,345],[481,348],[504,345],[482,345],[525,345],[483,345],[514,348],[485,345],[486,345],[526,345],[488,345],[490,345],[491,345],[497,345],[498,345],[492,348],[528,345],[515,348],[527,348],[493,345],[494,345],[529,345],[495,345],[487,348],[530,345],[513,345],[531,345],[496,348],[499,345],[500,345],[518,348],[532,345],[533,345],[512,349],[489,345],[534,348],[535,345],[536,345],[537,345],[538,348],[501,345],[539,345],[503,348],[505,345],[502,348],[484,345],[506,345],[509,345],[507,345],[508,345],[461,345],[542,345],[541,345],[549,345],[543,345],[544,345],[546,345],[547,345],[545,345],[550,345],[548,345],[567,350],[565,351],[566,352],[564,353],[563,345],[562,354],[431,3],[433,3],[429,3],[560,3],[561,355],[439,344],[430,3],[762,3],[761,3],[767,356],[763,357],[766,358],[765,359],[764,3],[417,360],[416,361],[415,3],[597,362],[596,363],[1127,364],[511,365],[510,3],[822,366],[821,3],[746,3],[819,367],[834,254],[836,368],[820,3],[64,3],[259,369],[232,3],[210,370],[208,370],[123,371],[74,372],[73,373],[209,374],[194,375],[116,376],[72,377],[71,378],[258,373],[223,379],[222,379],[134,380],[230,371],[231,371],[233,381],[234,371],[235,378],[236,371],[207,371],[237,371],[238,382],[239,371],[240,379],[241,383],[242,371],[243,371],[244,371],[245,371],[246,379],[247,371],[248,371],[249,371],[250,371],[251,384],[252,371],[253,371],[254,371],[255,371],[256,371],[76,378],[77,378],[78,378],[79,378],[80,378],[81,378],[82,378],[83,371],[85,385],[86,378],[84,378],[87,378],[88,378],[89,378],[90,378],[91,378],[92,378],[93,371],[94,378],[95,378],[96,378],[97,378],[98,378],[99,371],[100,378],[101,378],[102,378],[103,378],[104,378],[105,378],[106,371],[108,386],[107,378],[109,378],[110,378],[111,378],[112,378],[113,384],[114,371],[115,371],[129,387],[117,388],[118,378],[119,378],[120,371],[121,378],[122,378],[124,389],[125,378],[126,378],[127,378],[128,378],[130,378],[131,378],[132,378],[133,378],[135,390],[136,378],[137,378],[138,378],[139,371],[140,378],[141,391],[142,391],[143,391],[144,371],[145,378],[146,378],[147,378],[152,378],[148,378],[149,371],[150,378],[151,371],[153,378],[154,378],[155,378],[156,378],[157,378],[158,378],[159,371],[160,378],[161,378],[162,378],[163,378],[164,378],[165,378],[166,378],[167,378],[168,378],[169,378],[170,378],[171,378],[172,378],[173,378],[174,378],[175,378],[176,392],[177,378],[178,378],[179,378],[180,378],[181,378],[182,378],[183,371],[184,371],[185,371],[186,371],[187,371],[188,378],[189,378],[190,378],[191,378],[257,371],[193,393],[216,394],[211,394],[202,395],[200,396],[214,397],[203,398],[217,399],[212,400],[213,397],[215,401],[201,3],[206,3],[198,402],[199,403],[196,3],[197,404],[195,378],[204,405],[75,406],[224,3],[225,3],[226,3],[227,3],[228,3],[229,3],[218,3],[221,379],[220,3],[219,407],[192,408],[205,409],[835,367],[61,3],[62,3],[12,3],[10,3],[11,3],[16,3],[15,3],[2,3],[17,3],[18,3],[19,3],[20,3],[21,3],[22,3],[23,3],[24,3],[3,3],[25,3],[26,3],[4,3],[27,3],[31,3],[28,3],[29,3],[30,3],[32,3],[33,3],[34,3],[5,3],[35,3],[36,3],[37,3],[38,3],[6,3],[42,3],[39,3],[40,3],[41,3],[43,3],[7,3],[44,3],[49,3],[50,3],[45,3],[46,3],[47,3],[48,3],[8,3],[54,3],[51,3],[52,3],[53,3],[55,3],[9,3],[56,3],[63,3],[57,3],[58,3],[60,3],[59,3],[1,3],[14,3],[13,3],[627,410],[637,411],[626,410],[647,412],[618,413],[617,414],[646,415],[640,416],[645,417],[620,418],[634,419],[619,420],[643,421],[615,422],[614,415],[644,423],[616,424],[621,425],[622,3],[625,425],[612,3],[648,426],[638,427],[629,428],[630,429],[632,430],[628,431],[631,432],[641,415],[623,433],[624,434],[633,435],[613,436],[636,427],[635,425],[639,3],[642,437],[917,438],[902,3],[903,3],[904,3],[905,3],[901,3],[906,439],[907,3],[909,440],[908,439],[910,439],[911,440],[912,439],[913,3],[914,439],[915,3],[916,3],[1084,441],[944,442],[945,443],[943,444],[941,3],[942,445],[1086,3],[748,446],[778,447],[747,448],[777,449],[1082,450],[1083,451],[1081,452],[713,65],[714,453],[599,454],[732,455],[428,456],[1087,3],[1088,457],[1089,3],[1059,458],[1060,459],[1058,460],[1090,3],[1057,3],[1091,461],[1092,3],[782,3],[783,462],[1093,3],[784,463],[787,464],[781,465],[1094,3],[780,3],[893,3],[785,3],[786,466],[715,467],[737,468],[604,469],[1085,470],[418,3],[717,471],[718,472],[426,473],[716,453],[427,474],[946,3],[947,475],[1095,3],[949,476],[950,477],[948,478],[595,479],[598,3],[731,480],[733,481],[600,482],[719,3],[729,483],[1096,3],[730,484],[736,485],[603,486],[734,487],[601,488],[735,489],[602,490],[924,491],[899,492],[891,493],[894,494],[900,495],[922,496],[897,497],[923,498],[920,499],[898,498],[1097,3],[936,500],[937,501],[1098,3],[918,502],[932,503],[933,504],[930,505],[931,506],[925,507],[934,508],[788,65],[927,3],[895,3],[896,3],[929,3],[892,3],[928,3],[1099,3],[1100,3],[926,3],[1120,509],[935,3],[919,3],[921,3],[939,510],[940,511],[938,512]],"affectedFilesPendingEmit":[1084,944,945,943,941,942,1086,748,778,747,777,1082,1083,1081,713,714,599,732,428,1087,1088,1089,1059,1060,1058,1090,1057,1091,1092,782,783,1093,784,787,781,1094,780,893,785,786,715,737,604,1085,418,717,718,426,716,427,946,947,1095,949,950,948,595,598,731,733,600,719,729,1096,730,736,603,734,601,735,602,924,899,891,894,900,922,897,923,920,898,1097,936,937,1098,918,932,933,930,931,925,934,788,927,895,896,929,892,928,1099,1100,926,1120,935,919,921,939,940,938],"version":"5.8.3"} \ No newline at end of file