├── example.env ├── CODE_OF_CONDUCT.md ├── .snyk ├── .gitignore ├── .dockerignore ├── frontend ├── .gitignore ├── vite.config.js ├── package.json ├── pnpm-lock.yaml ├── index.html └── main.js ├── fly.toml ├── deepgram.toml ├── .npmrc ├── LICENSE ├── Dockerfile ├── package.json ├── README.md ├── SECURITY.md ├── CONTRIBUTING.md ├── server.js └── pnpm-lock.yaml /example.env: -------------------------------------------------------------------------------- 1 | DEEPGRAM_API_KEY=%api_key% 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | This project follows Deepgram's Code of Conduct. You can find the full text of our Code of Conduct on our website at: 4 | 5 | https://dpgr.am/coc 6 | 7 | For any questions or to report violations, please contact Deepgram Developer Relations at devrel@deepgram.com. -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.25.0 3 | 4 | # Empty ignore ensures all vulnerabilities are detected 5 | # {} not needed, When Snyk parses the .snyk file, it sees an empty ignore section and proceeds to report all vulnerabilities. 6 | ignore: 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /frontend/node_modules 6 | /.pnp 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | /frontend/dist 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | config.json 28 | 29 | .env -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /frontend/node_modules 6 | /.pnp 7 | .pnp.js 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | /frontend/dist 15 | 16 | # misc 17 | .DS_Store 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | config.json 28 | 29 | .env -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | 4 | # Build outputs 5 | dist/ 6 | build/ 7 | 8 | # Environment files 9 | .env 10 | .env.local 11 | .env.*.local 12 | 13 | # Editor directories and files 14 | .vscode/* 15 | !.vscode/extensions.json 16 | .idea 17 | .DS_Store 18 | *.suo 19 | *.ntvs* 20 | *.njsproj 21 | *.sln 22 | *.sw? 23 | 24 | # Logs 25 | *.log 26 | npm-debug.log* 27 | yarn-debug.log* 28 | yarn-error.log* 29 | pnpm-debug.log* 30 | 31 | # Temporary files 32 | *.tmp 33 | .cache/ 34 | 35 | -------------------------------------------------------------------------------- /frontend/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | 3 | export default defineConfig({ 4 | root: '.', 5 | server: { 6 | port: 8081, 7 | open: false, 8 | host: true 9 | }, 10 | preview: { 11 | port: 8081, 12 | open: true, 13 | host: true 14 | }, 15 | build: { 16 | outDir: 'dist', 17 | emptyOutDir: true, 18 | rollupOptions: { 19 | output: { 20 | entryFileNames: 'assets/[name].js', 21 | chunkFileNames: 'assets/[name].js', 22 | assetFileNames: 'assets/[name].[ext]' 23 | } 24 | } 25 | } 26 | }); 27 | 28 | -------------------------------------------------------------------------------- /fly.toml: -------------------------------------------------------------------------------- 1 | # fly.toml app configuration file generated for deepgram-dx-starters-node-transcription on 2025-11-09T12:12:03Z 2 | # 3 | # See https://fly.io/docs/reference/configuration/ for information about how to use this file. 4 | # 5 | 6 | app = 'deepgram-dx-starters-node-transcription' 7 | primary_region = 'lhr' 8 | 9 | [build] 10 | 11 | [http_service] 12 | internal_port = 3000 13 | force_https = true 14 | auto_stop_machines = 'stop' 15 | auto_start_machines = true 16 | min_machines_running = 0 17 | processes = ['app'] 18 | 19 | [[vm]] 20 | memory = '1gb' 21 | cpu_kind = 'shared' 22 | cpus = 1 23 | -------------------------------------------------------------------------------- /deepgram.toml: -------------------------------------------------------------------------------- 1 | [meta] 2 | title = "Node Transcription Starter" 3 | description = "Get started using Deepgram's Transcription with this Node demo app" 4 | author = "Deepgram DX Team (https://developers.deepgram.com)" 5 | useCase = "STT" 6 | language = "JavaScript" 7 | framework = "Node" 8 | 9 | [pre-build] 10 | command = "pnpm run install:all" 11 | message = "Dependencies installed (root + frontend)" 12 | 13 | [build] 14 | command = "pnpm build" 15 | message = "Build completed" 16 | 17 | [build.config] 18 | sample = "example.env" 19 | output = ".env" 20 | 21 | [post-build] 22 | message = "Run `pnpm start` to get up and running." 23 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | # Package Manager Configuration 2 | # Force pnpm usage - breaks npm/yarn intentionally 3 | node-linker=pnpm 4 | 5 | # Security: Disable all lifecycle scripts 6 | ignore-scripts=true 7 | enable-pre-post-scripts=false 8 | 9 | # Security: Require packages to be 10+ days old before installation 10 | minimum-release-age=14400 11 | 12 | # Security: Verify package integrity hashes 13 | verify-store-integrity=true 14 | 15 | # Security: Enforce strict trust policies 16 | trust-policy=strict 17 | 18 | # Security: Strict peer dependency resolution 19 | strict-peer-dependencies=true 20 | 21 | # Performance: Use symlinks for node_modules 22 | symlink=true 23 | 24 | # Lockfile: Ensure lockfile is not modified during install 25 | frozen-lockfile=false 26 | 27 | -------------------------------------------------------------------------------- /frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deepgram/transcription-html", 3 | "version": "0.0.1", 4 | "private": true, 5 | "description": "Minimal HTML starter with Deepgram design system styles", 6 | "main": "index.html", 7 | "type": "module", 8 | "scripts": { 9 | "dev": "vite", 10 | "build": "vite build", 11 | "preview": "vite preview" 12 | }, 13 | "keywords": [ 14 | "deepgram", 15 | "speech-to-text", 16 | "transcription", 17 | "html", 18 | "javascript", 19 | "css", 20 | "audio", 21 | "voice-recognition" 22 | ], 23 | "author": "Deepgram Starter UIs Team", 24 | "license": "MIT", 25 | "repository": { 26 | "type": "git", 27 | "url": "https://github.com/deepgram/starter-uis.git", 28 | "directory": "apps/transcription-html" 29 | }, 30 | "engines": { 31 | "node": ">=14.0.0" 32 | }, 33 | "browserslist": [ 34 | "defaults", 35 | "not ie 11", 36 | "not op_mini all" 37 | ], 38 | "dependencies": { 39 | "@deepgram/styles": "latest" 40 | }, 41 | "devDependencies": { 42 | "vite": "^7.2.2" 43 | } 44 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Deepgram Templates 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1 2 | 3 | # Adjust NODE_VERSION as desired 4 | ARG NODE_VERSION=24.4.1 5 | FROM node:${NODE_VERSION}-slim AS base 6 | 7 | LABEL fly_launch_runtime="Node.js" 8 | 9 | # Node.js app lives here 10 | WORKDIR /app 11 | 12 | # Set production environment 13 | ENV NODE_ENV="production" 14 | 15 | # Install pnpm 16 | ARG PNPM_VERSION=10.14.0 17 | RUN npm install -g pnpm@$PNPM_VERSION 18 | 19 | 20 | # Throw-away build stage to reduce size of final image 21 | FROM base AS build 22 | 23 | # Install packages needed to build node modules 24 | RUN apt-get update -qq && \ 25 | apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 26 | 27 | # Install node modules 28 | COPY .npmrc package.json pnpm-lock.yaml ./ 29 | COPY frontend/.npmrc frontend/package.json frontend/pnpm-lock.yaml frontend/ 30 | # Install root dependencies 31 | RUN pnpm install --frozen-lockfile --prod=false 32 | # Install frontend dependencies separately (postinstall scripts disabled for security) 33 | RUN cd frontend && pnpm install --frozen-lockfile --prod=false && cd .. 34 | 35 | # Copy application code (including .npmrc for security settings) 36 | COPY . . 37 | 38 | # Build application 39 | RUN pnpm run build 40 | 41 | # Remove development dependencies 42 | RUN pnpm prune --prod 43 | 44 | 45 | # Final stage for app image 46 | FROM base 47 | 48 | # Copy built application 49 | COPY --from=build /app /app 50 | 51 | # Start the server by default, this can be overwritten at runtime 52 | EXPOSE 3000 53 | CMD [ "pnpm", "run", "start" ] 54 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deepgram/prerecorded-node-starter", 3 | "version": "0.0.1", 4 | "private": true, 5 | "packageManager": "pnpm@10.0.0", 6 | "engines": { 7 | "node": ">=24.0.0", 8 | "pnpm": ">=10.0.0" 9 | }, 10 | "scripts": { 11 | "install:all": "pnpm install && cd frontend && pnpm install && cd ..", 12 | "install:frontend": "cd frontend && pnpm install && cd ..", 13 | "build": "cd frontend && pnpm run build", 14 | "start": "node --no-deprecation server.js", 15 | "dev": "npm-run-all --parallel dev:backend dev:frontend", 16 | "dev:backend": "NODE_ENV=development nodemon --no-deprecation server.js", 17 | "dev:frontend": "cd frontend && pnpm run dev -- --no-open --logLevel error", 18 | "security-check": "snyk test --severity-threshold=low --package-manager=pnpm --fail-on=all", 19 | "security-check:all": "pnpm run security-check && cd frontend && pnpm run security-check && cd .." 20 | }, 21 | "dependencies": { 22 | "@deepgram/sdk": "4.11.2", 23 | "cors": "2.8.5", 24 | "dotenv": "17.2.3", 25 | "express": "5.2.1", 26 | "http-proxy-middleware": "3.0.5", 27 | "multer": "2.0.2", 28 | "npm-run-all": "4.1.5" 29 | }, 30 | "devDependencies": { 31 | "@flydotio/dockerfile": "0.7.10", 32 | "nodemon": "3.1.10" 33 | }, 34 | "browserslist": { 35 | "production": [ 36 | ">0.2%", 37 | "not dead", 38 | "not op_mini all" 39 | ], 40 | "development": [ 41 | "last 1 chrome version", 42 | "last 1 firefox version", 43 | "last 1 safari version" 44 | ] 45 | } 46 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node Transcription Starter 2 | 3 | Speech-to-text demo using Deepgram's API with Node.js backend and web frontend. 4 | 5 | ## Prerequisites 6 | 7 | - [Deepgram API Key](https://console.deepgram.com/signup?jump=keys) (sign up for free) 8 | - Node.js 24+ and pnpm 10+ 9 | 10 | **Note:** This project uses strict supply chain security measures. npm and yarn will NOT work - pnpm 10.0.0+ is required. See [SECURITY.md](SECURITY.md) for details. 11 | 12 | ## Quick Start 13 | 14 | 1. **Install dependencies** 15 | 16 | ```bash 17 | # Option 1: Use the helper script (recommended) 18 | pnpm run install:all 19 | 20 | # Option 2: Manual two-step install 21 | pnpm install 22 | cd frontend && pnpm install && cd .. 23 | ``` 24 | 25 | **Note:** Due to security settings (`ignore-scripts=true`), frontend dependencies must be installed separately. The `install:all` script handles both steps. See [SECURITY.md](SECURITY.md) for details. 26 | 27 | 2. **Set your API key** 28 | 29 | Create a `.env` file: 30 | 31 | ```bash 32 | DEEPGRAM_API_KEY=your_api_key_here 33 | ``` 34 | 35 | 3. **Run the app** 36 | 37 | **Development mode** (with hot reload): 38 | 39 | ```bash 40 | pnpm dev 41 | ``` 42 | 43 | **Production mode** (build and serve): 44 | 45 | ```bash 46 | pnpm build 47 | pnpm start 48 | ``` 49 | 50 | Open [http://localhost:3000](http://localhost:3000) 51 | 52 | ## Features 53 | 54 | - Upload audio files or provide URLs for transcription 55 | - Multiple model options 56 | - View transcription history 57 | - Responsive web interface 58 | 59 | ## How It Works 60 | 61 | - **Backend** (`server.js`): Node.js/Express server implementing the `/stt/transcribe` endpoint 62 | - **Frontend** (`frontend/`): Vite-powered web UI for audio upload and transcription display 63 | - **API**: Integrates with [Deepgram's Speech-to-Text API](https://developers.deepgram.com/) 64 | 65 | ## Security 66 | 67 | This project implements comprehensive supply chain security measures including: 68 | - Dependency pinning to exact versions 69 | - Automated vulnerability scanning with Snyk 70 | - Disabled lifecycle scripts 71 | - Strict package manager enforcement (pnpm only) 72 | 73 | See [SECURITY.md](SECURITY.md) for complete security documentation and reporting procedures. 74 | 75 | ## Contributing 76 | 77 | Contributions are welcome! Please review: 78 | - [Contributing Guidelines](CONTRIBUTING.md) - includes pnpm setup requirements 79 | - [Code of Conduct](CODE_OF_CONDUCT.md) 80 | - [Security Policy](SECURITY.md) - required for dependency updates 81 | 82 | ## Getting Help 83 | 84 | - [Open an issue](https://github.com/deepgram-starters/node-transcription/issues) 85 | - [Join our Discord](https://discord.gg/xWRaCDBtW4) 86 | - [Deepgram Documentation](https://developers.deepgram.com/) 87 | 88 | ## License 89 | 90 | MIT - See [LICENSE](./LICENSE) 91 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | Deepgram's security policy can be found on our main website. 4 | 5 | [Deepgram Security Policy](https://developers.deepgram.com/documentation/security/security-policy/) 6 | 7 | ## Supply Chain Security 8 | 9 | This project implements comprehensive supply chain security measures to protect against vulnerabilities in dependencies. 10 | 11 | ### Package Manager Security 12 | 13 | **pnpm 10.0.0+ is required** - this project will not work with npm or yarn. 14 | 15 | Security configurations (`.npmrc`): 16 | - `ignore-scripts=true` - All lifecycle scripts are disabled to prevent malicious code execution 17 | - `enable-pre-post-scripts=false` - Pre/post install scripts are blocked 18 | - `minimum-release-age=14400` - Packages must be 10+ days old before installation (4-hour minimum in minutes) 19 | - `verify-store-integrity=true` - Package integrity hashes are verified 20 | - `trust-policy=strict` - Strict trust policies enforced 21 | - `strict-peer-dependencies=true` - Strict peer dependency resolution 22 | 23 | ### Dependency Pinning Strategy 24 | 25 | All dependencies are pinned to exact versions (no `^` or `~` ranges) to ensure: 26 | - Reproducible builds across all environments 27 | - No unexpected updates that could introduce vulnerabilities 28 | - Full control over dependency updates 29 | 30 | Updates to dependencies should be: 31 | 1. Tested thoroughly in development 32 | 2. Scanned for security vulnerabilities 33 | 3. Reviewed before merging to main 34 | 35 | ### Snyk Integration 36 | 37 | This project uses [Snyk](https://snyk.io) for continuous security monitoring: 38 | 39 | **Local Security Checks:** 40 | ```bash 41 | # Run security scan on root project 42 | pnpm run security-check 43 | 44 | # Run security scan on frontend 45 | cd frontend && pnpm run security-check 46 | 47 | # Scan all projects 48 | snyk test --all-projects --severity-threshold=low --package-manager=pnpm 49 | ``` 50 | 51 | **CI/CD Integration:** 52 | - All pushes to `main` trigger automated Snyk security scans 53 | - Build fails if any vulnerabilities are detected (severity threshold: low) 54 | - Security scan runs before deployment 55 | 56 | **Required Secret:** 57 | - `SNYK_TOKEN` must be configured in GitHub repository secrets 58 | 59 | ### Lockfile Protection 60 | 61 | The `pnpm-lock.yaml` file is protected: 62 | - CI uses `--frozen-lockfile` flag to prevent modifications 63 | - Any lockfile changes must be committed explicitly 64 | - Ensures consistency between development and production 65 | 66 | ### Vulnerability Overrides 67 | 68 | Known vulnerabilities are patched using `pnpm.overrides` in `package.json`: 69 | - Overrides force safe versions of transitive dependencies 70 | - Documented in package.json for transparency 71 | 72 | ### Reporting Security Issues 73 | 74 | If you discover a security vulnerability in this project: 75 | 76 | 1. **Do NOT** open a public GitHub issue 77 | 2. Email security concerns to: security@deepgram.com 78 | 3. Include detailed information about the vulnerability 79 | 4. Allow reasonable time for response before public disclosure 80 | 81 | We take security seriously and will respond promptly to legitimate security concerns. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | We welcome contributions! Before adding new functionality, open an issue first. Bug reports, fixes, and feedback are always appreciated. 4 | 5 | Please take the time to review the [Code of Conduct](CODE_OF_CONDUCT.md), which all contributors are subject to on this project. 6 | 7 | ## Prerequisites 8 | 9 | **Required:** 10 | - **Node.js 24.0.0+** 11 | - **pnpm 10.0.0+** (npm and yarn will NOT work due to security configurations) 12 | 13 | **Installation:** 14 | ```bash 15 | # Install pnpm globally if not already installed 16 | npm install -g pnpm@10.0.0 17 | 18 | # Install all dependencies (recommended) 19 | pnpm run install:all 20 | 21 | # Or install manually in two steps: 22 | pnpm install # Install root dependencies 23 | pnpm run install:frontend # Install frontend dependencies 24 | ``` 25 | 26 | **Important:** This project uses strict security measures: 27 | - All lifecycle scripts are disabled (`ignore-scripts=true`) 28 | - Dependencies are pinned to exact versions 29 | - Using npm or yarn will fail intentionally 30 | - Frontend must be installed separately due to blocked postinstall scripts 31 | - Use `install:all` helper script for convenience 32 | 33 | ## Reporting Bugs 34 | 35 | Before submitting a bug report: 36 | - Search existing issues and comment if one exists instead of creating a duplicate. 37 | 38 | When submitting a bug report: 39 | - Use a clear title 40 | - List exact steps to reproduce the issue 41 | - Provide examples, links, or code snippets 42 | - Describe observed vs. expected behavior 43 | - Include screenshots or GIFs 44 | - For macOS and Windows: [LICEcap](https://www.cockos.com/licecap/) 45 | - For Linux: [Silentcast](https://github.com/colinkeenan/silentcast) 46 | - Mention if the issue is consistent or intermittent and share environment details 47 | 48 | ## Suggesting Enhancements 49 | 50 | Before submitting an enhancement: 51 | - Search existing suggestions and comment on one instead of creating a duplicate. 52 | 53 | When submitting an enhancement: 54 | - Use a clear title 55 | - Describe the enhancement step-by-step 56 | - Provide examples or code snippets 57 | - Explain current vs. expected behavior and its benefits 58 | 59 | ## First Time Contributors 60 | 61 | Check `beginner` and `help-wanted` issues to get started. 62 | 63 | ## Pull Requests 64 | 65 | Please follow these steps: 66 | 1. Use the Pull Request template 67 | 2. Follow the [Code of Conduct](CODE_OF_CONDUCT.md) 68 | 3. Run security checks locally before submitting: 69 | ```bash 70 | pnpm run security-check 71 | ``` 72 | 4. Ensure all [status checks](https://help.github.com/articles/about-status-checks/) pass before review 73 | - Security scanning (Snyk) must pass 74 | - All dependencies must be pinned to exact versions 75 | - Lockfile changes must be committed if dependencies updated 76 | 77 | Note: Reviewers may request additional changes before merging. 78 | 79 | ## Security Scanning 80 | 81 | All pull requests are automatically scanned for security vulnerabilities using Snyk. PRs will be blocked if: 82 | - Any vulnerabilities are detected (including low severity) 83 | - Dependencies with version ranges (`^`, `~`) are added 84 | - Lockfile is out of sync 85 | 86 | Review the [Security Policy](SECURITY.md) for detailed information about our security practices. 87 | 88 | ## Questions? 89 | 90 | Connect with us through any of these channels: 91 | - [GitHub Discussions](https://github.com/orgs/deepgram/discussions) 92 | - [Discord](https://discord.gg/deepgram) 93 | - [Bluesky](https://bsky.app/profile/deepgram.com) 94 | 95 | For additional guidance, check out [GitHub Flow](https://guides.github.com/introduction/flow/index.html). -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Node Transcription Starter - Backend Server 3 | * 4 | * This is a simple Express server that provides a transcription API endpoint 5 | * powered by Deepgram's Speech-to-Text service. It's designed to be easily 6 | * modified and extended for your own projects. 7 | * 8 | * Key Features: 9 | * - Single API endpoint: POST /stt/transcribe 10 | * - Accepts both file uploads and URLs 11 | * - Proxies to Vite dev server in development 12 | * - Serves static frontend in production 13 | */ 14 | 15 | require("dotenv").config(); 16 | 17 | const { createClient } = require("@deepgram/sdk"); 18 | const { createProxyMiddleware } = require("http-proxy-middleware"); 19 | const express = require("express"); 20 | const multer = require("multer"); 21 | const path = require("path"); 22 | 23 | // ============================================================================ 24 | // CONFIGURATION - Customize these values for your needs 25 | // ============================================================================ 26 | 27 | /** 28 | * Default transcription model to use when none is specified 29 | * Options: "nova-3", "nova-2", "nova", "enhanced", "base" 30 | * See: https://developers.deepgram.com/docs/models-languages-overview 31 | */ 32 | const DEFAULT_MODEL = "nova-3"; 33 | 34 | /** 35 | * Server configuration - These can be overridden via environment variables 36 | */ 37 | const CONFIG = { 38 | port: process.env.PORT || 3000, 39 | host: process.env.HOST || "0.0.0.0", 40 | vitePort: process.env.VITE_PORT || 8081, 41 | isDevelopment: process.env.NODE_ENV === "development", 42 | }; 43 | 44 | // ============================================================================ 45 | // API KEY LOADING - Load Deepgram API key from .env or config.json 46 | // ============================================================================ 47 | 48 | /** 49 | * Loads the Deepgram API key from environment variables or config.json 50 | * Priority: DEEPGRAM_API_KEY env var > config.json > error 51 | */ 52 | function loadApiKey() { 53 | // Try environment variable first (recommended) 54 | let apiKey = process.env.DEEPGRAM_API_KEY; 55 | 56 | // Fall back to config.json if it exists 57 | if (!apiKey) { 58 | try { 59 | const config = require("./config.json"); 60 | apiKey = config.dgKey; 61 | } catch (err) { 62 | // config.json doesn't exist or is invalid - that's ok 63 | } 64 | } 65 | 66 | // Exit with helpful error if no API key found 67 | if (!apiKey) { 68 | console.error("\n❌ ERROR: Deepgram API key not found!\n"); 69 | console.error("Please set your API key using one of these methods:\n"); 70 | console.error("1. Create a .env file (recommended):"); 71 | console.error(" DEEPGRAM_API_KEY=your_api_key_here\n"); 72 | console.error("2. Environment variable:"); 73 | console.error(" export DEEPGRAM_API_KEY=your_api_key_here\n"); 74 | console.error("3. Create a config.json file:"); 75 | console.error(" cp config.json.example config.json"); 76 | console.error(" # Then edit config.json with your API key\n"); 77 | console.error("Get your API key at: https://console.deepgram.com\n"); 78 | process.exit(1); 79 | } 80 | 81 | return apiKey; 82 | } 83 | 84 | const apiKey = loadApiKey(); 85 | 86 | // ============================================================================ 87 | // SETUP - Initialize Express, Deepgram, and middleware 88 | // ============================================================================ 89 | 90 | // Initialize Deepgram client 91 | const deepgram = createClient(apiKey); 92 | 93 | // Configure Multer for file uploads (stores files in memory) 94 | const storage = multer.memoryStorage(); 95 | const upload = multer({ storage: storage }); 96 | 97 | // Initialize Express app 98 | const app = express(); 99 | 100 | // ============================================================================ 101 | // HELPER FUNCTIONS - Modular logic for easier understanding and testing 102 | // ============================================================================ 103 | 104 | /** 105 | * Validates that either a file or URL was provided in the request 106 | * @param {Object} file - Multer file object 107 | * @param {string} url - URL string from request body 108 | * @returns {Object|null} - Request object for Deepgram, or null if invalid 109 | */ 110 | function validateTranscriptionInput(file, url) { 111 | // URL-based transcription 112 | if (url) { 113 | return { url }; 114 | } 115 | 116 | // File-based transcription 117 | if (file) { 118 | return { buffer: file.buffer, mimetype: file.mimetype }; 119 | } 120 | 121 | // Neither provided 122 | return null; 123 | } 124 | 125 | /** 126 | * Sends a transcription request to Deepgram 127 | * @param {Object} dgRequest - Request object with url OR buffer+mimetype 128 | * @param {string} model - Model name to use (e.g., "nova-3") 129 | * @returns {Promise} - Deepgram API response 130 | */ 131 | async function transcribeAudio(dgRequest, model = DEFAULT_MODEL) { 132 | // URL transcription 133 | if (dgRequest.url) { 134 | return await deepgram.listen.prerecorded.transcribeUrl( 135 | { url: dgRequest.url }, 136 | { model } 137 | ); 138 | } 139 | 140 | // File transcription 141 | return await deepgram.listen.prerecorded.transcribeFile(dgRequest.buffer, { 142 | model, 143 | mimetype: dgRequest.mimetype, 144 | }); 145 | } 146 | 147 | /** 148 | * Formats Deepgram's response into a simplified, consistent structure 149 | * This is where you'd customize the response format for your application 150 | * 151 | * @param {Object} transcriptionResponse - Raw Deepgram API response 152 | * @param {string} modelName - Name of model used for transcription 153 | * @returns {Object} - Formatted response object 154 | */ 155 | function formatTranscriptionResponse(transcriptionResponse, modelName) { 156 | const transcription = transcriptionResponse.result; 157 | const result = transcription?.results?.channels?.[0]?.alternatives?.[0]; 158 | 159 | if (!result) { 160 | throw new Error("No transcription results returned from Deepgram"); 161 | } 162 | 163 | // Build response object 164 | const response = { 165 | transcript: result.transcript || "", 166 | words: result.words || [], 167 | metadata: { 168 | model_uuid: transcription.metadata?.model_uuid, 169 | request_id: transcription.metadata?.request_id, 170 | model_name: modelName, 171 | }, 172 | }; 173 | 174 | // Add optional fields if available 175 | if (transcription.metadata?.duration) { 176 | response.duration = transcription.metadata.duration; 177 | } 178 | 179 | return response; 180 | } 181 | 182 | /** 183 | * Formats error responses in a consistent structure 184 | * @param {Error} error - The error that occurred 185 | * @param {number} statusCode - HTTP status code to return 186 | * @returns {Object} - Formatted error response 187 | */ 188 | function formatErrorResponse(error, statusCode = 500) { 189 | return { 190 | statusCode, 191 | body: { 192 | error: { 193 | type: statusCode === 400 ? "ValidationError" : "TranscriptionError", 194 | code: statusCode === 400 ? "MISSING_INPUT" : "TRANSCRIPTION_FAILED", 195 | message: error.message || "An error occurred during transcription", 196 | details: { 197 | originalError: error.toString(), 198 | }, 199 | }, 200 | }, 201 | }; 202 | } 203 | 204 | // ============================================================================ 205 | // API ROUTES - Define your API endpoints here 206 | // ============================================================================ 207 | 208 | /** 209 | * POST /stt/transcribe 210 | * 211 | * Main transcription endpoint. Accepts either: 212 | * - A file upload (multipart/form-data with 'file' field) 213 | * - A URL to audio file (form data with 'url' field) 214 | * 215 | * Optional parameters: 216 | * - model: Deepgram model to use (default: "nova-3") 217 | * 218 | * CUSTOMIZATION TIPS: 219 | * - Add more Deepgram features like diarization, sentiment, etc. in the 220 | * transcribeAudio() function by adding options to the API call 221 | * - Modify formatTranscriptionResponse() to include/exclude different fields 222 | * - Add authentication middleware here if you want to protect this endpoint 223 | */ 224 | app.post("/stt/transcribe", upload.single("file"), async (req, res) => { 225 | try { 226 | const { body, file } = req; 227 | const { url, model } = body; 228 | 229 | // Validate input - must have either file or URL 230 | const dgRequest = validateTranscriptionInput(file, url); 231 | if (!dgRequest) { 232 | const errorResponse = formatErrorResponse( 233 | new Error("Either file or url must be provided"), 234 | 400 235 | ); 236 | return res.status(errorResponse.statusCode).json(errorResponse.body); 237 | } 238 | 239 | // Send transcription request to Deepgram 240 | const transcriptionResponse = await transcribeAudio( 241 | dgRequest, 242 | model || DEFAULT_MODEL 243 | ); 244 | 245 | // Format and return response 246 | const response = formatTranscriptionResponse( 247 | transcriptionResponse, 248 | model || DEFAULT_MODEL 249 | ); 250 | res.json(response); 251 | } catch (err) { 252 | console.error("Transcription error:", err); 253 | 254 | // Return formatted error response 255 | const errorResponse = formatErrorResponse(err); 256 | res.status(errorResponse.statusCode).json(errorResponse.body); 257 | } 258 | }); 259 | 260 | /** 261 | * ADD YOUR CUSTOM ROUTES HERE 262 | * 263 | * Examples: 264 | * - POST /stt/transcribe-with-diarization 265 | * - POST /stt/summarize 266 | * - GET /health (health check endpoint) 267 | * - POST /webhooks/deepgram (callback endpoint) 268 | */ 269 | 270 | // ============================================================================ 271 | // FRONTEND SERVING - Development proxy or production static files 272 | // ============================================================================ 273 | 274 | /** 275 | * In development: Proxy all requests to Vite dev server for hot reload 276 | * In production: Serve pre-built static files from frontend/dist 277 | * 278 | * IMPORTANT: This MUST come AFTER your API routes to avoid conflicts 279 | */ 280 | if (CONFIG.isDevelopment) { 281 | // Development: Proxy to Vite dev server 282 | app.use( 283 | "/", 284 | createProxyMiddleware({ 285 | target: `http://localhost:${CONFIG.vitePort}`, 286 | changeOrigin: true, 287 | ws: true, // Enable WebSocket proxying for Vite HMR (Hot Module Reload) 288 | }) 289 | ); 290 | } else { 291 | // Production: Serve static files from frontend/dist 292 | const distPath = path.join(__dirname, "frontend", "dist"); 293 | app.use(express.static(distPath)); 294 | } 295 | 296 | // ============================================================================ 297 | // SERVER START 298 | // ============================================================================ 299 | 300 | app.listen(CONFIG.port, CONFIG.host, () => { 301 | console.log("\n" + "=".repeat(70)); 302 | console.log( 303 | `🚀 STT Backend Server running at http://localhost:${CONFIG.port}` 304 | ); 305 | if (CONFIG.isDevelopment) { 306 | console.log( 307 | `📡 Proxying frontend from Vite dev server on port ${CONFIG.vitePort}` 308 | ); 309 | console.log(`\n⚠️ Open your browser to http://localhost:${CONFIG.port}`); 310 | } else { 311 | console.log(`📦 Serving built frontend from frontend/dist`); 312 | } 313 | console.log("=".repeat(70) + "\n"); 314 | }); 315 | -------------------------------------------------------------------------------- /frontend/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@deepgram/styles': 12 | specifier: latest 13 | version: 0.0.9 14 | devDependencies: 15 | vite: 16 | specifier: ^7.2.2 17 | version: 7.2.7 18 | 19 | packages: 20 | 21 | '@deepgram/styles@0.0.9': 22 | resolution: {integrity: sha512-SC/Zftny5Pr9HZ2pyOJl9LdMFOt5LMij9TZwevMyaT6AJoUmZBkNqm1H6PZmgQhLsWgx58n35XLqaTw4a41GnA==} 23 | peerDependencies: 24 | tailwindcss: ^3.4.0 25 | peerDependenciesMeta: 26 | tailwindcss: 27 | optional: true 28 | 29 | '@esbuild/aix-ppc64@0.25.12': 30 | resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} 31 | engines: {node: '>=18'} 32 | cpu: [ppc64] 33 | os: [aix] 34 | 35 | '@esbuild/android-arm64@0.25.12': 36 | resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} 37 | engines: {node: '>=18'} 38 | cpu: [arm64] 39 | os: [android] 40 | 41 | '@esbuild/android-arm@0.25.12': 42 | resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} 43 | engines: {node: '>=18'} 44 | cpu: [arm] 45 | os: [android] 46 | 47 | '@esbuild/android-x64@0.25.12': 48 | resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} 49 | engines: {node: '>=18'} 50 | cpu: [x64] 51 | os: [android] 52 | 53 | '@esbuild/darwin-arm64@0.25.12': 54 | resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} 55 | engines: {node: '>=18'} 56 | cpu: [arm64] 57 | os: [darwin] 58 | 59 | '@esbuild/darwin-x64@0.25.12': 60 | resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} 61 | engines: {node: '>=18'} 62 | cpu: [x64] 63 | os: [darwin] 64 | 65 | '@esbuild/freebsd-arm64@0.25.12': 66 | resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} 67 | engines: {node: '>=18'} 68 | cpu: [arm64] 69 | os: [freebsd] 70 | 71 | '@esbuild/freebsd-x64@0.25.12': 72 | resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} 73 | engines: {node: '>=18'} 74 | cpu: [x64] 75 | os: [freebsd] 76 | 77 | '@esbuild/linux-arm64@0.25.12': 78 | resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} 79 | engines: {node: '>=18'} 80 | cpu: [arm64] 81 | os: [linux] 82 | 83 | '@esbuild/linux-arm@0.25.12': 84 | resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} 85 | engines: {node: '>=18'} 86 | cpu: [arm] 87 | os: [linux] 88 | 89 | '@esbuild/linux-ia32@0.25.12': 90 | resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} 91 | engines: {node: '>=18'} 92 | cpu: [ia32] 93 | os: [linux] 94 | 95 | '@esbuild/linux-loong64@0.25.12': 96 | resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} 97 | engines: {node: '>=18'} 98 | cpu: [loong64] 99 | os: [linux] 100 | 101 | '@esbuild/linux-mips64el@0.25.12': 102 | resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} 103 | engines: {node: '>=18'} 104 | cpu: [mips64el] 105 | os: [linux] 106 | 107 | '@esbuild/linux-ppc64@0.25.12': 108 | resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} 109 | engines: {node: '>=18'} 110 | cpu: [ppc64] 111 | os: [linux] 112 | 113 | '@esbuild/linux-riscv64@0.25.12': 114 | resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} 115 | engines: {node: '>=18'} 116 | cpu: [riscv64] 117 | os: [linux] 118 | 119 | '@esbuild/linux-s390x@0.25.12': 120 | resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} 121 | engines: {node: '>=18'} 122 | cpu: [s390x] 123 | os: [linux] 124 | 125 | '@esbuild/linux-x64@0.25.12': 126 | resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} 127 | engines: {node: '>=18'} 128 | cpu: [x64] 129 | os: [linux] 130 | 131 | '@esbuild/netbsd-arm64@0.25.12': 132 | resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} 133 | engines: {node: '>=18'} 134 | cpu: [arm64] 135 | os: [netbsd] 136 | 137 | '@esbuild/netbsd-x64@0.25.12': 138 | resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} 139 | engines: {node: '>=18'} 140 | cpu: [x64] 141 | os: [netbsd] 142 | 143 | '@esbuild/openbsd-arm64@0.25.12': 144 | resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} 145 | engines: {node: '>=18'} 146 | cpu: [arm64] 147 | os: [openbsd] 148 | 149 | '@esbuild/openbsd-x64@0.25.12': 150 | resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} 151 | engines: {node: '>=18'} 152 | cpu: [x64] 153 | os: [openbsd] 154 | 155 | '@esbuild/openharmony-arm64@0.25.12': 156 | resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} 157 | engines: {node: '>=18'} 158 | cpu: [arm64] 159 | os: [openharmony] 160 | 161 | '@esbuild/sunos-x64@0.25.12': 162 | resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} 163 | engines: {node: '>=18'} 164 | cpu: [x64] 165 | os: [sunos] 166 | 167 | '@esbuild/win32-arm64@0.25.12': 168 | resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} 169 | engines: {node: '>=18'} 170 | cpu: [arm64] 171 | os: [win32] 172 | 173 | '@esbuild/win32-ia32@0.25.12': 174 | resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} 175 | engines: {node: '>=18'} 176 | cpu: [ia32] 177 | os: [win32] 178 | 179 | '@esbuild/win32-x64@0.25.12': 180 | resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} 181 | engines: {node: '>=18'} 182 | cpu: [x64] 183 | os: [win32] 184 | 185 | '@rollup/rollup-android-arm-eabi@4.53.3': 186 | resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} 187 | cpu: [arm] 188 | os: [android] 189 | 190 | '@rollup/rollup-android-arm64@4.53.3': 191 | resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} 192 | cpu: [arm64] 193 | os: [android] 194 | 195 | '@rollup/rollup-darwin-arm64@4.53.3': 196 | resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} 197 | cpu: [arm64] 198 | os: [darwin] 199 | 200 | '@rollup/rollup-darwin-x64@4.53.3': 201 | resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} 202 | cpu: [x64] 203 | os: [darwin] 204 | 205 | '@rollup/rollup-freebsd-arm64@4.53.3': 206 | resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} 207 | cpu: [arm64] 208 | os: [freebsd] 209 | 210 | '@rollup/rollup-freebsd-x64@4.53.3': 211 | resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} 212 | cpu: [x64] 213 | os: [freebsd] 214 | 215 | '@rollup/rollup-linux-arm-gnueabihf@4.53.3': 216 | resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} 217 | cpu: [arm] 218 | os: [linux] 219 | 220 | '@rollup/rollup-linux-arm-musleabihf@4.53.3': 221 | resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} 222 | cpu: [arm] 223 | os: [linux] 224 | 225 | '@rollup/rollup-linux-arm64-gnu@4.53.3': 226 | resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} 227 | cpu: [arm64] 228 | os: [linux] 229 | 230 | '@rollup/rollup-linux-arm64-musl@4.53.3': 231 | resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} 232 | cpu: [arm64] 233 | os: [linux] 234 | 235 | '@rollup/rollup-linux-loong64-gnu@4.53.3': 236 | resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} 237 | cpu: [loong64] 238 | os: [linux] 239 | 240 | '@rollup/rollup-linux-ppc64-gnu@4.53.3': 241 | resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} 242 | cpu: [ppc64] 243 | os: [linux] 244 | 245 | '@rollup/rollup-linux-riscv64-gnu@4.53.3': 246 | resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} 247 | cpu: [riscv64] 248 | os: [linux] 249 | 250 | '@rollup/rollup-linux-riscv64-musl@4.53.3': 251 | resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} 252 | cpu: [riscv64] 253 | os: [linux] 254 | 255 | '@rollup/rollup-linux-s390x-gnu@4.53.3': 256 | resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} 257 | cpu: [s390x] 258 | os: [linux] 259 | 260 | '@rollup/rollup-linux-x64-gnu@4.53.3': 261 | resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} 262 | cpu: [x64] 263 | os: [linux] 264 | 265 | '@rollup/rollup-linux-x64-musl@4.53.3': 266 | resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} 267 | cpu: [x64] 268 | os: [linux] 269 | 270 | '@rollup/rollup-openharmony-arm64@4.53.3': 271 | resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} 272 | cpu: [arm64] 273 | os: [openharmony] 274 | 275 | '@rollup/rollup-win32-arm64-msvc@4.53.3': 276 | resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} 277 | cpu: [arm64] 278 | os: [win32] 279 | 280 | '@rollup/rollup-win32-ia32-msvc@4.53.3': 281 | resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} 282 | cpu: [ia32] 283 | os: [win32] 284 | 285 | '@rollup/rollup-win32-x64-gnu@4.53.3': 286 | resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} 287 | cpu: [x64] 288 | os: [win32] 289 | 290 | '@rollup/rollup-win32-x64-msvc@4.53.3': 291 | resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} 292 | cpu: [x64] 293 | os: [win32] 294 | 295 | '@types/estree@1.0.8': 296 | resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} 297 | 298 | esbuild@0.25.12: 299 | resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} 300 | engines: {node: '>=18'} 301 | hasBin: true 302 | 303 | fdir@6.5.0: 304 | resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} 305 | engines: {node: '>=12.0.0'} 306 | peerDependencies: 307 | picomatch: ^3 || ^4 308 | peerDependenciesMeta: 309 | picomatch: 310 | optional: true 311 | 312 | fsevents@2.3.3: 313 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 314 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 315 | os: [darwin] 316 | 317 | nanoid@3.3.11: 318 | resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} 319 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 320 | hasBin: true 321 | 322 | picocolors@1.1.1: 323 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 324 | 325 | picomatch@4.0.3: 326 | resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} 327 | engines: {node: '>=12'} 328 | 329 | postcss@8.5.6: 330 | resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} 331 | engines: {node: ^10 || ^12 || >=14} 332 | 333 | rollup@4.53.3: 334 | resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} 335 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 336 | hasBin: true 337 | 338 | source-map-js@1.2.1: 339 | resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} 340 | engines: {node: '>=0.10.0'} 341 | 342 | tinyglobby@0.2.15: 343 | resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} 344 | engines: {node: '>=12.0.0'} 345 | 346 | vite@7.2.7: 347 | resolution: {integrity: sha512-ITcnkFeR3+fI8P1wMgItjGrR10170d8auB4EpMLPqmx6uxElH3a/hHGQabSHKdqd4FXWO1nFIp9rRn7JQ34ACQ==} 348 | engines: {node: ^20.19.0 || >=22.12.0} 349 | hasBin: true 350 | peerDependencies: 351 | '@types/node': ^20.19.0 || >=22.12.0 352 | jiti: '>=1.21.0' 353 | less: ^4.0.0 354 | lightningcss: ^1.21.0 355 | sass: ^1.70.0 356 | sass-embedded: ^1.70.0 357 | stylus: '>=0.54.8' 358 | sugarss: ^5.0.0 359 | terser: ^5.16.0 360 | tsx: ^4.8.1 361 | yaml: ^2.4.2 362 | peerDependenciesMeta: 363 | '@types/node': 364 | optional: true 365 | jiti: 366 | optional: true 367 | less: 368 | optional: true 369 | lightningcss: 370 | optional: true 371 | sass: 372 | optional: true 373 | sass-embedded: 374 | optional: true 375 | stylus: 376 | optional: true 377 | sugarss: 378 | optional: true 379 | terser: 380 | optional: true 381 | tsx: 382 | optional: true 383 | yaml: 384 | optional: true 385 | 386 | snapshots: 387 | 388 | '@deepgram/styles@0.0.9': {} 389 | 390 | '@esbuild/aix-ppc64@0.25.12': 391 | optional: true 392 | 393 | '@esbuild/android-arm64@0.25.12': 394 | optional: true 395 | 396 | '@esbuild/android-arm@0.25.12': 397 | optional: true 398 | 399 | '@esbuild/android-x64@0.25.12': 400 | optional: true 401 | 402 | '@esbuild/darwin-arm64@0.25.12': 403 | optional: true 404 | 405 | '@esbuild/darwin-x64@0.25.12': 406 | optional: true 407 | 408 | '@esbuild/freebsd-arm64@0.25.12': 409 | optional: true 410 | 411 | '@esbuild/freebsd-x64@0.25.12': 412 | optional: true 413 | 414 | '@esbuild/linux-arm64@0.25.12': 415 | optional: true 416 | 417 | '@esbuild/linux-arm@0.25.12': 418 | optional: true 419 | 420 | '@esbuild/linux-ia32@0.25.12': 421 | optional: true 422 | 423 | '@esbuild/linux-loong64@0.25.12': 424 | optional: true 425 | 426 | '@esbuild/linux-mips64el@0.25.12': 427 | optional: true 428 | 429 | '@esbuild/linux-ppc64@0.25.12': 430 | optional: true 431 | 432 | '@esbuild/linux-riscv64@0.25.12': 433 | optional: true 434 | 435 | '@esbuild/linux-s390x@0.25.12': 436 | optional: true 437 | 438 | '@esbuild/linux-x64@0.25.12': 439 | optional: true 440 | 441 | '@esbuild/netbsd-arm64@0.25.12': 442 | optional: true 443 | 444 | '@esbuild/netbsd-x64@0.25.12': 445 | optional: true 446 | 447 | '@esbuild/openbsd-arm64@0.25.12': 448 | optional: true 449 | 450 | '@esbuild/openbsd-x64@0.25.12': 451 | optional: true 452 | 453 | '@esbuild/openharmony-arm64@0.25.12': 454 | optional: true 455 | 456 | '@esbuild/sunos-x64@0.25.12': 457 | optional: true 458 | 459 | '@esbuild/win32-arm64@0.25.12': 460 | optional: true 461 | 462 | '@esbuild/win32-ia32@0.25.12': 463 | optional: true 464 | 465 | '@esbuild/win32-x64@0.25.12': 466 | optional: true 467 | 468 | '@rollup/rollup-android-arm-eabi@4.53.3': 469 | optional: true 470 | 471 | '@rollup/rollup-android-arm64@4.53.3': 472 | optional: true 473 | 474 | '@rollup/rollup-darwin-arm64@4.53.3': 475 | optional: true 476 | 477 | '@rollup/rollup-darwin-x64@4.53.3': 478 | optional: true 479 | 480 | '@rollup/rollup-freebsd-arm64@4.53.3': 481 | optional: true 482 | 483 | '@rollup/rollup-freebsd-x64@4.53.3': 484 | optional: true 485 | 486 | '@rollup/rollup-linux-arm-gnueabihf@4.53.3': 487 | optional: true 488 | 489 | '@rollup/rollup-linux-arm-musleabihf@4.53.3': 490 | optional: true 491 | 492 | '@rollup/rollup-linux-arm64-gnu@4.53.3': 493 | optional: true 494 | 495 | '@rollup/rollup-linux-arm64-musl@4.53.3': 496 | optional: true 497 | 498 | '@rollup/rollup-linux-loong64-gnu@4.53.3': 499 | optional: true 500 | 501 | '@rollup/rollup-linux-ppc64-gnu@4.53.3': 502 | optional: true 503 | 504 | '@rollup/rollup-linux-riscv64-gnu@4.53.3': 505 | optional: true 506 | 507 | '@rollup/rollup-linux-riscv64-musl@4.53.3': 508 | optional: true 509 | 510 | '@rollup/rollup-linux-s390x-gnu@4.53.3': 511 | optional: true 512 | 513 | '@rollup/rollup-linux-x64-gnu@4.53.3': 514 | optional: true 515 | 516 | '@rollup/rollup-linux-x64-musl@4.53.3': 517 | optional: true 518 | 519 | '@rollup/rollup-openharmony-arm64@4.53.3': 520 | optional: true 521 | 522 | '@rollup/rollup-win32-arm64-msvc@4.53.3': 523 | optional: true 524 | 525 | '@rollup/rollup-win32-ia32-msvc@4.53.3': 526 | optional: true 527 | 528 | '@rollup/rollup-win32-x64-gnu@4.53.3': 529 | optional: true 530 | 531 | '@rollup/rollup-win32-x64-msvc@4.53.3': 532 | optional: true 533 | 534 | '@types/estree@1.0.8': {} 535 | 536 | esbuild@0.25.12: 537 | optionalDependencies: 538 | '@esbuild/aix-ppc64': 0.25.12 539 | '@esbuild/android-arm': 0.25.12 540 | '@esbuild/android-arm64': 0.25.12 541 | '@esbuild/android-x64': 0.25.12 542 | '@esbuild/darwin-arm64': 0.25.12 543 | '@esbuild/darwin-x64': 0.25.12 544 | '@esbuild/freebsd-arm64': 0.25.12 545 | '@esbuild/freebsd-x64': 0.25.12 546 | '@esbuild/linux-arm': 0.25.12 547 | '@esbuild/linux-arm64': 0.25.12 548 | '@esbuild/linux-ia32': 0.25.12 549 | '@esbuild/linux-loong64': 0.25.12 550 | '@esbuild/linux-mips64el': 0.25.12 551 | '@esbuild/linux-ppc64': 0.25.12 552 | '@esbuild/linux-riscv64': 0.25.12 553 | '@esbuild/linux-s390x': 0.25.12 554 | '@esbuild/linux-x64': 0.25.12 555 | '@esbuild/netbsd-arm64': 0.25.12 556 | '@esbuild/netbsd-x64': 0.25.12 557 | '@esbuild/openbsd-arm64': 0.25.12 558 | '@esbuild/openbsd-x64': 0.25.12 559 | '@esbuild/openharmony-arm64': 0.25.12 560 | '@esbuild/sunos-x64': 0.25.12 561 | '@esbuild/win32-arm64': 0.25.12 562 | '@esbuild/win32-ia32': 0.25.12 563 | '@esbuild/win32-x64': 0.25.12 564 | 565 | fdir@6.5.0(picomatch@4.0.3): 566 | optionalDependencies: 567 | picomatch: 4.0.3 568 | 569 | fsevents@2.3.3: 570 | optional: true 571 | 572 | nanoid@3.3.11: {} 573 | 574 | picocolors@1.1.1: {} 575 | 576 | picomatch@4.0.3: {} 577 | 578 | postcss@8.5.6: 579 | dependencies: 580 | nanoid: 3.3.11 581 | picocolors: 1.1.1 582 | source-map-js: 1.2.1 583 | 584 | rollup@4.53.3: 585 | dependencies: 586 | '@types/estree': 1.0.8 587 | optionalDependencies: 588 | '@rollup/rollup-android-arm-eabi': 4.53.3 589 | '@rollup/rollup-android-arm64': 4.53.3 590 | '@rollup/rollup-darwin-arm64': 4.53.3 591 | '@rollup/rollup-darwin-x64': 4.53.3 592 | '@rollup/rollup-freebsd-arm64': 4.53.3 593 | '@rollup/rollup-freebsd-x64': 4.53.3 594 | '@rollup/rollup-linux-arm-gnueabihf': 4.53.3 595 | '@rollup/rollup-linux-arm-musleabihf': 4.53.3 596 | '@rollup/rollup-linux-arm64-gnu': 4.53.3 597 | '@rollup/rollup-linux-arm64-musl': 4.53.3 598 | '@rollup/rollup-linux-loong64-gnu': 4.53.3 599 | '@rollup/rollup-linux-ppc64-gnu': 4.53.3 600 | '@rollup/rollup-linux-riscv64-gnu': 4.53.3 601 | '@rollup/rollup-linux-riscv64-musl': 4.53.3 602 | '@rollup/rollup-linux-s390x-gnu': 4.53.3 603 | '@rollup/rollup-linux-x64-gnu': 4.53.3 604 | '@rollup/rollup-linux-x64-musl': 4.53.3 605 | '@rollup/rollup-openharmony-arm64': 4.53.3 606 | '@rollup/rollup-win32-arm64-msvc': 4.53.3 607 | '@rollup/rollup-win32-ia32-msvc': 4.53.3 608 | '@rollup/rollup-win32-x64-gnu': 4.53.3 609 | '@rollup/rollup-win32-x64-msvc': 4.53.3 610 | fsevents: 2.3.3 611 | 612 | source-map-js@1.2.1: {} 613 | 614 | tinyglobby@0.2.15: 615 | dependencies: 616 | fdir: 6.5.0(picomatch@4.0.3) 617 | picomatch: 4.0.3 618 | 619 | vite@7.2.7: 620 | dependencies: 621 | esbuild: 0.25.12 622 | fdir: 6.5.0(picomatch@4.0.3) 623 | picomatch: 4.0.3 624 | postcss: 8.5.6 625 | rollup: 4.53.3 626 | tinyglobby: 0.2.15 627 | optionalDependencies: 628 | fsevents: 2.3.3 629 | -------------------------------------------------------------------------------- /frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 29 | 30 | 31 | 32 | 33 | 34 | Deepgram Transcription Demo 35 | 36 | 39 | 40 | 41 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 54 | 55 | 308 | 309 | 310 | 311 | 315 | 316 |
317 |
318 | 321 | 327 |
328 |
329 | 330 | 337 | 338 |
339 |
340 | 341 | 344 | 345 | 440 | 441 | 445 | 446 |
447 |
448 |
449 |

Select your audio and options to try out transcription

450 |

451 | Choose an audio source from the sidebar, configure your options, and click transcribe to get started. 452 |

453 | 456 |
457 |
458 | 459 |
460 | 461 | 466 | 467 | 477 | 478 |
479 | 480 | 483 | 484 | 537 | 538 | 597 | 598 | 599 | 600 | 601 | -------------------------------------------------------------------------------- /frontend/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Transcription HTML Starter - Frontend Application 3 | * 4 | * This is a vanilla JavaScript frontend that provides a transcription UI 5 | * for Deepgram's Speech-to-Text service. It's designed to be easily 6 | * modified and extended for your own projects. 7 | * 8 | * Key Features: 9 | * - Audio source selection (URLs or file upload) 10 | * - Model selection 11 | * - Real-time transcription 12 | * - History management with localStorage 13 | * - Responsive UI with Deepgram design system 14 | * 15 | * Architecture: 16 | * - Pure vanilla JavaScript (no frameworks required) 17 | * - Uses native Fetch API for HTTP requests 18 | * - LocalStorage for history persistence 19 | * - Event-driven UI updates 20 | */ 21 | 22 | // ============================================================================ 23 | // CONFIGURATION - Customize these values for your needs 24 | // ============================================================================ 25 | 26 | /** 27 | * API endpoint for transcription requests 28 | * Change this if your backend is hosted elsewhere 29 | */ 30 | const API_ENDPOINT = "/stt/transcribe"; 31 | 32 | /** 33 | * LocalStorage key for history persistence 34 | * Change this if you want to use a different storage key 35 | */ 36 | const HISTORY_KEY = "deepgram_transcription_history"; 37 | 38 | /** 39 | * Maximum number of history entries to store 40 | * Prevents localStorage from growing too large 41 | */ 42 | const MAX_HISTORY_ENTRIES = 50; 43 | 44 | // ============================================================================ 45 | // STATE MANAGEMENT - Application state variables 46 | // ============================================================================ 47 | 48 | /** 49 | * DOM Elements - Cached references to frequently used elements 50 | * These are initialized in the init() function 51 | */ 52 | let audioSourceRadios; 53 | let audioFileInput; 54 | let modelSelect; 55 | let transcribeBtn; 56 | let mainContent; 57 | let statusContainer; 58 | let statusMessage; 59 | let metadataContainer; 60 | let metadataGrid; 61 | let historyTitle; 62 | let historySidebarContent; 63 | 64 | /** 65 | * Currently active transcription ID 66 | * Used to highlight the active history item 67 | */ 68 | let activeRequestId = null; 69 | 70 | // ============================================================================ 71 | // LOCALSTORAGE HISTORY MANAGEMENT 72 | // ============================================================================ 73 | 74 | /** 75 | * Retrieves transcription history from localStorage 76 | * 77 | * @returns {Array} Array of history entries, or empty array if none exist 78 | * 79 | * History entry structure: 80 | * { 81 | * id: string, // Request ID from Deepgram or local timestamp 82 | * timestamp: string, // ISO 8601 timestamp 83 | * audioSource: string, // URL or filename 84 | * model: string, // Model name used 85 | * response: object // Full transcription response 86 | * } 87 | */ 88 | function getTranscriptionHistory() { 89 | try { 90 | const history = localStorage.getItem(HISTORY_KEY); 91 | return history ? JSON.parse(history) : []; 92 | } catch (error) { 93 | console.error("Error reading transcription history:", error); 94 | return []; 95 | } 96 | } 97 | 98 | /** 99 | * Saves a transcription result to localStorage history 100 | * 101 | * @param {Object} transcriptionData - The transcription response from the API 102 | * @param {string} audioSource - URL or filename of the audio source 103 | * @param {string} model - Model name used for transcription 104 | * @returns {Object|null} The saved history entry, or null if save failed 105 | */ 106 | function saveTranscriptionToHistory(transcriptionData, audioSource, model) { 107 | try { 108 | const history = getTranscriptionHistory(); 109 | 110 | // Get request_id from metadata or generate a fallback ID 111 | const requestId = transcriptionData.metadata?.request_id || `local_${Date.now()}`; 112 | 113 | const historyEntry = { 114 | id: requestId, 115 | timestamp: new Date().toISOString(), 116 | audioSource, 117 | model, 118 | response: transcriptionData, 119 | }; 120 | 121 | // Add to beginning of array (newest first) 122 | history.unshift(historyEntry); 123 | 124 | // Keep only the most recent entries to prevent localStorage overflow 125 | const trimmedHistory = history.slice(0, MAX_HISTORY_ENTRIES); 126 | 127 | localStorage.setItem(HISTORY_KEY, JSON.stringify(trimmedHistory)); 128 | 129 | // Update history UI 130 | renderHistory(); 131 | 132 | return historyEntry; 133 | } catch (error) { 134 | console.error("Error saving transcription to history:", error); 135 | return null; 136 | } 137 | } 138 | 139 | /** 140 | * Clears all transcription history from localStorage 141 | * 142 | * @returns {boolean} True if successful, false if error occurred 143 | */ 144 | function clearTranscriptionHistory() { 145 | try { 146 | localStorage.removeItem(HISTORY_KEY); 147 | renderHistory(); 148 | return true; 149 | } catch (error) { 150 | console.error("Error clearing transcription history:", error); 151 | return false; 152 | } 153 | } 154 | 155 | /** 156 | * Retrieves a specific history entry by its request ID 157 | * 158 | * @param {string} requestId - The unique ID of the history entry 159 | * @returns {Object|undefined} The history entry, or undefined if not found 160 | */ 161 | function getHistoryEntryById(requestId) { 162 | const history = getTranscriptionHistory(); 163 | return history.find((entry) => entry.id === requestId); 164 | } 165 | 166 | // ============================================================================ 167 | // HISTORY UI RENDERING 168 | // ============================================================================ 169 | 170 | /** 171 | * Renders the history sidebar with all transcription entries 172 | * Highlights the currently active entry if one is selected 173 | */ 174 | function renderHistory() { 175 | const history = getTranscriptionHistory(); 176 | 177 | // Update title with count 178 | if (historyTitle) { 179 | historyTitle.textContent = `History (${history.length})`; 180 | } 181 | 182 | // Render history list 183 | if (historySidebarContent) { 184 | if (history.length === 0) { 185 | historySidebarContent.innerHTML = '
No transcriptions yet
'; 186 | } else { 187 | const historyList = document.createElement("div"); 188 | historyList.className = "history-list"; 189 | 190 | history.forEach((entry) => { 191 | const item = document.createElement("a"); 192 | const isActive = activeRequestId === entry.id; 193 | item.className = isActive ? "history-item history-item--active" : "history-item"; 194 | item.href = `?request_id=${entry.id}`; 195 | item.onclick = (e) => { 196 | e.preventDefault(); 197 | loadHistoryEntry(entry.id); 198 | }; 199 | 200 | const timestamp = new Date(entry.timestamp); 201 | const timeStr = timestamp.toLocaleString("en-US", { 202 | month: "short", 203 | day: "numeric", 204 | hour: "numeric", 205 | minute: "2-digit", 206 | }); 207 | 208 | item.innerHTML = ` 209 |
${entry.id}
210 |
${timeStr}
211 |
${entry.model || "nova-3"}
212 | `; 213 | 214 | historyList.appendChild(item); 215 | }); 216 | 217 | historySidebarContent.innerHTML = ""; 218 | historySidebarContent.appendChild(historyList); 219 | } 220 | } 221 | } 222 | 223 | /** 224 | * Loads and displays a history entry by its request ID 225 | * 226 | * @param {string} requestId - The unique ID of the history entry to load 227 | */ 228 | function loadHistoryEntry(requestId) { 229 | const entry = getHistoryEntryById(requestId); 230 | 231 | if (!entry) { 232 | showError(`History entry not found: ${requestId}`); 233 | return; 234 | } 235 | 236 | // Set the active request ID 237 | activeRequestId = entry.id; 238 | 239 | // Display the transcription 240 | displayTranscript(entry.response); 241 | displayMetadata(entry.response); 242 | hideStatus(); 243 | 244 | // Re-render history to update highlighting 245 | renderHistory(); 246 | } 247 | 248 | /** 249 | * Checks URL query parameters for a request_id and loads it if present 250 | * This enables deep linking to specific transcription results 251 | */ 252 | function checkUrlForRequestId() { 253 | const urlParams = new URLSearchParams(window.location.search); 254 | const requestId = urlParams.get("request_id"); 255 | 256 | if (requestId) { 257 | loadHistoryEntry(requestId); 258 | } else { 259 | // No request_id means we should show the initial form state 260 | resetToInitialState(); 261 | } 262 | } 263 | 264 | // ============================================================================ 265 | // FORM VALIDATION 266 | // ============================================================================ 267 | 268 | /** 269 | * Checks if the form is valid and ready to submit 270 | * 271 | * Form is valid if either: 272 | * - A radio button (audio source) is selected, OR 273 | * - A file has been uploaded 274 | * 275 | * @returns {boolean} True if form is valid, false otherwise 276 | */ 277 | function isFormValid() { 278 | // Check if a radio button is selected 279 | const selectedRadio = document.querySelector('input[name="audioSource"]:checked'); 280 | 281 | // Check if a file has been uploaded 282 | const hasFile = audioFileInput && audioFileInput.files && audioFileInput.files.length > 0; 283 | 284 | // Form is valid if either condition is true 285 | return !!(selectedRadio || hasFile); 286 | } 287 | 288 | /** 289 | * Updates the transcribe button's disabled state based on form validity 290 | * Called whenever form inputs change 291 | */ 292 | function updateFormValidation() { 293 | const isValid = isFormValid(); 294 | transcribeBtn.disabled = !isValid; 295 | } 296 | 297 | // ============================================================================ 298 | // INITIALIZATION & SETUP 299 | // ============================================================================ 300 | 301 | /** 302 | * Initializes the application 303 | * - Caches DOM element references 304 | * - Sets up event listeners 305 | * - Loads initial state from URL parameters 306 | * - Renders history sidebar 307 | * 308 | * Called when DOM is ready 309 | */ 310 | function init() { 311 | // Get DOM elements 312 | audioSourceRadios = document.querySelectorAll('input[name="audioSource"]'); 313 | audioFileInput = document.getElementById("audioFile"); 314 | modelSelect = document.getElementById("model"); 315 | transcribeBtn = document.getElementById("transcribeBtn"); 316 | mainContent = document.getElementById("mainContent"); 317 | statusContainer = document.getElementById("statusContainer"); 318 | statusMessage = document.getElementById("statusMessage"); 319 | metadataContainer = document.getElementById("metadataContainer"); 320 | metadataGrid = document.getElementById("metadataGrid"); 321 | historyTitle = document.getElementById("historyTitle"); 322 | historySidebarContent = document.getElementById("historySidebarContent"); 323 | 324 | // Check if we should enable elements (no state parameter means normal operation) 325 | const urlParams = new URLSearchParams(window.location.search); 326 | const state = urlParams.get("state"); 327 | 328 | if (!state) { 329 | // Enable all form elements for normal operation 330 | enableFormElements(); 331 | } 332 | 333 | setupEventListeners(); 334 | // Set initial state 335 | updateFormValidation(); 336 | // Render history 337 | renderHistory(); 338 | // Check URL for request_id 339 | checkUrlForRequestId(); 340 | } 341 | 342 | /** 343 | * Sets up all event listeners for the application 344 | * - Audio source radio buttons 345 | * - File upload input 346 | * - Transcribe button 347 | * - Browser navigation (back/forward) 348 | */ 349 | function setupEventListeners() { 350 | // Audio source radios - listen for changes directly on radios 351 | audioSourceRadios.forEach((radio) => { 352 | radio.addEventListener("change", handleRadioChange); 353 | }); 354 | 355 | // File upload 356 | audioFileInput.addEventListener("change", handleFileUpload); 357 | 358 | // Transcribe button 359 | transcribeBtn.addEventListener("click", handleTranscribe); 360 | 361 | // Handle browser back/forward navigation 362 | window.addEventListener("popstate", () => { 363 | checkUrlForRequestId(); 364 | }); 365 | } 366 | 367 | // ============================================================================ 368 | // EVENT HANDLERS 369 | // ============================================================================ 370 | 371 | /** 372 | * Handles radio button (audio source) selection 373 | * - Clears file upload when a radio is selected 374 | * - Resets file upload card display 375 | * - Updates form validation 376 | */ 377 | function handleRadioChange() { 378 | // Clear file upload when a radio is selected 379 | if (audioFileInput) { 380 | audioFileInput.value = ""; 381 | } 382 | 383 | const fileCheckbox = document.getElementById("fileSelected"); 384 | if (fileCheckbox) { 385 | fileCheckbox.checked = false; 386 | } 387 | 388 | // Reset file upload card text 389 | const fileCard = document.querySelector(".dg-card--file-upload"); 390 | if (fileCard) { 391 | const descriptionEl = fileCard.querySelector("p.file-upload-description"); 392 | if (descriptionEl) descriptionEl.textContent = "Choose from device"; 393 | } 394 | 395 | // Update form validation 396 | updateFormValidation(); 397 | } 398 | 399 | /** 400 | * Handles file upload selection 401 | * - Unchecks all radio buttons 402 | * - Checks the file upload checkbox 403 | * - Updates card display with filename 404 | * - Updates form validation 405 | * 406 | * @param {Event} e - The file input change event 407 | */ 408 | function handleFileUpload(e) { 409 | const file = e.target.files[0]; 410 | if (file) { 411 | // Uncheck all radio buttons 412 | audioSourceRadios.forEach((radio) => { 413 | radio.checked = false; 414 | }); 415 | 416 | // Check the file selected checkbox 417 | const fileCheckbox = document.getElementById("fileSelected"); 418 | if (fileCheckbox) { 419 | fileCheckbox.checked = true; 420 | } 421 | 422 | // Update card content to show file name 423 | const fileCard = document.querySelector(".dg-card--file-upload"); 424 | if (fileCard) { 425 | const descriptionEl = fileCard.querySelector("p.file-upload-description"); 426 | if (descriptionEl) descriptionEl.textContent = file.name; 427 | } 428 | } 429 | 430 | // Update form validation 431 | updateFormValidation(); 432 | } 433 | 434 | /** 435 | * Handles transcription request 436 | * Main function that: 437 | * - Validates form input 438 | * - Creates FormData with file or URL 439 | * - Makes API request to transcription endpoint 440 | * - Saves result to history 441 | * - Displays transcription result 442 | * - Handles errors 443 | * 444 | * CUSTOMIZATION TIPS: 445 | * - Modify API_ENDPOINT constant to change backend URL 446 | * - Add additional form parameters before making request 447 | * - Customize error handling logic 448 | * - Add progress tracking or file size validation 449 | */ 450 | async function handleTranscribe() { 451 | const selectedRadio = document.querySelector('input[name="audioSource"]:checked'); 452 | const file = audioFileInput.files[0]; 453 | 454 | // Check if either a URL or file was selected 455 | if (!selectedRadio && !file) { 456 | showError("Please select an audio source or upload a file"); 457 | return; 458 | } 459 | 460 | const model = modelSelect.value; 461 | let audioSource = ""; 462 | 463 | // Disable form elements and show working status 464 | disableFormElements(); 465 | showWorking(); 466 | 467 | try { 468 | // Create FormData for multipart/form-data upload 469 | const formData = new FormData(); 470 | 471 | if (file) { 472 | // File upload takes precedence 473 | formData.append("file", file); 474 | audioSource = file.name; 475 | } else if (selectedRadio) { 476 | // URL from radio button 477 | formData.append("url", selectedRadio.value); 478 | audioSource = selectedRadio.value; 479 | } 480 | 481 | // Add model parameter to form data if specified 482 | if (model) { 483 | formData.append("model", model); 484 | } 485 | 486 | // Make API request with multipart/form-data 487 | const response = await fetch(API_ENDPOINT, { 488 | method: "POST", 489 | body: formData, 490 | // Don't set Content-Type header - browser will set it with boundary 491 | }); 492 | 493 | if (!response.ok) { 494 | const errorData = await response.json().catch(() => ({})); 495 | 496 | // Validate error response matches contract 497 | if (errorData.error && errorData.error.message) { 498 | const errorCode = errorData.error.code ? ` (${errorData.error.code})` : ""; 499 | const errorType = errorData.error.type ? `[${errorData.error.type}] ` : ""; 500 | throw new Error(`${errorType}${errorData.error.message}${errorCode}`); 501 | } 502 | 503 | throw new Error(`Request failed with status ${response.status}`); 504 | } 505 | 506 | const data = await response.json(); 507 | 508 | // Validate response matches contract (required: transcript field) 509 | if (!data.transcript && data.transcript !== "") { 510 | throw new Error("Invalid response: missing required 'transcript' field"); 511 | } 512 | 513 | // Save to history and get the entry 514 | const historyEntry = saveTranscriptionToHistory(data, audioSource, model); 515 | 516 | // Set the active request ID and display 517 | if (historyEntry) { 518 | activeRequestId = historyEntry.id; 519 | enableFormElements(); 520 | displayTranscript(data); 521 | displayMetadata(data); 522 | hideStatus(); 523 | renderHistory(); // Re-render to highlight the active item 524 | } else { 525 | // Fallback: display directly if save failed 526 | enableFormElements(); 527 | displayTranscript(data); 528 | displayMetadata(data); 529 | hideStatus(); 530 | } 531 | } catch (error) { 532 | console.error("Transcription error:", error); 533 | // Re-enable form elements on error 534 | enableFormElements(); 535 | showError(error.message); 536 | } 537 | } 538 | 539 | // ============================================================================ 540 | // UI STATE MANAGEMENT 541 | // ============================================================================ 542 | 543 | /** 544 | * Shows "processing" status indicator 545 | * Displays spinner and hides metadata 546 | */ 547 | function showWorking() { 548 | statusContainer.style.display = "block"; 549 | statusMessage.className = "dg-status dg-status--with-icon dg-status--primary"; 550 | statusMessage.innerHTML = 551 | ' Processing transcription...'; 552 | metadataContainer.style.display = "none"; 553 | } 554 | 555 | /** 556 | * Shows error status indicator 557 | * Displays error icon and message, hides metadata 558 | * 559 | * @param {string} message - The error message to display 560 | */ 561 | function showError(message) { 562 | statusContainer.style.display = "block"; 563 | statusMessage.className = "dg-status dg-status--with-icon dg-status--error"; 564 | statusMessage.innerHTML = ` ${message}`; 565 | metadataContainer.style.display = "none"; 566 | } 567 | 568 | /** 569 | * Hides the status indicator 570 | */ 571 | function hideStatus() { 572 | statusContainer.style.display = "none"; 573 | } 574 | 575 | // ============================================================================ 576 | // RESULTS DISPLAY 577 | // ============================================================================ 578 | 579 | /** 580 | * Displays the transcription result in the main content area 581 | * 582 | * @param {Object} data - The transcription response data 583 | * @param {string} data.transcript - The transcribed text 584 | * 585 | * CUSTOMIZATION TIP: 586 | * - Modify this function to display additional fields like paragraphs, words, etc. 587 | * - Add word-level highlighting or timestamps 588 | * - Format output differently (e.g., show speakers for diarization) 589 | */ 590 | function displayTranscript(data) { 591 | const transcript = data.transcript || "No transcript available"; 592 | 593 | mainContent.innerHTML = ` 594 |
595 |

Transcript

596 |
597 | ${escapeHtml(transcript)} 598 |
599 |
600 | `; 601 | } 602 | 603 | /** 604 | * Resets the application to its initial state 605 | * - Clears active request ID 606 | * - Shows form sections 607 | * - Hides metadata and status 608 | * - Resets main content to empty state 609 | * - Re-enables form elements 610 | */ 611 | function resetToInitialState() { 612 | // Clear active request ID 613 | activeRequestId = null; 614 | 615 | // Show form sections 616 | const controlsSections = document.querySelectorAll(".controls-section"); 617 | controlsSections.forEach((section) => { 618 | section.style.display = "block"; 619 | }); 620 | 621 | // Hide metadata 622 | if (metadataContainer) { 623 | metadataContainer.style.display = "none"; 624 | } 625 | 626 | // Hide status 627 | hideStatus(); 628 | 629 | // Reset main content to empty state 630 | if (mainContent) { 631 | mainContent.innerHTML = ` 632 |
633 |
634 |

Select your audio and options to try out transcription

635 |

636 | Choose an audio source from the sidebar, configure your options, and click transcribe to get started. 637 |

638 | 641 |
642 | `; 643 | 644 | // Re-attach event listener to the new transcribe button 645 | transcribeBtn = document.getElementById("transcribeBtn"); 646 | if (transcribeBtn) { 647 | transcribeBtn.addEventListener("click", handleTranscribe); 648 | } 649 | } 650 | 651 | // Enable form elements 652 | enableFormElements(); 653 | 654 | // Update form validation 655 | updateFormValidation(); 656 | 657 | // Re-render history to clear highlighting 658 | renderHistory(); 659 | } 660 | 661 | /** 662 | * Displays transcription metadata in the sidebar 663 | * Shows duration, word count, and any metadata from the response 664 | * 665 | * @param {Object} data - The transcription response data 666 | * @param {number} [data.duration] - Audio duration in seconds 667 | * @param {Array} [data.words] - Array of words with timestamps 668 | * @param {Object} [data.metadata] - Additional metadata from Deepgram 669 | * 670 | * CUSTOMIZATION TIP: 671 | * - Add or remove metadata fields 672 | * - Format values differently (e.g., duration as MM:SS) 673 | * - Add custom calculated metrics 674 | */ 675 | function displayMetadata(data) { 676 | // Hide form sections 677 | const controlsSections = document.querySelectorAll(".controls-section"); 678 | controlsSections.forEach((section) => { 679 | section.style.display = "none"; 680 | }); 681 | 682 | metadataContainer.style.display = "block"; 683 | 684 | const metadata = []; 685 | 686 | if (data.duration !== undefined) { 687 | metadata.push({ 688 | label: "Duration", 689 | value: `${data.duration.toFixed(2)}s`, 690 | }); 691 | } 692 | 693 | if (data.words && data.words.length > 0) { 694 | metadata.push({ 695 | label: "Word Count", 696 | value: data.words.length, 697 | }); 698 | } 699 | 700 | if (data.metadata) { 701 | Object.entries(data.metadata).forEach(([key, value]) => { 702 | metadata.push({ 703 | label: key, 704 | value: typeof value === "object" ? JSON.stringify(value) : String(value), 705 | }); 706 | }); 707 | } 708 | 709 | const metadataHTML = metadata 710 | .map( 711 | (item) => ` 712 | 716 | ` 717 | ) 718 | .join(""); 719 | 720 | // Get base path without query parameters 721 | const basePath = window.location.pathname; 722 | 723 | metadataGrid.innerHTML = ` 724 | ${metadataHTML} 725 | 726 | 727 | Transcribe Another 728 | 729 | `; 730 | } 731 | 732 | // ============================================================================ 733 | // UTILITY FUNCTIONS 734 | // ============================================================================ 735 | 736 | /** 737 | * Escapes HTML special characters to prevent XSS attacks 738 | * Uses browser's native text rendering to safely escape content 739 | * 740 | * @param {string} text - The text to escape 741 | * @returns {string} HTML-safe escaped text 742 | */ 743 | function escapeHtml(text) { 744 | const div = document.createElement("div"); 745 | div.textContent = text; 746 | return div.innerHTML; 747 | } 748 | 749 | /** 750 | * Disables all form elements during transcription processing 751 | * Prevents user from making changes while request is in flight 752 | * Adds visual feedback with disabled styling 753 | */ 754 | function disableFormElements() { 755 | // Query DOM directly to ensure we get the latest elements 756 | const radios = document.querySelectorAll('input[name="audioSource"]'); 757 | const fileInput = document.getElementById("audioFile"); 758 | const select = document.getElementById("model"); 759 | const btn = document.getElementById("transcribeBtn"); 760 | 761 | // Disable audio source radios 762 | radios.forEach((radio) => { 763 | radio.disabled = true; 764 | }); 765 | 766 | // Disable file upload 767 | if (fileInput) { 768 | fileInput.disabled = true; 769 | } 770 | 771 | // Disable model select 772 | if (select) { 773 | select.disabled = true; 774 | } 775 | 776 | // Disable transcribe button 777 | if (btn) { 778 | btn.disabled = true; 779 | } 780 | 781 | // Add visual feedback to cards by adding disabled class 782 | const cards = document.querySelectorAll(".dg-card--selectable, .dg-card--file-upload"); 783 | cards.forEach((card) => { 784 | card.classList.add("dg-card--disabled"); 785 | }); 786 | } 787 | 788 | /** 789 | * Re-enables all form elements after transcription completes 790 | * Removes disabled styling and re-validates form 791 | */ 792 | function enableFormElements() { 793 | // Query DOM directly to ensure we get the latest elements 794 | const radios = document.querySelectorAll('input[name="audioSource"]'); 795 | const fileInput = document.getElementById("audioFile"); 796 | const select = document.getElementById("model"); 797 | 798 | // Enable audio source radios 799 | radios.forEach((radio) => { 800 | radio.disabled = false; 801 | }); 802 | 803 | // Enable file upload 804 | if (fileInput) { 805 | fileInput.disabled = false; 806 | } 807 | 808 | // Enable model select 809 | if (select) { 810 | select.disabled = false; 811 | } 812 | 813 | // Re-enable transcribe button (but respect form validation) 814 | updateFormValidation(); 815 | 816 | // Remove visual feedback from cards by removing disabled class 817 | const cards = document.querySelectorAll(".dg-card--selectable, .dg-card--file-upload"); 818 | cards.forEach((card) => { 819 | card.classList.remove("dg-card--disabled"); 820 | }); 821 | } 822 | 823 | // ============================================================================ 824 | // STATE PREVIEW MODE - For development and testing 825 | // ============================================================================ 826 | 827 | /** 828 | * Checks URL parameters for state preview mode 829 | * Used for testing different UI states during development 830 | * 831 | * Available states: 832 | * - ?state=waiting - Shows processing/loading state 833 | * - ?state=results - Shows results with mock data 834 | * - ?state=error - Shows error state 835 | * - (no parameter) - Shows normal initial state 836 | */ 837 | function checkUrlStateParameter() { 838 | const urlParams = new URLSearchParams(window.location.search); 839 | const state = urlParams.get("state"); 840 | 841 | if (state === "waiting") { 842 | setWaitingState(); 843 | } else if (state === "results") { 844 | setResultsState(); 845 | } else if (state === "error") { 846 | setErrorState(); 847 | } 848 | // Default state (initial) is already set by HTML 849 | } 850 | 851 | /** 852 | * Sets the UI to "waiting" state with mock data 853 | * Used for development and testing 854 | */ 855 | function setWaitingState() { 856 | // Select first radio button 857 | const firstRadio = document.querySelector('input[name="audioSource"]'); 858 | if (firstRadio) { 859 | firstRadio.checked = true; 860 | } 861 | 862 | // Update main content to show processing state 863 | const content = document.getElementById("mainContent"); 864 | if (content) { 865 | content.innerHTML = ` 866 |
867 |
868 | 869 |
870 |

Processing your audio...

871 |

872 | Your transcription request is being processed. This may take a few moments depending on the audio length. 873 |

874 |
875 | `; 876 | } 877 | 878 | // Show working status 879 | showWorking(); 880 | 881 | // Elements stay disabled (they're disabled by default in HTML) 882 | } 883 | 884 | /** 885 | * Sets the UI to "results" state with mock transcription data 886 | * Used for development and testing 887 | */ 888 | function setResultsState() { 889 | // Select first radio button 890 | const firstRadio = document.querySelector('input[name="audioSource"]'); 891 | if (firstRadio) { 892 | firstRadio.checked = true; 893 | updateFormValidation(); 894 | } 895 | 896 | // Re-enable form elements 897 | enableFormElements(); 898 | 899 | // Mock response data 900 | const mockData = { 901 | transcript: 902 | "Yeah, as as much as it's worth celebrating, the first spacewalk, with an all female team, I think many of us are looking forward to it just being normal. And I think if it signifies anything, it is to honor the the women who came before us who, um, were skilled and qualified, and didn't get the same opportunities that we have today.", 903 | duration: 17.64, 904 | words: [ 905 | { word: "yeah", start: 0.08, end: 0.32 }, 906 | { word: "as", start: 0.32, end: 0.48 }, 907 | { word: "as", start: 0.64, end: 0.8 }, 908 | { word: "much", start: 0.8, end: 1.04 }, 909 | { word: "as", start: 1.04, end: 1.12 }, 910 | ], 911 | metadata: { 912 | model_uuid: "6103c447-e5a9-45b9-8d1f-f168eae8b5f4", 913 | request_id: "99f23e1a-7e98-4e50-a33c-2c7e2b6f0a4a", 914 | model_name: "nova-3", 915 | }, 916 | }; 917 | 918 | displayTranscript(mockData); 919 | displayMetadata(mockData); 920 | hideStatus(); 921 | } 922 | 923 | /** 924 | * Sets the UI to "error" state with mock error message 925 | * Used for development and testing 926 | */ 927 | function setErrorState() { 928 | // Select first radio button 929 | const firstRadio = document.querySelector('input[name="audioSource"]'); 930 | if (firstRadio) { 931 | firstRadio.checked = true; 932 | updateFormValidation(); 933 | } 934 | 935 | // Re-enable form elements 936 | enableFormElements(); 937 | 938 | // Update main content to show error state 939 | const basePath = window.location.pathname; 940 | mainContent.innerHTML = ` 941 |
942 |
943 | 944 |
945 |

Transcription Failed

946 |

947 | We encountered an error while processing your audio. Please check your connection and try again. 948 |

949 | 950 | 951 | Transcribe Another 952 | 953 |
954 | `; 955 | 956 | // Show error status 957 | showError("Unable to connect to transcription service. Please try again later."); 958 | } 959 | 960 | // ============================================================================ 961 | // APPLICATION BOOTSTRAP 962 | // ============================================================================ 963 | 964 | /** 965 | * Initialize the application when DOM is ready 966 | * Handles both loading and already-loaded states 967 | */ 968 | if (document.readyState === "loading") { 969 | document.addEventListener("DOMContentLoaded", () => { 970 | init(); 971 | checkUrlStateParameter(); 972 | }); 973 | } else { 974 | init(); 975 | checkUrlStateParameter(); 976 | } 977 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '9.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | importers: 8 | 9 | .: 10 | dependencies: 11 | '@deepgram/sdk': 12 | specifier: 4.11.2 13 | version: 4.11.2 14 | cors: 15 | specifier: 2.8.5 16 | version: 2.8.5 17 | dotenv: 18 | specifier: 17.2.3 19 | version: 17.2.3 20 | express: 21 | specifier: 5.2.1 22 | version: 5.2.1 23 | http-proxy-middleware: 24 | specifier: 3.0.5 25 | version: 3.0.5 26 | multer: 27 | specifier: 2.0.2 28 | version: 2.0.2 29 | npm-run-all: 30 | specifier: 4.1.5 31 | version: 4.1.5 32 | devDependencies: 33 | '@flydotio/dockerfile': 34 | specifier: 0.7.10 35 | version: 0.7.10(@types/node@24.10.2) 36 | nodemon: 37 | specifier: 3.1.10 38 | version: 3.1.10 39 | 40 | packages: 41 | 42 | '@deepgram/captions@1.2.0': 43 | resolution: {integrity: sha512-8B1C/oTxTxyHlSFubAhNRgCbQ2SQ5wwvtlByn8sDYZvdDtdn/VE2yEPZ4BvUnrKWmsbTQY6/ooLV+9Ka2qmDSQ==} 44 | engines: {node: '>=18.0.0'} 45 | 46 | '@deepgram/sdk@4.11.2': 47 | resolution: {integrity: sha512-lKGxuXxlSixC8bB0BnzmIpbVjUSgYtz17cqvrgv0ZjmazgUPkuUj9egQPj6k+fbPX8wRzWEqlhrL/DXlXqeDXA==} 48 | engines: {node: '>=18.0.0'} 49 | 50 | '@flydotio/dockerfile@0.7.10': 51 | resolution: {integrity: sha512-dTXqBjCl7nFmnhlyeDjjPtX+sdfYBWFH9PUKNqAYttvBiczKcYXxr7/0A0wZ+g1FB1tmMzsOzedgr6xap/AB9g==} 52 | engines: {node: '>=16.0.0'} 53 | hasBin: true 54 | 55 | '@inquirer/ansi@1.0.2': 56 | resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} 57 | engines: {node: '>=18'} 58 | 59 | '@inquirer/checkbox@4.3.2': 60 | resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} 61 | engines: {node: '>=18'} 62 | peerDependencies: 63 | '@types/node': '>=18' 64 | peerDependenciesMeta: 65 | '@types/node': 66 | optional: true 67 | 68 | '@inquirer/confirm@5.1.21': 69 | resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} 70 | engines: {node: '>=18'} 71 | peerDependencies: 72 | '@types/node': '>=18' 73 | peerDependenciesMeta: 74 | '@types/node': 75 | optional: true 76 | 77 | '@inquirer/core@10.3.2': 78 | resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} 79 | engines: {node: '>=18'} 80 | peerDependencies: 81 | '@types/node': '>=18' 82 | peerDependenciesMeta: 83 | '@types/node': 84 | optional: true 85 | 86 | '@inquirer/editor@4.2.23': 87 | resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} 88 | engines: {node: '>=18'} 89 | peerDependencies: 90 | '@types/node': '>=18' 91 | peerDependenciesMeta: 92 | '@types/node': 93 | optional: true 94 | 95 | '@inquirer/expand@4.0.23': 96 | resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} 97 | engines: {node: '>=18'} 98 | peerDependencies: 99 | '@types/node': '>=18' 100 | peerDependenciesMeta: 101 | '@types/node': 102 | optional: true 103 | 104 | '@inquirer/external-editor@1.0.3': 105 | resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} 106 | engines: {node: '>=18'} 107 | peerDependencies: 108 | '@types/node': '>=18' 109 | peerDependenciesMeta: 110 | '@types/node': 111 | optional: true 112 | 113 | '@inquirer/figures@1.0.15': 114 | resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} 115 | engines: {node: '>=18'} 116 | 117 | '@inquirer/input@4.3.1': 118 | resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} 119 | engines: {node: '>=18'} 120 | peerDependencies: 121 | '@types/node': '>=18' 122 | peerDependenciesMeta: 123 | '@types/node': 124 | optional: true 125 | 126 | '@inquirer/number@3.0.23': 127 | resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} 128 | engines: {node: '>=18'} 129 | peerDependencies: 130 | '@types/node': '>=18' 131 | peerDependenciesMeta: 132 | '@types/node': 133 | optional: true 134 | 135 | '@inquirer/password@4.0.23': 136 | resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} 137 | engines: {node: '>=18'} 138 | peerDependencies: 139 | '@types/node': '>=18' 140 | peerDependenciesMeta: 141 | '@types/node': 142 | optional: true 143 | 144 | '@inquirer/prompts@7.10.1': 145 | resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} 146 | engines: {node: '>=18'} 147 | peerDependencies: 148 | '@types/node': '>=18' 149 | peerDependenciesMeta: 150 | '@types/node': 151 | optional: true 152 | 153 | '@inquirer/rawlist@4.1.11': 154 | resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} 155 | engines: {node: '>=18'} 156 | peerDependencies: 157 | '@types/node': '>=18' 158 | peerDependenciesMeta: 159 | '@types/node': 160 | optional: true 161 | 162 | '@inquirer/search@3.2.2': 163 | resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} 164 | engines: {node: '>=18'} 165 | peerDependencies: 166 | '@types/node': '>=18' 167 | peerDependenciesMeta: 168 | '@types/node': 169 | optional: true 170 | 171 | '@inquirer/select@4.4.2': 172 | resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} 173 | engines: {node: '>=18'} 174 | peerDependencies: 175 | '@types/node': '>=18' 176 | peerDependenciesMeta: 177 | '@types/node': 178 | optional: true 179 | 180 | '@inquirer/type@3.0.10': 181 | resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} 182 | engines: {node: '>=18'} 183 | peerDependencies: 184 | '@types/node': '>=18' 185 | peerDependenciesMeta: 186 | '@types/node': 187 | optional: true 188 | 189 | '@types/http-proxy@1.17.17': 190 | resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} 191 | 192 | '@types/node@18.19.130': 193 | resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} 194 | 195 | '@types/node@24.10.2': 196 | resolution: {integrity: sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==} 197 | 198 | accepts@2.0.0: 199 | resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} 200 | engines: {node: '>= 0.6'} 201 | 202 | ansi-regex@5.0.1: 203 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 204 | engines: {node: '>=8'} 205 | 206 | ansi-styles@3.2.1: 207 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 208 | engines: {node: '>=4'} 209 | 210 | ansi-styles@4.3.0: 211 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 212 | engines: {node: '>=8'} 213 | 214 | anymatch@3.1.3: 215 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 216 | engines: {node: '>= 8'} 217 | 218 | append-field@1.0.0: 219 | resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} 220 | 221 | array-buffer-byte-length@1.0.2: 222 | resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} 223 | engines: {node: '>= 0.4'} 224 | 225 | arraybuffer.prototype.slice@1.0.4: 226 | resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} 227 | engines: {node: '>= 0.4'} 228 | 229 | async-function@1.0.0: 230 | resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} 231 | engines: {node: '>= 0.4'} 232 | 233 | async@3.2.6: 234 | resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} 235 | 236 | available-typed-arrays@1.0.7: 237 | resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} 238 | engines: {node: '>= 0.4'} 239 | 240 | balanced-match@1.0.2: 241 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 242 | 243 | binary-extensions@2.3.0: 244 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} 245 | engines: {node: '>=8'} 246 | 247 | body-parser@2.2.1: 248 | resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} 249 | engines: {node: '>=18'} 250 | 251 | brace-expansion@1.1.12: 252 | resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} 253 | 254 | brace-expansion@2.0.2: 255 | resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} 256 | 257 | braces@3.0.3: 258 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} 259 | engines: {node: '>=8'} 260 | 261 | buffer-from@1.1.2: 262 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 263 | 264 | busboy@1.6.0: 265 | resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} 266 | engines: {node: '>=10.16.0'} 267 | 268 | bytes@3.1.2: 269 | resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} 270 | engines: {node: '>= 0.8'} 271 | 272 | call-bind-apply-helpers@1.0.2: 273 | resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} 274 | engines: {node: '>= 0.4'} 275 | 276 | call-bind@1.0.8: 277 | resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} 278 | engines: {node: '>= 0.4'} 279 | 280 | call-bound@1.0.4: 281 | resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} 282 | engines: {node: '>= 0.4'} 283 | 284 | chalk@2.4.2: 285 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 286 | engines: {node: '>=4'} 287 | 288 | chalk@5.6.2: 289 | resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} 290 | engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 291 | 292 | chardet@2.1.1: 293 | resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} 294 | 295 | chokidar@3.6.0: 296 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 297 | engines: {node: '>= 8.10.0'} 298 | 299 | cli-width@4.1.0: 300 | resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} 301 | engines: {node: '>= 12'} 302 | 303 | cliui@8.0.1: 304 | resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} 305 | engines: {node: '>=12'} 306 | 307 | color-convert@1.9.3: 308 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 309 | 310 | color-convert@2.0.1: 311 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 312 | engines: {node: '>=7.0.0'} 313 | 314 | color-name@1.1.3: 315 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 316 | 317 | color-name@1.1.4: 318 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 319 | 320 | concat-map@0.0.1: 321 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 322 | 323 | concat-stream@2.0.0: 324 | resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} 325 | engines: {'0': node >= 6.0} 326 | 327 | content-disposition@1.0.1: 328 | resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} 329 | engines: {node: '>=18'} 330 | 331 | content-type@1.0.5: 332 | resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} 333 | engines: {node: '>= 0.6'} 334 | 335 | cookie-signature@1.2.2: 336 | resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} 337 | engines: {node: '>=6.6.0'} 338 | 339 | cookie@0.7.2: 340 | resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} 341 | engines: {node: '>= 0.6'} 342 | 343 | cors@2.8.5: 344 | resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} 345 | engines: {node: '>= 0.10'} 346 | 347 | cross-fetch@3.2.0: 348 | resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} 349 | 350 | cross-spawn@6.0.6: 351 | resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} 352 | engines: {node: '>=4.8'} 353 | 354 | data-view-buffer@1.0.2: 355 | resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} 356 | engines: {node: '>= 0.4'} 357 | 358 | data-view-byte-length@1.0.2: 359 | resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} 360 | engines: {node: '>= 0.4'} 361 | 362 | data-view-byte-offset@1.0.1: 363 | resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} 364 | engines: {node: '>= 0.4'} 365 | 366 | dayjs@1.11.19: 367 | resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} 368 | 369 | debug@4.4.3: 370 | resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} 371 | engines: {node: '>=6.0'} 372 | peerDependencies: 373 | supports-color: '*' 374 | peerDependenciesMeta: 375 | supports-color: 376 | optional: true 377 | 378 | deepmerge@4.3.1: 379 | resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} 380 | engines: {node: '>=0.10.0'} 381 | 382 | define-data-property@1.1.4: 383 | resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} 384 | engines: {node: '>= 0.4'} 385 | 386 | define-properties@1.2.1: 387 | resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} 388 | engines: {node: '>= 0.4'} 389 | 390 | depd@2.0.0: 391 | resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} 392 | engines: {node: '>= 0.8'} 393 | 394 | diff@7.0.0: 395 | resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} 396 | engines: {node: '>=0.3.1'} 397 | 398 | dotenv@17.2.3: 399 | resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} 400 | engines: {node: '>=12'} 401 | 402 | dunder-proto@1.0.1: 403 | resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} 404 | engines: {node: '>= 0.4'} 405 | 406 | ee-first@1.1.1: 407 | resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} 408 | 409 | ejs@3.1.10: 410 | resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} 411 | engines: {node: '>=0.10.0'} 412 | hasBin: true 413 | 414 | emoji-regex@8.0.0: 415 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 416 | 417 | encodeurl@2.0.0: 418 | resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} 419 | engines: {node: '>= 0.8'} 420 | 421 | error-ex@1.3.4: 422 | resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} 423 | 424 | es-abstract@1.24.0: 425 | resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} 426 | engines: {node: '>= 0.4'} 427 | 428 | es-define-property@1.0.1: 429 | resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} 430 | engines: {node: '>= 0.4'} 431 | 432 | es-errors@1.3.0: 433 | resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} 434 | engines: {node: '>= 0.4'} 435 | 436 | es-object-atoms@1.1.1: 437 | resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} 438 | engines: {node: '>= 0.4'} 439 | 440 | es-set-tostringtag@2.1.0: 441 | resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} 442 | engines: {node: '>= 0.4'} 443 | 444 | es-to-primitive@1.3.0: 445 | resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} 446 | engines: {node: '>= 0.4'} 447 | 448 | escalade@3.2.0: 449 | resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} 450 | engines: {node: '>=6'} 451 | 452 | escape-html@1.0.3: 453 | resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} 454 | 455 | escape-string-regexp@1.0.5: 456 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 457 | engines: {node: '>=0.8.0'} 458 | 459 | etag@1.8.1: 460 | resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} 461 | engines: {node: '>= 0.6'} 462 | 463 | eventemitter3@4.0.7: 464 | resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} 465 | 466 | events@3.3.0: 467 | resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 468 | engines: {node: '>=0.8.x'} 469 | 470 | express@5.2.1: 471 | resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} 472 | engines: {node: '>= 18'} 473 | 474 | filelist@1.0.4: 475 | resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} 476 | 477 | fill-range@7.1.1: 478 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} 479 | engines: {node: '>=8'} 480 | 481 | finalhandler@2.1.1: 482 | resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} 483 | engines: {node: '>= 18.0.0'} 484 | 485 | follow-redirects@1.15.11: 486 | resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} 487 | engines: {node: '>=4.0'} 488 | peerDependencies: 489 | debug: '*' 490 | peerDependenciesMeta: 491 | debug: 492 | optional: true 493 | 494 | for-each@0.3.5: 495 | resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} 496 | engines: {node: '>= 0.4'} 497 | 498 | forwarded@0.2.0: 499 | resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} 500 | engines: {node: '>= 0.6'} 501 | 502 | fresh@2.0.0: 503 | resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} 504 | engines: {node: '>= 0.8'} 505 | 506 | fsevents@2.3.3: 507 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 508 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 509 | os: [darwin] 510 | 511 | function-bind@1.1.2: 512 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} 513 | 514 | function.prototype.name@1.1.8: 515 | resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} 516 | engines: {node: '>= 0.4'} 517 | 518 | functions-have-names@1.2.3: 519 | resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} 520 | 521 | generator-function@2.0.1: 522 | resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} 523 | engines: {node: '>= 0.4'} 524 | 525 | get-caller-file@2.0.5: 526 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 527 | engines: {node: 6.* || 8.* || >= 10.*} 528 | 529 | get-intrinsic@1.3.0: 530 | resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} 531 | engines: {node: '>= 0.4'} 532 | 533 | get-proto@1.0.1: 534 | resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} 535 | engines: {node: '>= 0.4'} 536 | 537 | get-symbol-description@1.1.0: 538 | resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} 539 | engines: {node: '>= 0.4'} 540 | 541 | glob-parent@5.1.2: 542 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 543 | engines: {node: '>= 6'} 544 | 545 | globalthis@1.0.4: 546 | resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} 547 | engines: {node: '>= 0.4'} 548 | 549 | gopd@1.2.0: 550 | resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} 551 | engines: {node: '>= 0.4'} 552 | 553 | graceful-fs@4.2.11: 554 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} 555 | 556 | has-bigints@1.1.0: 557 | resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} 558 | engines: {node: '>= 0.4'} 559 | 560 | has-flag@3.0.0: 561 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 562 | engines: {node: '>=4'} 563 | 564 | has-property-descriptors@1.0.2: 565 | resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} 566 | 567 | has-proto@1.2.0: 568 | resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} 569 | engines: {node: '>= 0.4'} 570 | 571 | has-symbols@1.1.0: 572 | resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} 573 | engines: {node: '>= 0.4'} 574 | 575 | has-tostringtag@1.0.2: 576 | resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} 577 | engines: {node: '>= 0.4'} 578 | 579 | hasown@2.0.2: 580 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} 581 | engines: {node: '>= 0.4'} 582 | 583 | hosted-git-info@2.8.9: 584 | resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} 585 | 586 | http-errors@2.0.1: 587 | resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} 588 | engines: {node: '>= 0.8'} 589 | 590 | http-proxy-middleware@3.0.5: 591 | resolution: {integrity: sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==} 592 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} 593 | 594 | http-proxy@1.18.1: 595 | resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} 596 | engines: {node: '>=8.0.0'} 597 | 598 | iconv-lite@0.7.0: 599 | resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} 600 | engines: {node: '>=0.10.0'} 601 | 602 | ignore-by-default@1.0.1: 603 | resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} 604 | 605 | inherits@2.0.4: 606 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 607 | 608 | inquirer@12.11.1: 609 | resolution: {integrity: sha512-9VF7mrY+3OmsAfjH3yKz/pLbJ5z22E23hENKw3/LNSaA/sAt3v49bDRY+Ygct1xwuKT+U+cBfTzjCPySna69Qw==} 610 | engines: {node: '>=18'} 611 | peerDependencies: 612 | '@types/node': '>=18' 613 | peerDependenciesMeta: 614 | '@types/node': 615 | optional: true 616 | 617 | internal-slot@1.1.0: 618 | resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} 619 | engines: {node: '>= 0.4'} 620 | 621 | ipaddr.js@1.9.1: 622 | resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} 623 | engines: {node: '>= 0.10'} 624 | 625 | is-array-buffer@3.0.5: 626 | resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} 627 | engines: {node: '>= 0.4'} 628 | 629 | is-arrayish@0.2.1: 630 | resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 631 | 632 | is-async-function@2.1.1: 633 | resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} 634 | engines: {node: '>= 0.4'} 635 | 636 | is-bigint@1.1.0: 637 | resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} 638 | engines: {node: '>= 0.4'} 639 | 640 | is-binary-path@2.1.0: 641 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 642 | engines: {node: '>=8'} 643 | 644 | is-boolean-object@1.2.2: 645 | resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} 646 | engines: {node: '>= 0.4'} 647 | 648 | is-callable@1.2.7: 649 | resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} 650 | engines: {node: '>= 0.4'} 651 | 652 | is-core-module@2.16.1: 653 | resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} 654 | engines: {node: '>= 0.4'} 655 | 656 | is-data-view@1.0.2: 657 | resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} 658 | engines: {node: '>= 0.4'} 659 | 660 | is-date-object@1.1.0: 661 | resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} 662 | engines: {node: '>= 0.4'} 663 | 664 | is-extglob@2.1.1: 665 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 666 | engines: {node: '>=0.10.0'} 667 | 668 | is-finalizationregistry@1.1.1: 669 | resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} 670 | engines: {node: '>= 0.4'} 671 | 672 | is-fullwidth-code-point@3.0.0: 673 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 674 | engines: {node: '>=8'} 675 | 676 | is-generator-function@1.1.2: 677 | resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} 678 | engines: {node: '>= 0.4'} 679 | 680 | is-glob@4.0.3: 681 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 682 | engines: {node: '>=0.10.0'} 683 | 684 | is-map@2.0.3: 685 | resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} 686 | engines: {node: '>= 0.4'} 687 | 688 | is-negative-zero@2.0.3: 689 | resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} 690 | engines: {node: '>= 0.4'} 691 | 692 | is-number-object@1.1.1: 693 | resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} 694 | engines: {node: '>= 0.4'} 695 | 696 | is-number@7.0.0: 697 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 698 | engines: {node: '>=0.12.0'} 699 | 700 | is-plain-object@5.0.0: 701 | resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} 702 | engines: {node: '>=0.10.0'} 703 | 704 | is-promise@4.0.0: 705 | resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} 706 | 707 | is-regex@1.2.1: 708 | resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} 709 | engines: {node: '>= 0.4'} 710 | 711 | is-set@2.0.3: 712 | resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} 713 | engines: {node: '>= 0.4'} 714 | 715 | is-shared-array-buffer@1.0.4: 716 | resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} 717 | engines: {node: '>= 0.4'} 718 | 719 | is-string@1.1.1: 720 | resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} 721 | engines: {node: '>= 0.4'} 722 | 723 | is-symbol@1.1.1: 724 | resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} 725 | engines: {node: '>= 0.4'} 726 | 727 | is-typed-array@1.1.15: 728 | resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} 729 | engines: {node: '>= 0.4'} 730 | 731 | is-weakmap@2.0.2: 732 | resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} 733 | engines: {node: '>= 0.4'} 734 | 735 | is-weakref@1.1.1: 736 | resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} 737 | engines: {node: '>= 0.4'} 738 | 739 | is-weakset@2.0.4: 740 | resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} 741 | engines: {node: '>= 0.4'} 742 | 743 | isarray@2.0.5: 744 | resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} 745 | 746 | isexe@2.0.0: 747 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 748 | 749 | jake@10.9.4: 750 | resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} 751 | engines: {node: '>=10'} 752 | hasBin: true 753 | 754 | json-parse-better-errors@1.0.2: 755 | resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} 756 | 757 | load-json-file@4.0.0: 758 | resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} 759 | engines: {node: '>=4'} 760 | 761 | math-intrinsics@1.1.0: 762 | resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} 763 | engines: {node: '>= 0.4'} 764 | 765 | media-typer@0.3.0: 766 | resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} 767 | engines: {node: '>= 0.6'} 768 | 769 | media-typer@1.1.0: 770 | resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} 771 | engines: {node: '>= 0.8'} 772 | 773 | memorystream@0.3.1: 774 | resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} 775 | engines: {node: '>= 0.10.0'} 776 | 777 | merge-descriptors@2.0.0: 778 | resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} 779 | engines: {node: '>=18'} 780 | 781 | micromatch@4.0.8: 782 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} 783 | engines: {node: '>=8.6'} 784 | 785 | mime-db@1.52.0: 786 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 787 | engines: {node: '>= 0.6'} 788 | 789 | mime-db@1.54.0: 790 | resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} 791 | engines: {node: '>= 0.6'} 792 | 793 | mime-types@2.1.35: 794 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 795 | engines: {node: '>= 0.6'} 796 | 797 | mime-types@3.0.2: 798 | resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} 799 | engines: {node: '>=18'} 800 | 801 | minimatch@3.1.2: 802 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 803 | 804 | minimatch@5.1.6: 805 | resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} 806 | engines: {node: '>=10'} 807 | 808 | minimist@1.2.8: 809 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 810 | 811 | mkdirp@0.5.6: 812 | resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} 813 | hasBin: true 814 | 815 | ms@2.1.3: 816 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 817 | 818 | multer@2.0.2: 819 | resolution: {integrity: sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==} 820 | engines: {node: '>= 10.16.0'} 821 | 822 | mute-stream@2.0.0: 823 | resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} 824 | engines: {node: ^18.17.0 || >=20.5.0} 825 | 826 | negotiator@1.0.0: 827 | resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} 828 | engines: {node: '>= 0.6'} 829 | 830 | nice-try@1.0.5: 831 | resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} 832 | 833 | node-fetch@2.7.0: 834 | resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} 835 | engines: {node: 4.x || >=6.0.0} 836 | peerDependencies: 837 | encoding: ^0.1.0 838 | peerDependenciesMeta: 839 | encoding: 840 | optional: true 841 | 842 | nodemon@3.1.10: 843 | resolution: {integrity: sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==} 844 | engines: {node: '>=10'} 845 | hasBin: true 846 | 847 | normalize-package-data@2.5.0: 848 | resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} 849 | 850 | normalize-path@3.0.0: 851 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 852 | engines: {node: '>=0.10.0'} 853 | 854 | npm-run-all@4.1.5: 855 | resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} 856 | engines: {node: '>= 4'} 857 | hasBin: true 858 | 859 | object-assign@4.1.1: 860 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 861 | engines: {node: '>=0.10.0'} 862 | 863 | object-inspect@1.13.4: 864 | resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} 865 | engines: {node: '>= 0.4'} 866 | 867 | object-keys@1.1.1: 868 | resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} 869 | engines: {node: '>= 0.4'} 870 | 871 | object.assign@4.1.7: 872 | resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} 873 | engines: {node: '>= 0.4'} 874 | 875 | on-finished@2.4.1: 876 | resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} 877 | engines: {node: '>= 0.8'} 878 | 879 | once@1.4.0: 880 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 881 | 882 | own-keys@1.0.1: 883 | resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} 884 | engines: {node: '>= 0.4'} 885 | 886 | parse-json@4.0.0: 887 | resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} 888 | engines: {node: '>=4'} 889 | 890 | parseurl@1.3.3: 891 | resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} 892 | engines: {node: '>= 0.8'} 893 | 894 | path-key@2.0.1: 895 | resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} 896 | engines: {node: '>=4'} 897 | 898 | path-parse@1.0.7: 899 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 900 | 901 | path-to-regexp@8.3.0: 902 | resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} 903 | 904 | path-type@3.0.0: 905 | resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} 906 | engines: {node: '>=4'} 907 | 908 | picocolors@1.1.1: 909 | resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} 910 | 911 | picomatch@2.3.1: 912 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 913 | engines: {node: '>=8.6'} 914 | 915 | pidtree@0.3.1: 916 | resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} 917 | engines: {node: '>=0.10'} 918 | hasBin: true 919 | 920 | pify@3.0.0: 921 | resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} 922 | engines: {node: '>=4'} 923 | 924 | possible-typed-array-names@1.1.0: 925 | resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} 926 | engines: {node: '>= 0.4'} 927 | 928 | proxy-addr@2.0.7: 929 | resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} 930 | engines: {node: '>= 0.10'} 931 | 932 | pstree.remy@1.1.8: 933 | resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} 934 | 935 | qs@6.14.0: 936 | resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} 937 | engines: {node: '>=0.6'} 938 | 939 | range-parser@1.2.1: 940 | resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} 941 | engines: {node: '>= 0.6'} 942 | 943 | raw-body@3.0.2: 944 | resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} 945 | engines: {node: '>= 0.10'} 946 | 947 | read-pkg@3.0.0: 948 | resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} 949 | engines: {node: '>=4'} 950 | 951 | readable-stream@3.6.2: 952 | resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} 953 | engines: {node: '>= 6'} 954 | 955 | readdirp@3.6.0: 956 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 957 | engines: {node: '>=8.10.0'} 958 | 959 | reflect.getprototypeof@1.0.10: 960 | resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} 961 | engines: {node: '>= 0.4'} 962 | 963 | regexp.prototype.flags@1.5.4: 964 | resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} 965 | engines: {node: '>= 0.4'} 966 | 967 | require-directory@2.1.1: 968 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 969 | engines: {node: '>=0.10.0'} 970 | 971 | requires-port@1.0.0: 972 | resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} 973 | 974 | resolve@1.22.11: 975 | resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} 976 | engines: {node: '>= 0.4'} 977 | hasBin: true 978 | 979 | router@2.2.0: 980 | resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} 981 | engines: {node: '>= 18'} 982 | 983 | run-async@4.0.6: 984 | resolution: {integrity: sha512-IoDlSLTs3Yq593mb3ZoKWKXMNu3UpObxhgA/Xuid5p4bbfi2jdY1Hj0m1K+0/tEuQTxIGMhQDqGjKb7RuxGpAQ==} 985 | engines: {node: '>=0.12.0'} 986 | 987 | rxjs@7.8.2: 988 | resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} 989 | 990 | safe-array-concat@1.1.3: 991 | resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} 992 | engines: {node: '>=0.4'} 993 | 994 | safe-buffer@5.2.1: 995 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 996 | 997 | safe-push-apply@1.0.0: 998 | resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} 999 | engines: {node: '>= 0.4'} 1000 | 1001 | safe-regex-test@1.1.0: 1002 | resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} 1003 | engines: {node: '>= 0.4'} 1004 | 1005 | safer-buffer@2.1.2: 1006 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 1007 | 1008 | semver@5.7.2: 1009 | resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} 1010 | hasBin: true 1011 | 1012 | semver@7.7.3: 1013 | resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} 1014 | engines: {node: '>=10'} 1015 | hasBin: true 1016 | 1017 | send@1.2.0: 1018 | resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} 1019 | engines: {node: '>= 18'} 1020 | 1021 | serve-static@2.2.0: 1022 | resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} 1023 | engines: {node: '>= 18'} 1024 | 1025 | set-function-length@1.2.2: 1026 | resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} 1027 | engines: {node: '>= 0.4'} 1028 | 1029 | set-function-name@2.0.2: 1030 | resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} 1031 | engines: {node: '>= 0.4'} 1032 | 1033 | set-proto@1.0.0: 1034 | resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} 1035 | engines: {node: '>= 0.4'} 1036 | 1037 | setprototypeof@1.2.0: 1038 | resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} 1039 | 1040 | shebang-command@1.2.0: 1041 | resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} 1042 | engines: {node: '>=0.10.0'} 1043 | 1044 | shebang-regex@1.0.0: 1045 | resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} 1046 | engines: {node: '>=0.10.0'} 1047 | 1048 | shell-quote@1.8.3: 1049 | resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} 1050 | engines: {node: '>= 0.4'} 1051 | 1052 | side-channel-list@1.0.0: 1053 | resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} 1054 | engines: {node: '>= 0.4'} 1055 | 1056 | side-channel-map@1.0.1: 1057 | resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} 1058 | engines: {node: '>= 0.4'} 1059 | 1060 | side-channel-weakmap@1.0.2: 1061 | resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} 1062 | engines: {node: '>= 0.4'} 1063 | 1064 | side-channel@1.1.0: 1065 | resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} 1066 | engines: {node: '>= 0.4'} 1067 | 1068 | signal-exit@4.1.0: 1069 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1070 | engines: {node: '>=14'} 1071 | 1072 | simple-update-notifier@2.0.0: 1073 | resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} 1074 | engines: {node: '>=10'} 1075 | 1076 | spdx-correct@3.2.0: 1077 | resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} 1078 | 1079 | spdx-exceptions@2.5.0: 1080 | resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} 1081 | 1082 | spdx-expression-parse@3.0.1: 1083 | resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} 1084 | 1085 | spdx-license-ids@3.0.22: 1086 | resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} 1087 | 1088 | statuses@2.0.2: 1089 | resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} 1090 | engines: {node: '>= 0.8'} 1091 | 1092 | stop-iteration-iterator@1.1.0: 1093 | resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} 1094 | engines: {node: '>= 0.4'} 1095 | 1096 | streamsearch@1.1.0: 1097 | resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} 1098 | engines: {node: '>=10.0.0'} 1099 | 1100 | string-width@4.2.3: 1101 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1102 | engines: {node: '>=8'} 1103 | 1104 | string.prototype.padend@3.1.6: 1105 | resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} 1106 | engines: {node: '>= 0.4'} 1107 | 1108 | string.prototype.trim@1.2.10: 1109 | resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} 1110 | engines: {node: '>= 0.4'} 1111 | 1112 | string.prototype.trimend@1.0.9: 1113 | resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} 1114 | engines: {node: '>= 0.4'} 1115 | 1116 | string.prototype.trimstart@1.0.8: 1117 | resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} 1118 | engines: {node: '>= 0.4'} 1119 | 1120 | string_decoder@1.3.0: 1121 | resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} 1122 | 1123 | strip-ansi@6.0.1: 1124 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1125 | engines: {node: '>=8'} 1126 | 1127 | strip-bom@3.0.0: 1128 | resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} 1129 | engines: {node: '>=4'} 1130 | 1131 | supports-color@5.5.0: 1132 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 1133 | engines: {node: '>=4'} 1134 | 1135 | supports-preserve-symlinks-flag@1.0.0: 1136 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1137 | engines: {node: '>= 0.4'} 1138 | 1139 | to-regex-range@5.0.1: 1140 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1141 | engines: {node: '>=8.0'} 1142 | 1143 | toidentifier@1.0.1: 1144 | resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} 1145 | engines: {node: '>=0.6'} 1146 | 1147 | touch@3.1.1: 1148 | resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} 1149 | hasBin: true 1150 | 1151 | tr46@0.0.3: 1152 | resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} 1153 | 1154 | tslib@2.8.1: 1155 | resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} 1156 | 1157 | type-is@1.6.18: 1158 | resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} 1159 | engines: {node: '>= 0.6'} 1160 | 1161 | type-is@2.0.1: 1162 | resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} 1163 | engines: {node: '>= 0.6'} 1164 | 1165 | typed-array-buffer@1.0.3: 1166 | resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} 1167 | engines: {node: '>= 0.4'} 1168 | 1169 | typed-array-byte-length@1.0.3: 1170 | resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} 1171 | engines: {node: '>= 0.4'} 1172 | 1173 | typed-array-byte-offset@1.0.4: 1174 | resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} 1175 | engines: {node: '>= 0.4'} 1176 | 1177 | typed-array-length@1.0.7: 1178 | resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} 1179 | engines: {node: '>= 0.4'} 1180 | 1181 | typedarray@0.0.6: 1182 | resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} 1183 | 1184 | unbox-primitive@1.1.0: 1185 | resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} 1186 | engines: {node: '>= 0.4'} 1187 | 1188 | undefsafe@2.0.5: 1189 | resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} 1190 | 1191 | undici-types@5.26.5: 1192 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} 1193 | 1194 | undici-types@7.16.0: 1195 | resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} 1196 | 1197 | unpipe@1.0.0: 1198 | resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} 1199 | engines: {node: '>= 0.8'} 1200 | 1201 | util-deprecate@1.0.2: 1202 | resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 1203 | 1204 | validate-npm-package-license@3.0.4: 1205 | resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} 1206 | 1207 | vary@1.1.2: 1208 | resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} 1209 | engines: {node: '>= 0.8'} 1210 | 1211 | webidl-conversions@3.0.1: 1212 | resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} 1213 | 1214 | whatwg-url@5.0.0: 1215 | resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} 1216 | 1217 | which-boxed-primitive@1.1.1: 1218 | resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} 1219 | engines: {node: '>= 0.4'} 1220 | 1221 | which-builtin-type@1.2.1: 1222 | resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} 1223 | engines: {node: '>= 0.4'} 1224 | 1225 | which-collection@1.0.2: 1226 | resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} 1227 | engines: {node: '>= 0.4'} 1228 | 1229 | which-typed-array@1.1.19: 1230 | resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} 1231 | engines: {node: '>= 0.4'} 1232 | 1233 | which@1.3.1: 1234 | resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} 1235 | hasBin: true 1236 | 1237 | wrap-ansi@6.2.0: 1238 | resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} 1239 | engines: {node: '>=8'} 1240 | 1241 | wrap-ansi@7.0.0: 1242 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1243 | engines: {node: '>=10'} 1244 | 1245 | wrappy@1.0.2: 1246 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 1247 | 1248 | ws@8.18.3: 1249 | resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} 1250 | engines: {node: '>=10.0.0'} 1251 | peerDependencies: 1252 | bufferutil: ^4.0.1 1253 | utf-8-validate: '>=5.0.2' 1254 | peerDependenciesMeta: 1255 | bufferutil: 1256 | optional: true 1257 | utf-8-validate: 1258 | optional: true 1259 | 1260 | xtend@4.0.2: 1261 | resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} 1262 | engines: {node: '>=0.4'} 1263 | 1264 | y18n@5.0.8: 1265 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 1266 | engines: {node: '>=10'} 1267 | 1268 | yargs-parser@21.1.1: 1269 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} 1270 | engines: {node: '>=12'} 1271 | 1272 | yargs@17.7.2: 1273 | resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} 1274 | engines: {node: '>=12'} 1275 | 1276 | yoctocolors-cjs@2.1.3: 1277 | resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} 1278 | engines: {node: '>=18'} 1279 | 1280 | snapshots: 1281 | 1282 | '@deepgram/captions@1.2.0': 1283 | dependencies: 1284 | dayjs: 1.11.19 1285 | 1286 | '@deepgram/sdk@4.11.2': 1287 | dependencies: 1288 | '@deepgram/captions': 1.2.0 1289 | '@types/node': 18.19.130 1290 | cross-fetch: 3.2.0 1291 | deepmerge: 4.3.1 1292 | events: 3.3.0 1293 | ws: 8.18.3 1294 | transitivePeerDependencies: 1295 | - bufferutil 1296 | - encoding 1297 | - utf-8-validate 1298 | 1299 | '@flydotio/dockerfile@0.7.10(@types/node@24.10.2)': 1300 | dependencies: 1301 | chalk: 5.6.2 1302 | diff: 7.0.0 1303 | ejs: 3.1.10 1304 | inquirer: 12.11.1(@types/node@24.10.2) 1305 | shell-quote: 1.8.3 1306 | yargs: 17.7.2 1307 | transitivePeerDependencies: 1308 | - '@types/node' 1309 | 1310 | '@inquirer/ansi@1.0.2': {} 1311 | 1312 | '@inquirer/checkbox@4.3.2(@types/node@24.10.2)': 1313 | dependencies: 1314 | '@inquirer/ansi': 1.0.2 1315 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1316 | '@inquirer/figures': 1.0.15 1317 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1318 | yoctocolors-cjs: 2.1.3 1319 | optionalDependencies: 1320 | '@types/node': 24.10.2 1321 | 1322 | '@inquirer/confirm@5.1.21(@types/node@24.10.2)': 1323 | dependencies: 1324 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1325 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1326 | optionalDependencies: 1327 | '@types/node': 24.10.2 1328 | 1329 | '@inquirer/core@10.3.2(@types/node@24.10.2)': 1330 | dependencies: 1331 | '@inquirer/ansi': 1.0.2 1332 | '@inquirer/figures': 1.0.15 1333 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1334 | cli-width: 4.1.0 1335 | mute-stream: 2.0.0 1336 | signal-exit: 4.1.0 1337 | wrap-ansi: 6.2.0 1338 | yoctocolors-cjs: 2.1.3 1339 | optionalDependencies: 1340 | '@types/node': 24.10.2 1341 | 1342 | '@inquirer/editor@4.2.23(@types/node@24.10.2)': 1343 | dependencies: 1344 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1345 | '@inquirer/external-editor': 1.0.3(@types/node@24.10.2) 1346 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1347 | optionalDependencies: 1348 | '@types/node': 24.10.2 1349 | 1350 | '@inquirer/expand@4.0.23(@types/node@24.10.2)': 1351 | dependencies: 1352 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1353 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1354 | yoctocolors-cjs: 2.1.3 1355 | optionalDependencies: 1356 | '@types/node': 24.10.2 1357 | 1358 | '@inquirer/external-editor@1.0.3(@types/node@24.10.2)': 1359 | dependencies: 1360 | chardet: 2.1.1 1361 | iconv-lite: 0.7.0 1362 | optionalDependencies: 1363 | '@types/node': 24.10.2 1364 | 1365 | '@inquirer/figures@1.0.15': {} 1366 | 1367 | '@inquirer/input@4.3.1(@types/node@24.10.2)': 1368 | dependencies: 1369 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1370 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1371 | optionalDependencies: 1372 | '@types/node': 24.10.2 1373 | 1374 | '@inquirer/number@3.0.23(@types/node@24.10.2)': 1375 | dependencies: 1376 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1377 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1378 | optionalDependencies: 1379 | '@types/node': 24.10.2 1380 | 1381 | '@inquirer/password@4.0.23(@types/node@24.10.2)': 1382 | dependencies: 1383 | '@inquirer/ansi': 1.0.2 1384 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1385 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1386 | optionalDependencies: 1387 | '@types/node': 24.10.2 1388 | 1389 | '@inquirer/prompts@7.10.1(@types/node@24.10.2)': 1390 | dependencies: 1391 | '@inquirer/checkbox': 4.3.2(@types/node@24.10.2) 1392 | '@inquirer/confirm': 5.1.21(@types/node@24.10.2) 1393 | '@inquirer/editor': 4.2.23(@types/node@24.10.2) 1394 | '@inquirer/expand': 4.0.23(@types/node@24.10.2) 1395 | '@inquirer/input': 4.3.1(@types/node@24.10.2) 1396 | '@inquirer/number': 3.0.23(@types/node@24.10.2) 1397 | '@inquirer/password': 4.0.23(@types/node@24.10.2) 1398 | '@inquirer/rawlist': 4.1.11(@types/node@24.10.2) 1399 | '@inquirer/search': 3.2.2(@types/node@24.10.2) 1400 | '@inquirer/select': 4.4.2(@types/node@24.10.2) 1401 | optionalDependencies: 1402 | '@types/node': 24.10.2 1403 | 1404 | '@inquirer/rawlist@4.1.11(@types/node@24.10.2)': 1405 | dependencies: 1406 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1407 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1408 | yoctocolors-cjs: 2.1.3 1409 | optionalDependencies: 1410 | '@types/node': 24.10.2 1411 | 1412 | '@inquirer/search@3.2.2(@types/node@24.10.2)': 1413 | dependencies: 1414 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1415 | '@inquirer/figures': 1.0.15 1416 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1417 | yoctocolors-cjs: 2.1.3 1418 | optionalDependencies: 1419 | '@types/node': 24.10.2 1420 | 1421 | '@inquirer/select@4.4.2(@types/node@24.10.2)': 1422 | dependencies: 1423 | '@inquirer/ansi': 1.0.2 1424 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1425 | '@inquirer/figures': 1.0.15 1426 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1427 | yoctocolors-cjs: 2.1.3 1428 | optionalDependencies: 1429 | '@types/node': 24.10.2 1430 | 1431 | '@inquirer/type@3.0.10(@types/node@24.10.2)': 1432 | optionalDependencies: 1433 | '@types/node': 24.10.2 1434 | 1435 | '@types/http-proxy@1.17.17': 1436 | dependencies: 1437 | '@types/node': 24.10.2 1438 | 1439 | '@types/node@18.19.130': 1440 | dependencies: 1441 | undici-types: 5.26.5 1442 | 1443 | '@types/node@24.10.2': 1444 | dependencies: 1445 | undici-types: 7.16.0 1446 | 1447 | accepts@2.0.0: 1448 | dependencies: 1449 | mime-types: 3.0.2 1450 | negotiator: 1.0.0 1451 | 1452 | ansi-regex@5.0.1: {} 1453 | 1454 | ansi-styles@3.2.1: 1455 | dependencies: 1456 | color-convert: 1.9.3 1457 | 1458 | ansi-styles@4.3.0: 1459 | dependencies: 1460 | color-convert: 2.0.1 1461 | 1462 | anymatch@3.1.3: 1463 | dependencies: 1464 | normalize-path: 3.0.0 1465 | picomatch: 2.3.1 1466 | 1467 | append-field@1.0.0: {} 1468 | 1469 | array-buffer-byte-length@1.0.2: 1470 | dependencies: 1471 | call-bound: 1.0.4 1472 | is-array-buffer: 3.0.5 1473 | 1474 | arraybuffer.prototype.slice@1.0.4: 1475 | dependencies: 1476 | array-buffer-byte-length: 1.0.2 1477 | call-bind: 1.0.8 1478 | define-properties: 1.2.1 1479 | es-abstract: 1.24.0 1480 | es-errors: 1.3.0 1481 | get-intrinsic: 1.3.0 1482 | is-array-buffer: 3.0.5 1483 | 1484 | async-function@1.0.0: {} 1485 | 1486 | async@3.2.6: {} 1487 | 1488 | available-typed-arrays@1.0.7: 1489 | dependencies: 1490 | possible-typed-array-names: 1.1.0 1491 | 1492 | balanced-match@1.0.2: {} 1493 | 1494 | binary-extensions@2.3.0: {} 1495 | 1496 | body-parser@2.2.1: 1497 | dependencies: 1498 | bytes: 3.1.2 1499 | content-type: 1.0.5 1500 | debug: 4.4.3(supports-color@5.5.0) 1501 | http-errors: 2.0.1 1502 | iconv-lite: 0.7.0 1503 | on-finished: 2.4.1 1504 | qs: 6.14.0 1505 | raw-body: 3.0.2 1506 | type-is: 2.0.1 1507 | transitivePeerDependencies: 1508 | - supports-color 1509 | 1510 | brace-expansion@1.1.12: 1511 | dependencies: 1512 | balanced-match: 1.0.2 1513 | concat-map: 0.0.1 1514 | 1515 | brace-expansion@2.0.2: 1516 | dependencies: 1517 | balanced-match: 1.0.2 1518 | 1519 | braces@3.0.3: 1520 | dependencies: 1521 | fill-range: 7.1.1 1522 | 1523 | buffer-from@1.1.2: {} 1524 | 1525 | busboy@1.6.0: 1526 | dependencies: 1527 | streamsearch: 1.1.0 1528 | 1529 | bytes@3.1.2: {} 1530 | 1531 | call-bind-apply-helpers@1.0.2: 1532 | dependencies: 1533 | es-errors: 1.3.0 1534 | function-bind: 1.1.2 1535 | 1536 | call-bind@1.0.8: 1537 | dependencies: 1538 | call-bind-apply-helpers: 1.0.2 1539 | es-define-property: 1.0.1 1540 | get-intrinsic: 1.3.0 1541 | set-function-length: 1.2.2 1542 | 1543 | call-bound@1.0.4: 1544 | dependencies: 1545 | call-bind-apply-helpers: 1.0.2 1546 | get-intrinsic: 1.3.0 1547 | 1548 | chalk@2.4.2: 1549 | dependencies: 1550 | ansi-styles: 3.2.1 1551 | escape-string-regexp: 1.0.5 1552 | supports-color: 5.5.0 1553 | 1554 | chalk@5.6.2: {} 1555 | 1556 | chardet@2.1.1: {} 1557 | 1558 | chokidar@3.6.0: 1559 | dependencies: 1560 | anymatch: 3.1.3 1561 | braces: 3.0.3 1562 | glob-parent: 5.1.2 1563 | is-binary-path: 2.1.0 1564 | is-glob: 4.0.3 1565 | normalize-path: 3.0.0 1566 | readdirp: 3.6.0 1567 | optionalDependencies: 1568 | fsevents: 2.3.3 1569 | 1570 | cli-width@4.1.0: {} 1571 | 1572 | cliui@8.0.1: 1573 | dependencies: 1574 | string-width: 4.2.3 1575 | strip-ansi: 6.0.1 1576 | wrap-ansi: 7.0.0 1577 | 1578 | color-convert@1.9.3: 1579 | dependencies: 1580 | color-name: 1.1.3 1581 | 1582 | color-convert@2.0.1: 1583 | dependencies: 1584 | color-name: 1.1.4 1585 | 1586 | color-name@1.1.3: {} 1587 | 1588 | color-name@1.1.4: {} 1589 | 1590 | concat-map@0.0.1: {} 1591 | 1592 | concat-stream@2.0.0: 1593 | dependencies: 1594 | buffer-from: 1.1.2 1595 | inherits: 2.0.4 1596 | readable-stream: 3.6.2 1597 | typedarray: 0.0.6 1598 | 1599 | content-disposition@1.0.1: {} 1600 | 1601 | content-type@1.0.5: {} 1602 | 1603 | cookie-signature@1.2.2: {} 1604 | 1605 | cookie@0.7.2: {} 1606 | 1607 | cors@2.8.5: 1608 | dependencies: 1609 | object-assign: 4.1.1 1610 | vary: 1.1.2 1611 | 1612 | cross-fetch@3.2.0: 1613 | dependencies: 1614 | node-fetch: 2.7.0 1615 | transitivePeerDependencies: 1616 | - encoding 1617 | 1618 | cross-spawn@6.0.6: 1619 | dependencies: 1620 | nice-try: 1.0.5 1621 | path-key: 2.0.1 1622 | semver: 5.7.2 1623 | shebang-command: 1.2.0 1624 | which: 1.3.1 1625 | 1626 | data-view-buffer@1.0.2: 1627 | dependencies: 1628 | call-bound: 1.0.4 1629 | es-errors: 1.3.0 1630 | is-data-view: 1.0.2 1631 | 1632 | data-view-byte-length@1.0.2: 1633 | dependencies: 1634 | call-bound: 1.0.4 1635 | es-errors: 1.3.0 1636 | is-data-view: 1.0.2 1637 | 1638 | data-view-byte-offset@1.0.1: 1639 | dependencies: 1640 | call-bound: 1.0.4 1641 | es-errors: 1.3.0 1642 | is-data-view: 1.0.2 1643 | 1644 | dayjs@1.11.19: {} 1645 | 1646 | debug@4.4.3(supports-color@5.5.0): 1647 | dependencies: 1648 | ms: 2.1.3 1649 | optionalDependencies: 1650 | supports-color: 5.5.0 1651 | 1652 | deepmerge@4.3.1: {} 1653 | 1654 | define-data-property@1.1.4: 1655 | dependencies: 1656 | es-define-property: 1.0.1 1657 | es-errors: 1.3.0 1658 | gopd: 1.2.0 1659 | 1660 | define-properties@1.2.1: 1661 | dependencies: 1662 | define-data-property: 1.1.4 1663 | has-property-descriptors: 1.0.2 1664 | object-keys: 1.1.1 1665 | 1666 | depd@2.0.0: {} 1667 | 1668 | diff@7.0.0: {} 1669 | 1670 | dotenv@17.2.3: {} 1671 | 1672 | dunder-proto@1.0.1: 1673 | dependencies: 1674 | call-bind-apply-helpers: 1.0.2 1675 | es-errors: 1.3.0 1676 | gopd: 1.2.0 1677 | 1678 | ee-first@1.1.1: {} 1679 | 1680 | ejs@3.1.10: 1681 | dependencies: 1682 | jake: 10.9.4 1683 | 1684 | emoji-regex@8.0.0: {} 1685 | 1686 | encodeurl@2.0.0: {} 1687 | 1688 | error-ex@1.3.4: 1689 | dependencies: 1690 | is-arrayish: 0.2.1 1691 | 1692 | es-abstract@1.24.0: 1693 | dependencies: 1694 | array-buffer-byte-length: 1.0.2 1695 | arraybuffer.prototype.slice: 1.0.4 1696 | available-typed-arrays: 1.0.7 1697 | call-bind: 1.0.8 1698 | call-bound: 1.0.4 1699 | data-view-buffer: 1.0.2 1700 | data-view-byte-length: 1.0.2 1701 | data-view-byte-offset: 1.0.1 1702 | es-define-property: 1.0.1 1703 | es-errors: 1.3.0 1704 | es-object-atoms: 1.1.1 1705 | es-set-tostringtag: 2.1.0 1706 | es-to-primitive: 1.3.0 1707 | function.prototype.name: 1.1.8 1708 | get-intrinsic: 1.3.0 1709 | get-proto: 1.0.1 1710 | get-symbol-description: 1.1.0 1711 | globalthis: 1.0.4 1712 | gopd: 1.2.0 1713 | has-property-descriptors: 1.0.2 1714 | has-proto: 1.2.0 1715 | has-symbols: 1.1.0 1716 | hasown: 2.0.2 1717 | internal-slot: 1.1.0 1718 | is-array-buffer: 3.0.5 1719 | is-callable: 1.2.7 1720 | is-data-view: 1.0.2 1721 | is-negative-zero: 2.0.3 1722 | is-regex: 1.2.1 1723 | is-set: 2.0.3 1724 | is-shared-array-buffer: 1.0.4 1725 | is-string: 1.1.1 1726 | is-typed-array: 1.1.15 1727 | is-weakref: 1.1.1 1728 | math-intrinsics: 1.1.0 1729 | object-inspect: 1.13.4 1730 | object-keys: 1.1.1 1731 | object.assign: 4.1.7 1732 | own-keys: 1.0.1 1733 | regexp.prototype.flags: 1.5.4 1734 | safe-array-concat: 1.1.3 1735 | safe-push-apply: 1.0.0 1736 | safe-regex-test: 1.1.0 1737 | set-proto: 1.0.0 1738 | stop-iteration-iterator: 1.1.0 1739 | string.prototype.trim: 1.2.10 1740 | string.prototype.trimend: 1.0.9 1741 | string.prototype.trimstart: 1.0.8 1742 | typed-array-buffer: 1.0.3 1743 | typed-array-byte-length: 1.0.3 1744 | typed-array-byte-offset: 1.0.4 1745 | typed-array-length: 1.0.7 1746 | unbox-primitive: 1.1.0 1747 | which-typed-array: 1.1.19 1748 | 1749 | es-define-property@1.0.1: {} 1750 | 1751 | es-errors@1.3.0: {} 1752 | 1753 | es-object-atoms@1.1.1: 1754 | dependencies: 1755 | es-errors: 1.3.0 1756 | 1757 | es-set-tostringtag@2.1.0: 1758 | dependencies: 1759 | es-errors: 1.3.0 1760 | get-intrinsic: 1.3.0 1761 | has-tostringtag: 1.0.2 1762 | hasown: 2.0.2 1763 | 1764 | es-to-primitive@1.3.0: 1765 | dependencies: 1766 | is-callable: 1.2.7 1767 | is-date-object: 1.1.0 1768 | is-symbol: 1.1.1 1769 | 1770 | escalade@3.2.0: {} 1771 | 1772 | escape-html@1.0.3: {} 1773 | 1774 | escape-string-regexp@1.0.5: {} 1775 | 1776 | etag@1.8.1: {} 1777 | 1778 | eventemitter3@4.0.7: {} 1779 | 1780 | events@3.3.0: {} 1781 | 1782 | express@5.2.1: 1783 | dependencies: 1784 | accepts: 2.0.0 1785 | body-parser: 2.2.1 1786 | content-disposition: 1.0.1 1787 | content-type: 1.0.5 1788 | cookie: 0.7.2 1789 | cookie-signature: 1.2.2 1790 | debug: 4.4.3(supports-color@5.5.0) 1791 | depd: 2.0.0 1792 | encodeurl: 2.0.0 1793 | escape-html: 1.0.3 1794 | etag: 1.8.1 1795 | finalhandler: 2.1.1 1796 | fresh: 2.0.0 1797 | http-errors: 2.0.1 1798 | merge-descriptors: 2.0.0 1799 | mime-types: 3.0.2 1800 | on-finished: 2.4.1 1801 | once: 1.4.0 1802 | parseurl: 1.3.3 1803 | proxy-addr: 2.0.7 1804 | qs: 6.14.0 1805 | range-parser: 1.2.1 1806 | router: 2.2.0 1807 | send: 1.2.0 1808 | serve-static: 2.2.0 1809 | statuses: 2.0.2 1810 | type-is: 2.0.1 1811 | vary: 1.1.2 1812 | transitivePeerDependencies: 1813 | - supports-color 1814 | 1815 | filelist@1.0.4: 1816 | dependencies: 1817 | minimatch: 5.1.6 1818 | 1819 | fill-range@7.1.1: 1820 | dependencies: 1821 | to-regex-range: 5.0.1 1822 | 1823 | finalhandler@2.1.1: 1824 | dependencies: 1825 | debug: 4.4.3(supports-color@5.5.0) 1826 | encodeurl: 2.0.0 1827 | escape-html: 1.0.3 1828 | on-finished: 2.4.1 1829 | parseurl: 1.3.3 1830 | statuses: 2.0.2 1831 | transitivePeerDependencies: 1832 | - supports-color 1833 | 1834 | follow-redirects@1.15.11(debug@4.4.3): 1835 | optionalDependencies: 1836 | debug: 4.4.3(supports-color@5.5.0) 1837 | 1838 | for-each@0.3.5: 1839 | dependencies: 1840 | is-callable: 1.2.7 1841 | 1842 | forwarded@0.2.0: {} 1843 | 1844 | fresh@2.0.0: {} 1845 | 1846 | fsevents@2.3.3: 1847 | optional: true 1848 | 1849 | function-bind@1.1.2: {} 1850 | 1851 | function.prototype.name@1.1.8: 1852 | dependencies: 1853 | call-bind: 1.0.8 1854 | call-bound: 1.0.4 1855 | define-properties: 1.2.1 1856 | functions-have-names: 1.2.3 1857 | hasown: 2.0.2 1858 | is-callable: 1.2.7 1859 | 1860 | functions-have-names@1.2.3: {} 1861 | 1862 | generator-function@2.0.1: {} 1863 | 1864 | get-caller-file@2.0.5: {} 1865 | 1866 | get-intrinsic@1.3.0: 1867 | dependencies: 1868 | call-bind-apply-helpers: 1.0.2 1869 | es-define-property: 1.0.1 1870 | es-errors: 1.3.0 1871 | es-object-atoms: 1.1.1 1872 | function-bind: 1.1.2 1873 | get-proto: 1.0.1 1874 | gopd: 1.2.0 1875 | has-symbols: 1.1.0 1876 | hasown: 2.0.2 1877 | math-intrinsics: 1.1.0 1878 | 1879 | get-proto@1.0.1: 1880 | dependencies: 1881 | dunder-proto: 1.0.1 1882 | es-object-atoms: 1.1.1 1883 | 1884 | get-symbol-description@1.1.0: 1885 | dependencies: 1886 | call-bound: 1.0.4 1887 | es-errors: 1.3.0 1888 | get-intrinsic: 1.3.0 1889 | 1890 | glob-parent@5.1.2: 1891 | dependencies: 1892 | is-glob: 4.0.3 1893 | 1894 | globalthis@1.0.4: 1895 | dependencies: 1896 | define-properties: 1.2.1 1897 | gopd: 1.2.0 1898 | 1899 | gopd@1.2.0: {} 1900 | 1901 | graceful-fs@4.2.11: {} 1902 | 1903 | has-bigints@1.1.0: {} 1904 | 1905 | has-flag@3.0.0: {} 1906 | 1907 | has-property-descriptors@1.0.2: 1908 | dependencies: 1909 | es-define-property: 1.0.1 1910 | 1911 | has-proto@1.2.0: 1912 | dependencies: 1913 | dunder-proto: 1.0.1 1914 | 1915 | has-symbols@1.1.0: {} 1916 | 1917 | has-tostringtag@1.0.2: 1918 | dependencies: 1919 | has-symbols: 1.1.0 1920 | 1921 | hasown@2.0.2: 1922 | dependencies: 1923 | function-bind: 1.1.2 1924 | 1925 | hosted-git-info@2.8.9: {} 1926 | 1927 | http-errors@2.0.1: 1928 | dependencies: 1929 | depd: 2.0.0 1930 | inherits: 2.0.4 1931 | setprototypeof: 1.2.0 1932 | statuses: 2.0.2 1933 | toidentifier: 1.0.1 1934 | 1935 | http-proxy-middleware@3.0.5: 1936 | dependencies: 1937 | '@types/http-proxy': 1.17.17 1938 | debug: 4.4.3(supports-color@5.5.0) 1939 | http-proxy: 1.18.1(debug@4.4.3) 1940 | is-glob: 4.0.3 1941 | is-plain-object: 5.0.0 1942 | micromatch: 4.0.8 1943 | transitivePeerDependencies: 1944 | - supports-color 1945 | 1946 | http-proxy@1.18.1(debug@4.4.3): 1947 | dependencies: 1948 | eventemitter3: 4.0.7 1949 | follow-redirects: 1.15.11(debug@4.4.3) 1950 | requires-port: 1.0.0 1951 | transitivePeerDependencies: 1952 | - debug 1953 | 1954 | iconv-lite@0.7.0: 1955 | dependencies: 1956 | safer-buffer: 2.1.2 1957 | 1958 | ignore-by-default@1.0.1: {} 1959 | 1960 | inherits@2.0.4: {} 1961 | 1962 | inquirer@12.11.1(@types/node@24.10.2): 1963 | dependencies: 1964 | '@inquirer/ansi': 1.0.2 1965 | '@inquirer/core': 10.3.2(@types/node@24.10.2) 1966 | '@inquirer/prompts': 7.10.1(@types/node@24.10.2) 1967 | '@inquirer/type': 3.0.10(@types/node@24.10.2) 1968 | mute-stream: 2.0.0 1969 | run-async: 4.0.6 1970 | rxjs: 7.8.2 1971 | optionalDependencies: 1972 | '@types/node': 24.10.2 1973 | 1974 | internal-slot@1.1.0: 1975 | dependencies: 1976 | es-errors: 1.3.0 1977 | hasown: 2.0.2 1978 | side-channel: 1.1.0 1979 | 1980 | ipaddr.js@1.9.1: {} 1981 | 1982 | is-array-buffer@3.0.5: 1983 | dependencies: 1984 | call-bind: 1.0.8 1985 | call-bound: 1.0.4 1986 | get-intrinsic: 1.3.0 1987 | 1988 | is-arrayish@0.2.1: {} 1989 | 1990 | is-async-function@2.1.1: 1991 | dependencies: 1992 | async-function: 1.0.0 1993 | call-bound: 1.0.4 1994 | get-proto: 1.0.1 1995 | has-tostringtag: 1.0.2 1996 | safe-regex-test: 1.1.0 1997 | 1998 | is-bigint@1.1.0: 1999 | dependencies: 2000 | has-bigints: 1.1.0 2001 | 2002 | is-binary-path@2.1.0: 2003 | dependencies: 2004 | binary-extensions: 2.3.0 2005 | 2006 | is-boolean-object@1.2.2: 2007 | dependencies: 2008 | call-bound: 1.0.4 2009 | has-tostringtag: 1.0.2 2010 | 2011 | is-callable@1.2.7: {} 2012 | 2013 | is-core-module@2.16.1: 2014 | dependencies: 2015 | hasown: 2.0.2 2016 | 2017 | is-data-view@1.0.2: 2018 | dependencies: 2019 | call-bound: 1.0.4 2020 | get-intrinsic: 1.3.0 2021 | is-typed-array: 1.1.15 2022 | 2023 | is-date-object@1.1.0: 2024 | dependencies: 2025 | call-bound: 1.0.4 2026 | has-tostringtag: 1.0.2 2027 | 2028 | is-extglob@2.1.1: {} 2029 | 2030 | is-finalizationregistry@1.1.1: 2031 | dependencies: 2032 | call-bound: 1.0.4 2033 | 2034 | is-fullwidth-code-point@3.0.0: {} 2035 | 2036 | is-generator-function@1.1.2: 2037 | dependencies: 2038 | call-bound: 1.0.4 2039 | generator-function: 2.0.1 2040 | get-proto: 1.0.1 2041 | has-tostringtag: 1.0.2 2042 | safe-regex-test: 1.1.0 2043 | 2044 | is-glob@4.0.3: 2045 | dependencies: 2046 | is-extglob: 2.1.1 2047 | 2048 | is-map@2.0.3: {} 2049 | 2050 | is-negative-zero@2.0.3: {} 2051 | 2052 | is-number-object@1.1.1: 2053 | dependencies: 2054 | call-bound: 1.0.4 2055 | has-tostringtag: 1.0.2 2056 | 2057 | is-number@7.0.0: {} 2058 | 2059 | is-plain-object@5.0.0: {} 2060 | 2061 | is-promise@4.0.0: {} 2062 | 2063 | is-regex@1.2.1: 2064 | dependencies: 2065 | call-bound: 1.0.4 2066 | gopd: 1.2.0 2067 | has-tostringtag: 1.0.2 2068 | hasown: 2.0.2 2069 | 2070 | is-set@2.0.3: {} 2071 | 2072 | is-shared-array-buffer@1.0.4: 2073 | dependencies: 2074 | call-bound: 1.0.4 2075 | 2076 | is-string@1.1.1: 2077 | dependencies: 2078 | call-bound: 1.0.4 2079 | has-tostringtag: 1.0.2 2080 | 2081 | is-symbol@1.1.1: 2082 | dependencies: 2083 | call-bound: 1.0.4 2084 | has-symbols: 1.1.0 2085 | safe-regex-test: 1.1.0 2086 | 2087 | is-typed-array@1.1.15: 2088 | dependencies: 2089 | which-typed-array: 1.1.19 2090 | 2091 | is-weakmap@2.0.2: {} 2092 | 2093 | is-weakref@1.1.1: 2094 | dependencies: 2095 | call-bound: 1.0.4 2096 | 2097 | is-weakset@2.0.4: 2098 | dependencies: 2099 | call-bound: 1.0.4 2100 | get-intrinsic: 1.3.0 2101 | 2102 | isarray@2.0.5: {} 2103 | 2104 | isexe@2.0.0: {} 2105 | 2106 | jake@10.9.4: 2107 | dependencies: 2108 | async: 3.2.6 2109 | filelist: 1.0.4 2110 | picocolors: 1.1.1 2111 | 2112 | json-parse-better-errors@1.0.2: {} 2113 | 2114 | load-json-file@4.0.0: 2115 | dependencies: 2116 | graceful-fs: 4.2.11 2117 | parse-json: 4.0.0 2118 | pify: 3.0.0 2119 | strip-bom: 3.0.0 2120 | 2121 | math-intrinsics@1.1.0: {} 2122 | 2123 | media-typer@0.3.0: {} 2124 | 2125 | media-typer@1.1.0: {} 2126 | 2127 | memorystream@0.3.1: {} 2128 | 2129 | merge-descriptors@2.0.0: {} 2130 | 2131 | micromatch@4.0.8: 2132 | dependencies: 2133 | braces: 3.0.3 2134 | picomatch: 2.3.1 2135 | 2136 | mime-db@1.52.0: {} 2137 | 2138 | mime-db@1.54.0: {} 2139 | 2140 | mime-types@2.1.35: 2141 | dependencies: 2142 | mime-db: 1.52.0 2143 | 2144 | mime-types@3.0.2: 2145 | dependencies: 2146 | mime-db: 1.54.0 2147 | 2148 | minimatch@3.1.2: 2149 | dependencies: 2150 | brace-expansion: 1.1.12 2151 | 2152 | minimatch@5.1.6: 2153 | dependencies: 2154 | brace-expansion: 2.0.2 2155 | 2156 | minimist@1.2.8: {} 2157 | 2158 | mkdirp@0.5.6: 2159 | dependencies: 2160 | minimist: 1.2.8 2161 | 2162 | ms@2.1.3: {} 2163 | 2164 | multer@2.0.2: 2165 | dependencies: 2166 | append-field: 1.0.0 2167 | busboy: 1.6.0 2168 | concat-stream: 2.0.0 2169 | mkdirp: 0.5.6 2170 | object-assign: 4.1.1 2171 | type-is: 1.6.18 2172 | xtend: 4.0.2 2173 | 2174 | mute-stream@2.0.0: {} 2175 | 2176 | negotiator@1.0.0: {} 2177 | 2178 | nice-try@1.0.5: {} 2179 | 2180 | node-fetch@2.7.0: 2181 | dependencies: 2182 | whatwg-url: 5.0.0 2183 | 2184 | nodemon@3.1.10: 2185 | dependencies: 2186 | chokidar: 3.6.0 2187 | debug: 4.4.3(supports-color@5.5.0) 2188 | ignore-by-default: 1.0.1 2189 | minimatch: 3.1.2 2190 | pstree.remy: 1.1.8 2191 | semver: 7.7.3 2192 | simple-update-notifier: 2.0.0 2193 | supports-color: 5.5.0 2194 | touch: 3.1.1 2195 | undefsafe: 2.0.5 2196 | 2197 | normalize-package-data@2.5.0: 2198 | dependencies: 2199 | hosted-git-info: 2.8.9 2200 | resolve: 1.22.11 2201 | semver: 5.7.2 2202 | validate-npm-package-license: 3.0.4 2203 | 2204 | normalize-path@3.0.0: {} 2205 | 2206 | npm-run-all@4.1.5: 2207 | dependencies: 2208 | ansi-styles: 3.2.1 2209 | chalk: 2.4.2 2210 | cross-spawn: 6.0.6 2211 | memorystream: 0.3.1 2212 | minimatch: 3.1.2 2213 | pidtree: 0.3.1 2214 | read-pkg: 3.0.0 2215 | shell-quote: 1.8.3 2216 | string.prototype.padend: 3.1.6 2217 | 2218 | object-assign@4.1.1: {} 2219 | 2220 | object-inspect@1.13.4: {} 2221 | 2222 | object-keys@1.1.1: {} 2223 | 2224 | object.assign@4.1.7: 2225 | dependencies: 2226 | call-bind: 1.0.8 2227 | call-bound: 1.0.4 2228 | define-properties: 1.2.1 2229 | es-object-atoms: 1.1.1 2230 | has-symbols: 1.1.0 2231 | object-keys: 1.1.1 2232 | 2233 | on-finished@2.4.1: 2234 | dependencies: 2235 | ee-first: 1.1.1 2236 | 2237 | once@1.4.0: 2238 | dependencies: 2239 | wrappy: 1.0.2 2240 | 2241 | own-keys@1.0.1: 2242 | dependencies: 2243 | get-intrinsic: 1.3.0 2244 | object-keys: 1.1.1 2245 | safe-push-apply: 1.0.0 2246 | 2247 | parse-json@4.0.0: 2248 | dependencies: 2249 | error-ex: 1.3.4 2250 | json-parse-better-errors: 1.0.2 2251 | 2252 | parseurl@1.3.3: {} 2253 | 2254 | path-key@2.0.1: {} 2255 | 2256 | path-parse@1.0.7: {} 2257 | 2258 | path-to-regexp@8.3.0: {} 2259 | 2260 | path-type@3.0.0: 2261 | dependencies: 2262 | pify: 3.0.0 2263 | 2264 | picocolors@1.1.1: {} 2265 | 2266 | picomatch@2.3.1: {} 2267 | 2268 | pidtree@0.3.1: {} 2269 | 2270 | pify@3.0.0: {} 2271 | 2272 | possible-typed-array-names@1.1.0: {} 2273 | 2274 | proxy-addr@2.0.7: 2275 | dependencies: 2276 | forwarded: 0.2.0 2277 | ipaddr.js: 1.9.1 2278 | 2279 | pstree.remy@1.1.8: {} 2280 | 2281 | qs@6.14.0: 2282 | dependencies: 2283 | side-channel: 1.1.0 2284 | 2285 | range-parser@1.2.1: {} 2286 | 2287 | raw-body@3.0.2: 2288 | dependencies: 2289 | bytes: 3.1.2 2290 | http-errors: 2.0.1 2291 | iconv-lite: 0.7.0 2292 | unpipe: 1.0.0 2293 | 2294 | read-pkg@3.0.0: 2295 | dependencies: 2296 | load-json-file: 4.0.0 2297 | normalize-package-data: 2.5.0 2298 | path-type: 3.0.0 2299 | 2300 | readable-stream@3.6.2: 2301 | dependencies: 2302 | inherits: 2.0.4 2303 | string_decoder: 1.3.0 2304 | util-deprecate: 1.0.2 2305 | 2306 | readdirp@3.6.0: 2307 | dependencies: 2308 | picomatch: 2.3.1 2309 | 2310 | reflect.getprototypeof@1.0.10: 2311 | dependencies: 2312 | call-bind: 1.0.8 2313 | define-properties: 1.2.1 2314 | es-abstract: 1.24.0 2315 | es-errors: 1.3.0 2316 | es-object-atoms: 1.1.1 2317 | get-intrinsic: 1.3.0 2318 | get-proto: 1.0.1 2319 | which-builtin-type: 1.2.1 2320 | 2321 | regexp.prototype.flags@1.5.4: 2322 | dependencies: 2323 | call-bind: 1.0.8 2324 | define-properties: 1.2.1 2325 | es-errors: 1.3.0 2326 | get-proto: 1.0.1 2327 | gopd: 1.2.0 2328 | set-function-name: 2.0.2 2329 | 2330 | require-directory@2.1.1: {} 2331 | 2332 | requires-port@1.0.0: {} 2333 | 2334 | resolve@1.22.11: 2335 | dependencies: 2336 | is-core-module: 2.16.1 2337 | path-parse: 1.0.7 2338 | supports-preserve-symlinks-flag: 1.0.0 2339 | 2340 | router@2.2.0: 2341 | dependencies: 2342 | debug: 4.4.3(supports-color@5.5.0) 2343 | depd: 2.0.0 2344 | is-promise: 4.0.0 2345 | parseurl: 1.3.3 2346 | path-to-regexp: 8.3.0 2347 | transitivePeerDependencies: 2348 | - supports-color 2349 | 2350 | run-async@4.0.6: {} 2351 | 2352 | rxjs@7.8.2: 2353 | dependencies: 2354 | tslib: 2.8.1 2355 | 2356 | safe-array-concat@1.1.3: 2357 | dependencies: 2358 | call-bind: 1.0.8 2359 | call-bound: 1.0.4 2360 | get-intrinsic: 1.3.0 2361 | has-symbols: 1.1.0 2362 | isarray: 2.0.5 2363 | 2364 | safe-buffer@5.2.1: {} 2365 | 2366 | safe-push-apply@1.0.0: 2367 | dependencies: 2368 | es-errors: 1.3.0 2369 | isarray: 2.0.5 2370 | 2371 | safe-regex-test@1.1.0: 2372 | dependencies: 2373 | call-bound: 1.0.4 2374 | es-errors: 1.3.0 2375 | is-regex: 1.2.1 2376 | 2377 | safer-buffer@2.1.2: {} 2378 | 2379 | semver@5.7.2: {} 2380 | 2381 | semver@7.7.3: {} 2382 | 2383 | send@1.2.0: 2384 | dependencies: 2385 | debug: 4.4.3(supports-color@5.5.0) 2386 | encodeurl: 2.0.0 2387 | escape-html: 1.0.3 2388 | etag: 1.8.1 2389 | fresh: 2.0.0 2390 | http-errors: 2.0.1 2391 | mime-types: 3.0.2 2392 | ms: 2.1.3 2393 | on-finished: 2.4.1 2394 | range-parser: 1.2.1 2395 | statuses: 2.0.2 2396 | transitivePeerDependencies: 2397 | - supports-color 2398 | 2399 | serve-static@2.2.0: 2400 | dependencies: 2401 | encodeurl: 2.0.0 2402 | escape-html: 1.0.3 2403 | parseurl: 1.3.3 2404 | send: 1.2.0 2405 | transitivePeerDependencies: 2406 | - supports-color 2407 | 2408 | set-function-length@1.2.2: 2409 | dependencies: 2410 | define-data-property: 1.1.4 2411 | es-errors: 1.3.0 2412 | function-bind: 1.1.2 2413 | get-intrinsic: 1.3.0 2414 | gopd: 1.2.0 2415 | has-property-descriptors: 1.0.2 2416 | 2417 | set-function-name@2.0.2: 2418 | dependencies: 2419 | define-data-property: 1.1.4 2420 | es-errors: 1.3.0 2421 | functions-have-names: 1.2.3 2422 | has-property-descriptors: 1.0.2 2423 | 2424 | set-proto@1.0.0: 2425 | dependencies: 2426 | dunder-proto: 1.0.1 2427 | es-errors: 1.3.0 2428 | es-object-atoms: 1.1.1 2429 | 2430 | setprototypeof@1.2.0: {} 2431 | 2432 | shebang-command@1.2.0: 2433 | dependencies: 2434 | shebang-regex: 1.0.0 2435 | 2436 | shebang-regex@1.0.0: {} 2437 | 2438 | shell-quote@1.8.3: {} 2439 | 2440 | side-channel-list@1.0.0: 2441 | dependencies: 2442 | es-errors: 1.3.0 2443 | object-inspect: 1.13.4 2444 | 2445 | side-channel-map@1.0.1: 2446 | dependencies: 2447 | call-bound: 1.0.4 2448 | es-errors: 1.3.0 2449 | get-intrinsic: 1.3.0 2450 | object-inspect: 1.13.4 2451 | 2452 | side-channel-weakmap@1.0.2: 2453 | dependencies: 2454 | call-bound: 1.0.4 2455 | es-errors: 1.3.0 2456 | get-intrinsic: 1.3.0 2457 | object-inspect: 1.13.4 2458 | side-channel-map: 1.0.1 2459 | 2460 | side-channel@1.1.0: 2461 | dependencies: 2462 | es-errors: 1.3.0 2463 | object-inspect: 1.13.4 2464 | side-channel-list: 1.0.0 2465 | side-channel-map: 1.0.1 2466 | side-channel-weakmap: 1.0.2 2467 | 2468 | signal-exit@4.1.0: {} 2469 | 2470 | simple-update-notifier@2.0.0: 2471 | dependencies: 2472 | semver: 7.7.3 2473 | 2474 | spdx-correct@3.2.0: 2475 | dependencies: 2476 | spdx-expression-parse: 3.0.1 2477 | spdx-license-ids: 3.0.22 2478 | 2479 | spdx-exceptions@2.5.0: {} 2480 | 2481 | spdx-expression-parse@3.0.1: 2482 | dependencies: 2483 | spdx-exceptions: 2.5.0 2484 | spdx-license-ids: 3.0.22 2485 | 2486 | spdx-license-ids@3.0.22: {} 2487 | 2488 | statuses@2.0.2: {} 2489 | 2490 | stop-iteration-iterator@1.1.0: 2491 | dependencies: 2492 | es-errors: 1.3.0 2493 | internal-slot: 1.1.0 2494 | 2495 | streamsearch@1.1.0: {} 2496 | 2497 | string-width@4.2.3: 2498 | dependencies: 2499 | emoji-regex: 8.0.0 2500 | is-fullwidth-code-point: 3.0.0 2501 | strip-ansi: 6.0.1 2502 | 2503 | string.prototype.padend@3.1.6: 2504 | dependencies: 2505 | call-bind: 1.0.8 2506 | define-properties: 1.2.1 2507 | es-abstract: 1.24.0 2508 | es-object-atoms: 1.1.1 2509 | 2510 | string.prototype.trim@1.2.10: 2511 | dependencies: 2512 | call-bind: 1.0.8 2513 | call-bound: 1.0.4 2514 | define-data-property: 1.1.4 2515 | define-properties: 1.2.1 2516 | es-abstract: 1.24.0 2517 | es-object-atoms: 1.1.1 2518 | has-property-descriptors: 1.0.2 2519 | 2520 | string.prototype.trimend@1.0.9: 2521 | dependencies: 2522 | call-bind: 1.0.8 2523 | call-bound: 1.0.4 2524 | define-properties: 1.2.1 2525 | es-object-atoms: 1.1.1 2526 | 2527 | string.prototype.trimstart@1.0.8: 2528 | dependencies: 2529 | call-bind: 1.0.8 2530 | define-properties: 1.2.1 2531 | es-object-atoms: 1.1.1 2532 | 2533 | string_decoder@1.3.0: 2534 | dependencies: 2535 | safe-buffer: 5.2.1 2536 | 2537 | strip-ansi@6.0.1: 2538 | dependencies: 2539 | ansi-regex: 5.0.1 2540 | 2541 | strip-bom@3.0.0: {} 2542 | 2543 | supports-color@5.5.0: 2544 | dependencies: 2545 | has-flag: 3.0.0 2546 | 2547 | supports-preserve-symlinks-flag@1.0.0: {} 2548 | 2549 | to-regex-range@5.0.1: 2550 | dependencies: 2551 | is-number: 7.0.0 2552 | 2553 | toidentifier@1.0.1: {} 2554 | 2555 | touch@3.1.1: {} 2556 | 2557 | tr46@0.0.3: {} 2558 | 2559 | tslib@2.8.1: {} 2560 | 2561 | type-is@1.6.18: 2562 | dependencies: 2563 | media-typer: 0.3.0 2564 | mime-types: 2.1.35 2565 | 2566 | type-is@2.0.1: 2567 | dependencies: 2568 | content-type: 1.0.5 2569 | media-typer: 1.1.0 2570 | mime-types: 3.0.2 2571 | 2572 | typed-array-buffer@1.0.3: 2573 | dependencies: 2574 | call-bound: 1.0.4 2575 | es-errors: 1.3.0 2576 | is-typed-array: 1.1.15 2577 | 2578 | typed-array-byte-length@1.0.3: 2579 | dependencies: 2580 | call-bind: 1.0.8 2581 | for-each: 0.3.5 2582 | gopd: 1.2.0 2583 | has-proto: 1.2.0 2584 | is-typed-array: 1.1.15 2585 | 2586 | typed-array-byte-offset@1.0.4: 2587 | dependencies: 2588 | available-typed-arrays: 1.0.7 2589 | call-bind: 1.0.8 2590 | for-each: 0.3.5 2591 | gopd: 1.2.0 2592 | has-proto: 1.2.0 2593 | is-typed-array: 1.1.15 2594 | reflect.getprototypeof: 1.0.10 2595 | 2596 | typed-array-length@1.0.7: 2597 | dependencies: 2598 | call-bind: 1.0.8 2599 | for-each: 0.3.5 2600 | gopd: 1.2.0 2601 | is-typed-array: 1.1.15 2602 | possible-typed-array-names: 1.1.0 2603 | reflect.getprototypeof: 1.0.10 2604 | 2605 | typedarray@0.0.6: {} 2606 | 2607 | unbox-primitive@1.1.0: 2608 | dependencies: 2609 | call-bound: 1.0.4 2610 | has-bigints: 1.1.0 2611 | has-symbols: 1.1.0 2612 | which-boxed-primitive: 1.1.1 2613 | 2614 | undefsafe@2.0.5: {} 2615 | 2616 | undici-types@5.26.5: {} 2617 | 2618 | undici-types@7.16.0: {} 2619 | 2620 | unpipe@1.0.0: {} 2621 | 2622 | util-deprecate@1.0.2: {} 2623 | 2624 | validate-npm-package-license@3.0.4: 2625 | dependencies: 2626 | spdx-correct: 3.2.0 2627 | spdx-expression-parse: 3.0.1 2628 | 2629 | vary@1.1.2: {} 2630 | 2631 | webidl-conversions@3.0.1: {} 2632 | 2633 | whatwg-url@5.0.0: 2634 | dependencies: 2635 | tr46: 0.0.3 2636 | webidl-conversions: 3.0.1 2637 | 2638 | which-boxed-primitive@1.1.1: 2639 | dependencies: 2640 | is-bigint: 1.1.0 2641 | is-boolean-object: 1.2.2 2642 | is-number-object: 1.1.1 2643 | is-string: 1.1.1 2644 | is-symbol: 1.1.1 2645 | 2646 | which-builtin-type@1.2.1: 2647 | dependencies: 2648 | call-bound: 1.0.4 2649 | function.prototype.name: 1.1.8 2650 | has-tostringtag: 1.0.2 2651 | is-async-function: 2.1.1 2652 | is-date-object: 1.1.0 2653 | is-finalizationregistry: 1.1.1 2654 | is-generator-function: 1.1.2 2655 | is-regex: 1.2.1 2656 | is-weakref: 1.1.1 2657 | isarray: 2.0.5 2658 | which-boxed-primitive: 1.1.1 2659 | which-collection: 1.0.2 2660 | which-typed-array: 1.1.19 2661 | 2662 | which-collection@1.0.2: 2663 | dependencies: 2664 | is-map: 2.0.3 2665 | is-set: 2.0.3 2666 | is-weakmap: 2.0.2 2667 | is-weakset: 2.0.4 2668 | 2669 | which-typed-array@1.1.19: 2670 | dependencies: 2671 | available-typed-arrays: 1.0.7 2672 | call-bind: 1.0.8 2673 | call-bound: 1.0.4 2674 | for-each: 0.3.5 2675 | get-proto: 1.0.1 2676 | gopd: 1.2.0 2677 | has-tostringtag: 1.0.2 2678 | 2679 | which@1.3.1: 2680 | dependencies: 2681 | isexe: 2.0.0 2682 | 2683 | wrap-ansi@6.2.0: 2684 | dependencies: 2685 | ansi-styles: 4.3.0 2686 | string-width: 4.2.3 2687 | strip-ansi: 6.0.1 2688 | 2689 | wrap-ansi@7.0.0: 2690 | dependencies: 2691 | ansi-styles: 4.3.0 2692 | string-width: 4.2.3 2693 | strip-ansi: 6.0.1 2694 | 2695 | wrappy@1.0.2: {} 2696 | 2697 | ws@8.18.3: {} 2698 | 2699 | xtend@4.0.2: {} 2700 | 2701 | y18n@5.0.8: {} 2702 | 2703 | yargs-parser@21.1.1: {} 2704 | 2705 | yargs@17.7.2: 2706 | dependencies: 2707 | cliui: 8.0.1 2708 | escalade: 3.2.0 2709 | get-caller-file: 2.0.5 2710 | require-directory: 2.1.1 2711 | string-width: 4.2.3 2712 | y18n: 5.0.8 2713 | yargs-parser: 21.1.1 2714 | 2715 | yoctocolors-cjs@2.1.3: {} 2716 | --------------------------------------------------------------------------------