diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/pull_request_template.md similarity index 73% rename from .github/PULL_REQUEST_TEMPLATE/pull_request_template.md rename to .github/pull_request_template.md index 0c5e03d5..aa99ffae 100644 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,12 +6,13 @@ New PR of [Template Name] Before submitting this PR, please make sure that: -- [ ] I have read the suggestions in the README.md file https://github.com/Dokploy/templates?tab=readme-ov-file#general-suggestions-when-creating-a-template +- [ ] I have read the suggestions in the README.md file https://github.com/Dokploy/templates?tab=readme-ov-file#general-requirements-when-creating-a-template - [ ] I have tested the template in my instance, so the maintainers don't spend time trying to figure out what's wrong. - [ ] I have added tests that demonstrate that my correction works or that my new feature works. ## Issues related (if applicable) -Close automatically the related issues using the keywords: `closes #ISSUE_NUMBER`, `fixes #ISSUE_NUMBER`, `resolves #ISSUE_NUMBER` +Close automatically the related issues using the keywords: `closes #ISSUE_NUMBER` -Example: `closes #123` \ No newline at end of file + +## Screenshots or Videos diff --git a/.github/workflows/deploy-preview.yml b/.github/workflows/deploy-preview.yml index 2f067433..a342ac7a 100644 --- a/.github/workflows/deploy-preview.yml +++ b/.github/workflows/deploy-preview.yml @@ -5,7 +5,9 @@ on: workflows: [Build Preview Deployment] types: - completed - + pull_request: + branches: + - canary permissions: actions: read deployments: write diff --git a/.github/workflows/cloudflare-pages-production.yml b/.github/workflows/deploy-production.yml similarity index 100% rename from .github/workflows/cloudflare-pages-production.yml rename to .github/workflows/deploy-production.yml diff --git a/.github/workflows/validate-docker-compose.yml b/.github/workflows/validate-docker-compose.yml new file mode 100644 index 00000000..ddd16aab --- /dev/null +++ b/.github/workflows/validate-docker-compose.yml @@ -0,0 +1,317 @@ +name: Validate Docker Compose Files + +on: + pull_request: + branches: + - canary + paths: + - 'blueprints/**/docker-compose.yml' + - 'blueprints/**/template.toml' + workflow_dispatch: + +jobs: + validate-docker-compose: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Necesitamos el historial completo para comparar con base + + - name: Set up Docker Compose + run: | + echo "🐳 Setting up Docker Compose..." + # Docker Compose V2 viene preinstalado en ubuntu-latest + docker compose version + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20.16.0 + + - name: Set up pnpm + uses: pnpm/action-setup@v4 + with: + version: 8 + + - name: Install dependencies + run: | + echo "πŸ“¦ Installing Node.js dependencies..." + cd build-scripts && pnpm install + + - name: Get changed files + id: changed-files + run: | + echo "πŸ” Detecting changed files..." + + # Obtener la rama base + BASE_SHA=$(git merge-base HEAD origin/${{ github.base_ref }}) + + # Encontrar todos los archivos docker-compose.yml y template.toml modificados/agregados + CHANGED_COMPOSE=$(git diff --name-only --diff-filter=ACMRT $BASE_SHA HEAD | grep -E 'blueprints/.*/docker-compose\.yml$' || true) + CHANGED_TOML=$(git diff --name-only --diff-filter=ACMRT $BASE_SHA HEAD | grep -E 'blueprints/.*/template\.toml$' || true) + + # Crear lista de directorios ΓΊnicos que tienen cambios + CHANGED_DIRS=$(echo -e "$CHANGED_COMPOSE\n$CHANGED_TOML" | sed 's|blueprints/\([^/]*\)/.*|\1|' | sort -u) + + echo "Changed compose files:" + echo "$CHANGED_COMPOSE" | while read file; do [ -n "$file" ] && echo " - $file"; done + + echo "Changed TOML files:" + echo "$CHANGED_TOML" | while read file; do [ -n "$file" ] && echo " - $file"; done + + echo "Changed directories:" + echo "$CHANGED_DIRS" | while read dir; do [ -n "$dir" ] && echo " - $dir"; done + + # Guardar para usar en siguientes pasos + echo "compose_files<> $GITHUB_OUTPUT + echo "$CHANGED_COMPOSE" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + echo "toml_files<> $GITHUB_OUTPUT + echo "$CHANGED_TOML" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + echo "directories<> $GITHUB_OUTPUT + echo "$CHANGED_DIRS" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Validate Docker Compose files syntax + id: validate-compose-syntax + run: | + echo "πŸ” Validating Docker Compose files syntax..." + + ERROR=0 + COMPOSE_FILES="${{ steps.changed-files.outputs.compose_files }}" + + if [ -z "$COMPOSE_FILES" ]; then + echo "ℹ️ No docker-compose.yml files changed, skipping validation" + exit 0 + fi + + echo "$COMPOSE_FILES" | while read -r compose_file; do + if [ -z "$compose_file" ]; then + continue + fi + + TEMPLATE_DIR=$(dirname "$compose_file") + TEMPLATE_NAME=$(basename "$TEMPLATE_DIR") + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "πŸ“¦ Validating syntax: $TEMPLATE_NAME" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + # Validar sintaxis de docker-compose.yml usando docker compose + echo "πŸ” Validating docker-compose.yml syntax..." + if ! docker compose -f "$compose_file" config > /dev/null 2>&1; then + echo "❌ ERROR: docker-compose.yml syntax is invalid in $TEMPLATE_NAME" + echo "Running docker compose config to show errors:" + docker compose -f "$compose_file" config 2>&1 || true + ERROR=1 + else + echo "βœ… docker-compose.yml syntax is valid" + fi + + # Obtener lista de servicios del compose + SERVICES=$(docker compose -f "$compose_file" config --services 2>/dev/null || echo "") + echo "πŸ“‹ Services found in docker-compose.yml:" + echo "$SERVICES" | while read service; do + [ -n "$service" ] && echo " - $service" + done + + # Guardar servicios para validaciΓ³n posterior + echo "$SERVICES" > "/tmp/${TEMPLATE_NAME}_services.txt" + done + + if [ $ERROR -eq 1 ]; then + echo "" + echo "❌ Docker Compose syntax validation failed" + exit 1 + else + echo "" + echo "βœ… All Docker Compose files have valid syntax" + fi + + - name: Validate Docker Compose best practices + id: validate-compose-practices + run: | + echo "πŸ” Validating Docker Compose best practices..." + + ERROR=0 + COMPOSE_FILES="${{ steps.changed-files.outputs.compose_files }}" + + if [ -z "$COMPOSE_FILES" ]; then + echo "ℹ️ No docker-compose.yml files changed, skipping validation" + exit 0 + fi + + # Convert to array to avoid subshell issues with pipe + # This ensures ERROR=1 inside the loop propagates to the parent shell + mapfile -t COMPOSE_ARRAY <<< "$COMPOSE_FILES" + + for compose_file in "${COMPOSE_ARRAY[@]}"; do + if [ -z "$compose_file" ]; then + continue + fi + + TEMPLATE_DIR=$(dirname "$compose_file") + TEMPLATE_NAME=$(basename "$TEMPLATE_DIR") + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "πŸ“¦ Validating best practices: $TEMPLATE_NAME" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + # Validar usando el script de TypeScript + if ! (cd build-scripts && pnpm exec tsx validate-docker-compose.ts --file "../$compose_file" --verbose); then + ERROR=1 + fi + done + + if [ $ERROR -eq 1 ]; then + echo "" + echo "❌ Docker Compose best practices validation failed" + exit 1 + else + echo "" + echo "βœ… All Docker Compose files follow best practices" + fi + + - name: Validate template.toml files + id: validate-toml + run: | + echo "πŸ” Validating template.toml files..." + + ERROR=0 + DIRECTORIES="${{ steps.changed-files.outputs.directories }}" + + if [ -z "$DIRECTORIES" ]; then + echo "ℹ️ No template directories changed, skipping TOML validation" + exit 0 + fi + + # Convert to array to avoid subshell issues with pipe + # This ensures ERROR=1 inside the loop propagates to the parent shell + mapfile -t DIRS_ARRAY <<< "$DIRECTORIES" + + for template_dir in "${DIRS_ARRAY[@]}"; do + if [ -z "$template_dir" ]; then + continue + fi + + TEMPLATE_PATH="blueprints/$template_dir" + TOML_FILE="$TEMPLATE_PATH/template.toml" + + if [ ! -f "$TOML_FILE" ]; then + echo "⚠️ WARNING: template.toml not found in $template_dir (might be deleted)" + continue + fi + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "πŸ“ Validating: $template_dir/template.toml" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + # Validar usando el script de TypeScript con tsx + # Ejecutar desde build-scripts para tener acceso a node_modules + if ! (cd build-scripts && pnpm exec tsx validate-template.ts --dir "../$TEMPLATE_PATH" --verbose); then + ERROR=1 + fi + done + + if [ $ERROR -eq 1 ]; then + echo "" + echo "❌ template.toml validation failed" + exit 1 + else + echo "" + echo "βœ… All template.toml files are valid" + fi + + - name: Test Docker Compose (dry-run) + id: test-compose + run: | + echo "πŸ§ͺ Testing Docker Compose files (dry-run)..." + + ERROR=0 + DIRECTORIES="${{ steps.changed-files.outputs.directories }}" + + if [ -z "$DIRECTORIES" ]; then + echo "ℹ️ No template directories changed, skipping dry-run test" + exit 0 + fi + + echo "$DIRECTORIES" | while read -r template_dir; do + if [ -z "$template_dir" ]; then + continue + fi + + COMPOSE_FILE="blueprints/$template_dir/docker-compose.yml" + + if [ ! -f "$COMPOSE_FILE" ]; then + continue + fi + + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "πŸ§ͺ Testing: $template_dir" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + # Cambiar al directorio del template para resolver rutas relativas + cd "blueprints/$template_dir" + + # Validar que docker-compose puede parsear el archivo completamente + echo "πŸ” Running docker compose config (full validation)..." + if docker compose config > /dev/null 2>&1; then + echo "βœ… Docker Compose file is fully valid and can be processed" + + # Mostrar informaciΓ³n ΓΊtil + echo "πŸ“‹ Configuration summary:" + docker compose config --services | while read service; do + [ -n "$service" ] && echo " Service: $service" + done + else + echo "❌ ERROR: Docker Compose file failed full validation" + docker compose config 2>&1 || true + ERROR=1 + fi + + cd - > /dev/null + done + + if [ $ERROR -eq 1 ]; then + echo "" + echo "❌ Docker Compose dry-run test failed" + exit 1 + else + echo "" + echo "βœ… All Docker Compose files passed dry-run test" + fi + + - name: Summary + if: always() + run: | + echo "" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "πŸ“Š Validation Summary" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + + if [ "${{ steps.validate-compose-syntax.outcome }}" == "success" ] && \ + [ "${{ steps.validate-compose-practices.outcome }}" == "success" ] && \ + [ "${{ steps.validate-toml.outcome }}" == "success" ] && \ + [ "${{ steps.test-compose.outcome }}" == "success" ]; then + echo "βœ… All validations passed!" + echo "" + echo "Your Docker Compose and template.toml files are valid and ready to merge." + else + echo "❌ Some validations failed. Please review the errors above." + echo "" + echo "Common issues to check:" + echo " - docker-compose.yml syntax errors" + echo " - template.toml syntax errors" + echo " - serviceName in template.toml must match service names in docker-compose.yml" + echo " - Avoid using container_name, explicit networks, or port mappings" + fi + diff --git a/.github/workflows/validate-meta.yml b/.github/workflows/validate-meta.yml index a394e7ec..8f9acb7a 100644 --- a/.github/workflows/validate-meta.yml +++ b/.github/workflows/validate-meta.yml @@ -2,10 +2,10 @@ name: Validate and Process Meta.json on: push: - branches: [main, master, develop] + branches: [canary] paths: ["meta.json"] pull_request: - branches: [main, master] + branches: [canary] paths: ["meta.json"] workflow_dispatch: diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 48cfaa8c..3e749b35 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -3,10 +3,10 @@ name: Validate Blueprints Structure and Meta on: pull_request: branches: - - main + - canary push: branches: - - main + - canary jobs: validate: diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/README.md b/README.md index 81ac50e3..b774c972 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,7 @@ We have a few helpers that are very common when creating a template, these are: -## General Suggestions when creating a template +## General Requirements when creating a template - Don't use this way in your docker compose file: @@ -225,4 +225,4 @@ services: 6. Now you can click on the Deploy Button and wait for the deployment to finish, and try to access to the service, if everything is correct you should access to the service and see the template working. -use the command `node dedupe-and-sort-meta.js` to deduplicate and sort the meta.json file. \ No newline at end of file +use the command `node dedupe-and-sort-meta.js` to deduplicate and sort the meta.json file. diff --git a/app/package-lock.json b/app/package-lock.json deleted file mode 100644 index 9579d3d9..00000000 --- a/app/package-lock.json +++ /dev/null @@ -1,4248 +0,0 @@ -{ - "name": "my-app", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "my-app", - "version": "0.0.0", - "dependencies": { - "@codemirror/autocomplete": "^6.18.6", - "@codemirror/lang-json": "^6.0.1", - "@codemirror/lang-yaml": "^6.1.1", - "@codemirror/language": "^6.10.1", - "@codemirror/legacy-modes": "6.4.0", - "@codemirror/view": "6.29.0", - "@iarna/toml": "^2.2.5", - "@radix-ui/react-dialog": "^1.1.6", - "@radix-ui/react-dropdown-menu": "^2.1.6", - "@radix-ui/react-label": "^2.1.2", - "@radix-ui/react-popover": "^1.1.6", - "@radix-ui/react-slot": "^1.1.2", - "@radix-ui/react-tabs": "^1.1.3", - "@tailwindcss/vite": "^4.0.12", - "@uiw/codemirror-theme-github": "^4.22.1", - "@uiw/react-codemirror": "^4.22.1", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "cmdk": "1.0.0", - "copy-to-clipboard": "^3.3.3", - "lucide-react": "^0.479.0", - "next-themes": "^0.4.5", - "react": "^19.0.0", - "react-dom": "^19.0.0", - "react-router-dom": "^7.4.1", - "sonner": "^2.0.1", - "tailwind-merge": "^3.0.2", - "tailwindcss": "^4.0.12", - "tailwindcss-animate": "^1.0.7", - "vite-plugin-static-copy": "^2.3.2", - "yaml": "2.7.1", - "zustand": "^5.0.3" - }, - "devDependencies": { - "@types/node": "^20.8.2", - "@types/react": "^19.0.10", - "@types/react-dom": "^19.0.4", - "@vitejs/plugin-react": "^4.3.4", - "globals": "^15.15.0", - "typescript": "~5.7.2", - "vite": "^6.2.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", - "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.0.tgz", - "integrity": "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", - "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", - "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", - "dev": true, - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.27.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", - "dev": true, - "dependencies": { - "@babel/types": "^7.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.27.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", - "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz", - "integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==", - "dev": true, - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@codemirror/autocomplete": { - "version": "6.18.6", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", - "integrity": "sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.17.0", - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@codemirror/commands": { - "version": "6.8.1", - "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.8.1.tgz", - "integrity": "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.4.0", - "@codemirror/view": "^6.27.0", - "@lezer/common": "^1.1.0" - } - }, - "node_modules/@codemirror/lang-json": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.2.tgz", - "integrity": "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@lezer/json": "^1.0.0" - } - }, - "node_modules/@codemirror/lang-yaml": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@codemirror/lang-yaml/-/lang-yaml-6.1.2.tgz", - "integrity": "sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.2.0", - "@lezer/lr": "^1.0.0", - "@lezer/yaml": "^1.0.0" - } - }, - "node_modules/@codemirror/language": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.11.2.tgz", - "integrity": "sha512-p44TsNArL4IVXDTbapUmEkAlvWs2CFQbcfc0ymDsis1kH2wh0gcY96AS29c/vp2d0y2Tquk1EDSaawpzilUiAw==", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.23.0", - "@lezer/common": "^1.1.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0", - "style-mod": "^4.0.0" - } - }, - "node_modules/@codemirror/legacy-modes": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.4.0.tgz", - "integrity": "sha512-5m/K+1A6gYR0e+h/dEde7LoGimMjRtWXZFg4Lo70cc8HzjSdHe3fLwjWMR0VRl5KFT1SxalSap7uMgPKF28wBA==", - "dependencies": { - "@codemirror/language": "^6.0.0" - } - }, - "node_modules/@codemirror/lint": { - "version": "6.8.5", - "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.8.5.tgz", - "integrity": "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA==", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.35.0", - "crelt": "^1.0.5" - } - }, - "node_modules/@codemirror/lint/node_modules/@codemirror/view": { - "version": "6.38.1", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.38.1.tgz", - "integrity": "sha512-RmTOkE7hRU3OVREqFVITWHz6ocgBjv08GoePscAakgVQfciA3SGCEk7mb9IzwW61cKKmlTpHXG6DUE5Ubx+MGQ==", - "dependencies": { - "@codemirror/state": "^6.5.0", - "crelt": "^1.0.6", - "style-mod": "^4.1.0", - "w3c-keyname": "^2.2.4" - } - }, - "node_modules/@codemirror/search": { - "version": "6.5.11", - "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.11.tgz", - "integrity": "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==", - "dependencies": { - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "crelt": "^1.0.5" - } - }, - "node_modules/@codemirror/state": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.5.2.tgz", - "integrity": "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==", - "dependencies": { - "@marijn/find-cluster-break": "^1.0.0" - } - }, - "node_modules/@codemirror/theme-one-dark": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.3.tgz", - "integrity": "sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0", - "@lezer/highlight": "^1.0.0" - } - }, - "node_modules/@codemirror/view": { - "version": "6.29.0", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.29.0.tgz", - "integrity": "sha512-ED4ims4fkf7eOA+HYLVP8VVg3NMllt1FPm9PEJBfYFnidKlRITBaua38u68L1F60eNtw2YNcDN5jsIzhKZwWQA==", - "dependencies": { - "@codemirror/state": "^6.4.0", - "style-mod": "^4.1.0", - "w3c-keyname": "^2.2.4" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.8.tgz", - "integrity": "sha512-urAvrUedIqEiFR3FYSLTWQgLu5tb+m0qZw0NBEasUeo6wuqatkMDaRT+1uABiGXEu5vqgPd7FGE1BhsAIy9QVA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.8.tgz", - "integrity": "sha512-RONsAvGCz5oWyePVnLdZY/HHwA++nxYWIX1atInlaW6SEkwq6XkP3+cb825EUcRs5Vss/lGh/2YxAb5xqc07Uw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.8.tgz", - "integrity": "sha512-OD3p7LYzWpLhZEyATcTSJ67qB5D+20vbtr6vHlHWSQYhKtzUYrETuWThmzFpZtFsBIxRvhO07+UgVA9m0i/O1w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.8.tgz", - "integrity": "sha512-yJAVPklM5+4+9dTeKwHOaA+LQkmrKFX96BM0A/2zQrbS6ENCmxc4OVoBs5dPkCCak2roAD+jKCdnmOqKszPkjA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.8.tgz", - "integrity": "sha512-Jw0mxgIaYX6R8ODrdkLLPwBqHTtYHJSmzzd+QeytSugzQ0Vg4c5rDky5VgkoowbZQahCbsv1rT1KW72MPIkevw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.8.tgz", - "integrity": "sha512-Vh2gLxxHnuoQ+GjPNvDSDRpoBCUzY4Pu0kBqMBDlK4fuWbKgGtmDIeEC081xi26PPjn+1tct+Bh8FjyLlw1Zlg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.8.tgz", - "integrity": "sha512-YPJ7hDQ9DnNe5vxOm6jaie9QsTwcKedPvizTVlqWG9GBSq+BuyWEDazlGaDTC5NGU4QJd666V0yqCBL2oWKPfA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.8.tgz", - "integrity": "sha512-MmaEXxQRdXNFsRN/KcIimLnSJrk2r5H8v+WVafRWz5xdSVmWLoITZQXcgehI2ZE6gioE6HirAEToM/RvFBeuhw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.8.tgz", - "integrity": "sha512-FuzEP9BixzZohl1kLf76KEVOsxtIBFwCaLupVuk4eFVnOZfU+Wsn+x5Ryam7nILV2pkq2TqQM9EZPsOBuMC+kg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.8.tgz", - "integrity": "sha512-WIgg00ARWv/uYLU7lsuDK00d/hHSfES5BzdWAdAig1ioV5kaFNrtK8EqGcUBJhYqotlUByUKz5Qo6u8tt7iD/w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.8.tgz", - "integrity": "sha512-A1D9YzRX1i+1AJZuFFUMP1E9fMaYY+GnSQil9Tlw05utlE86EKTUA7RjwHDkEitmLYiFsRd9HwKBPEftNdBfjg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.8.tgz", - "integrity": "sha512-O7k1J/dwHkY1RMVvglFHl1HzutGEFFZ3kNiDMSOyUrB7WcoHGf96Sh+64nTRT26l3GMbCW01Ekh/ThKM5iI7hQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.8.tgz", - "integrity": "sha512-uv+dqfRazte3BzfMp8PAQXmdGHQt2oC/y2ovwpTteqrMx2lwaksiFZ/bdkXJC19ttTvNXBuWH53zy/aTj1FgGw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.8.tgz", - "integrity": "sha512-GyG0KcMi1GBavP5JgAkkstMGyMholMDybAf8wF5A70CALlDM2p/f7YFE7H92eDeH/VBtFJA5MT4nRPDGg4JuzQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.8.tgz", - "integrity": "sha512-rAqDYFv3yzMrq7GIcen3XP7TUEG/4LK86LUPMIz6RT8A6pRIDn0sDcvjudVZBiiTcZCY9y2SgYX2lgK3AF+1eg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.8.tgz", - "integrity": "sha512-Xutvh6VjlbcHpsIIbwY8GVRbwoviWT19tFhgdA7DlenLGC/mbc3lBoVb7jxj9Z+eyGqvcnSyIltYUrkKzWqSvg==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.8.tgz", - "integrity": "sha512-ASFQhgY4ElXh3nDcOMTkQero4b1lgubskNlhIfJrsH5OKZXDpUAKBlNS0Kx81jwOBp+HCeZqmoJuihTv57/jvQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.8.tgz", - "integrity": "sha512-d1KfruIeohqAi6SA+gENMuObDbEjn22olAR7egqnkCD9DGBG0wsEARotkLgXDu6c4ncgWTZJtN5vcgxzWRMzcw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.8.tgz", - "integrity": "sha512-nVDCkrvx2ua+XQNyfrujIG38+YGyuy2Ru9kKVNyh5jAys6n+l44tTtToqHjino2My8VAY6Lw9H7RI73XFi66Cg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.8.tgz", - "integrity": "sha512-j8HgrDuSJFAujkivSMSfPQSAa5Fxbvk4rgNAS5i3K+r8s1X0p1uOO2Hl2xNsGFppOeHOLAVgYwDVlmxhq5h+SQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.8.tgz", - "integrity": "sha512-1h8MUAwa0VhNCDp6Af0HToI2TJFAn1uqT9Al6DJVzdIBAd21m/G0Yfc77KDM3uF3T/YaOgQq3qTJHPbTOInaIQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.8.tgz", - "integrity": "sha512-r2nVa5SIK9tSWd0kJd9HCffnDHKchTGikb//9c7HX+r+wHYCpQrSgxhlY6KWV1nFo1l4KFbsMlHk+L6fekLsUg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.8.tgz", - "integrity": "sha512-zUlaP2S12YhQ2UzUfcCuMDHQFJyKABkAjvO5YSndMiIkMimPmxA+BYSBikWgsRpvyxuRnow4nS5NPnf9fpv41w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.8.tgz", - "integrity": "sha512-YEGFFWESlPva8hGL+zvj2z/SaK+pH0SwOM0Nc/d+rVnW7GSTFlLBGzZkuSU9kFIGIo8q9X3ucpZhu8PDN5A2sQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.8.tgz", - "integrity": "sha512-hiGgGC6KZ5LZz58OL/+qVVoZiuZlUYlYHNAmczOm7bs2oE1XriPFi5ZHHrS8ACpV5EjySrnoCKmcbQMN+ojnHg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.8.tgz", - "integrity": "sha512-cn3Yr7+OaaZq1c+2pe+8yxC8E144SReCQjN6/2ynubzYjvyqZjTXfQJpAcQpsdJq3My7XADANiYGHoFC69pLQw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", - "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", - "dependencies": { - "@floating-ui/utils": "^0.2.10" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", - "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", - "dependencies": { - "@floating-ui/core": "^1.7.2", - "@floating-ui/utils": "^0.2.10" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", - "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", - "dependencies": { - "@floating-ui/dom": "^1.7.2" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==" - }, - "node_modules/@iarna/toml": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", - "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==" - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", - "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", - "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", - "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@lezer/common": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.3.tgz", - "integrity": "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==" - }, - "node_modules/@lezer/highlight": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.1.tgz", - "integrity": "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==", - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@lezer/json": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.3.tgz", - "integrity": "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.0.0" - } - }, - "node_modules/@lezer/lr": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.2.tgz", - "integrity": "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==", - "dependencies": { - "@lezer/common": "^1.0.0" - } - }, - "node_modules/@lezer/yaml": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@lezer/yaml/-/yaml-1.0.3.tgz", - "integrity": "sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==", - "dependencies": { - "@lezer/common": "^1.2.0", - "@lezer/highlight": "^1.0.0", - "@lezer/lr": "^1.4.0" - } - }, - "node_modules/@marijn/find-cluster-break": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", - "integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@radix-ui/primitive": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.2.tgz", - "integrity": "sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA==" - }, - "node_modules/@radix-ui/react-arrow": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", - "dependencies": { - "@radix-ui/react-primitive": "2.1.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-collection": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", - "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.10.tgz", - "integrity": "sha512-IM1zzRV4W3HtVgftdQiiOmA0AdJlCtMLe00FXaHwgt3rAnNsIyDqshvkIW3hj/iu5hu8ERP7KIYki6NkqDxAwQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-escape-keydown": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-dropdown-menu": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.15.tgz", - "integrity": "sha512-mIBnOjgwo9AH3FyKaSWoSu/dYj6VdhJ7frEPiGTeXCdUFHjl9h3mFh2wwhEtINOmYXWhdpf1rY2minFsmaNgVQ==", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-menu": "2.1.15", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz", - "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-label": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.7.tgz", - "integrity": "sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==", - "dependencies": { - "@radix-ui/react-primitive": "2.1.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-menu": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.1.15.tgz", - "integrity": "sha512-tVlmA3Vb9n8SZSd+YSbuFR66l87Wiy4du+YE+0hzKQEANA+7cWKH1WgqcEX4pXqxUFQKrWQGHdvEfw00TjFiew==", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popover": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.14.tgz", - "integrity": "sha512-ODz16+1iIbGUfFEfKx2HTPKizg2MN39uIOV8MXeHnmdd3i/N9Wt7vU46wbHsqA0xoaQyXVcs0KIlBdOA2Y95bw==", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", - "@radix-ui/react-focus-scope": "1.1.7", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", - "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-slot": "1.2.3", - "@radix-ui/react-use-controllable-state": "1.2.2", - "aria-hidden": "^1.2.4", - "react-remove-scroll": "^2.6.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-popper": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.7.tgz", - "integrity": "sha512-IUFAccz1JyKcf/RjB552PlWwxjeCJB8/4KxT7EhBHOJM+mN7LdW+B3kacJXILm32xawcMMjb2i0cIZpo+f9kiQ==", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-layout-effect": "1.1.1", - "@radix-ui/react-use-rect": "1.1.1", - "@radix-ui/react-use-size": "1.1.1", - "@radix-ui/rect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", - "dependencies": { - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.4.tgz", - "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", - "dependencies": { - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-roving-focus": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.10.tgz", - "integrity": "sha512-dT9aOXUen9JSsxnMPv/0VqySQf5eDQ6LCk5Sw28kamz8wSOW2bJdlX2Bg5VUIIcV+6XlHpWTIuTPCf/UNIyq8Q==", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-collection": "1.1.7", - "@radix-ui/react-compose-refs": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-callback-ref": "1.1.1", - "@radix-ui/react-use-controllable-state": "1.2.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.12.tgz", - "integrity": "sha512-GTVAlRVrQrSw3cEARM0nAx73ixrWDPNZAruETn3oHCNP6SbZ/hNxdxp+u7VkIEv3/sFoLq1PfcHrl7Pnp0CDpw==", - "dependencies": { - "@radix-ui/primitive": "1.1.2", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-presence": "1.1.4", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.10", - "@radix-ui/react-use-controllable-state": "1.2.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", - "dependencies": { - "@radix-ui/react-use-effect-event": "0.0.2", - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-effect-event": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", - "dependencies": { - "@radix-ui/rect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/rect": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==" - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", - "dev": true - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz", - "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz", - "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz", - "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz", - "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz", - "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz", - "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz", - "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz", - "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz", - "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz", - "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz", - "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz", - "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz", - "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz", - "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz", - "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz", - "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz", - "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz", - "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz", - "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz", - "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@tailwindcss/node": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.11.tgz", - "integrity": "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q==", - "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.30.1", - "magic-string": "^0.30.17", - "source-map-js": "^1.2.1", - "tailwindcss": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.11.tgz", - "integrity": "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg==", - "hasInstallScript": true, - "dependencies": { - "detect-libc": "^2.0.4", - "tar": "^7.4.3" - }, - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-arm64": "4.1.11", - "@tailwindcss/oxide-darwin-x64": "4.1.11", - "@tailwindcss/oxide-freebsd-x64": "4.1.11", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", - "@tailwindcss/oxide-linux-x64-musl": "4.1.11", - "@tailwindcss/oxide-wasm32-wasi": "4.1.11", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.11.tgz", - "integrity": "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.11.tgz", - "integrity": "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.11.tgz", - "integrity": "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.11.tgz", - "integrity": "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.11.tgz", - "integrity": "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.11.tgz", - "integrity": "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.11.tgz", - "integrity": "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.11.tgz", - "integrity": "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.11.tgz", - "integrity": "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.11.tgz", - "integrity": "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.11", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.11.tgz", - "integrity": "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.11.tgz", - "integrity": "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/vite": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.11.tgz", - "integrity": "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw==", - "dependencies": { - "@tailwindcss/node": "4.1.11", - "@tailwindcss/oxide": "4.1.11", - "tailwindcss": "4.1.11" - }, - "peerDependencies": { - "vite": "^5.2.0 || ^6 || ^7" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", - "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true - }, - "node_modules/@types/node": { - "version": "20.19.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.9.tgz", - "integrity": "sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==", - "dev": true, - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/react": { - "version": "19.1.8", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.8.tgz", - "integrity": "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==", - "dev": true, - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.1.6", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz", - "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==", - "dev": true, - "peerDependencies": { - "@types/react": "^19.0.0" - } - }, - "node_modules/@uiw/codemirror-extensions-basic-setup": { - "version": "4.24.1", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.24.1.tgz", - "integrity": "sha512-o1m1a8eUS3fWERMbDFvN8t8sZUFPgDKNemmlQ5Ot2vKm+Ax84lKP1dhEFgkiOaZ1bDHk4T5h6SjHuTghrJHKww==", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/commands": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/search": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - }, - "peerDependencies": { - "@codemirror/autocomplete": ">=6.0.0", - "@codemirror/commands": ">=6.0.0", - "@codemirror/language": ">=6.0.0", - "@codemirror/lint": ">=6.0.0", - "@codemirror/search": ">=6.0.0", - "@codemirror/state": ">=6.0.0", - "@codemirror/view": ">=6.0.0" - } - }, - "node_modules/@uiw/codemirror-theme-github": { - "version": "4.24.1", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-theme-github/-/codemirror-theme-github-4.24.1.tgz", - "integrity": "sha512-dl4qFEXINE4TFus7ALMfjFUCl7sWLkqTdaSaln0Vv3s+HVzSMAh5lkEdnH3yPcOOCl5ehYG4zIx8bqEnA2/FYQ==", - "dependencies": { - "@uiw/codemirror-themes": "4.24.1" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - } - }, - "node_modules/@uiw/codemirror-themes": { - "version": "4.24.1", - "resolved": "https://registry.npmjs.org/@uiw/codemirror-themes/-/codemirror-themes-4.24.1.tgz", - "integrity": "sha512-hduBbFNiWNW6nYa2/giKQ9YpzhWNw87BGpCjC+cXYMZ7bCD6q5DC6Hw+7z7ZwSzEaOQvV91lmirOjJ8hn9+pkg==", - "dependencies": { - "@codemirror/language": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - }, - "peerDependencies": { - "@codemirror/language": ">=6.0.0", - "@codemirror/state": ">=6.0.0", - "@codemirror/view": ">=6.0.0" - } - }, - "node_modules/@uiw/react-codemirror": { - "version": "4.24.1", - "resolved": "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.24.1.tgz", - "integrity": "sha512-BivF4NLqbuBQK5gPVhSkOARi9nPXw8X5r25EnInPeY+I9l1dfEX8O9V6+0xHTlGHyUo0cNfGEF9t1KHEicUfJw==", - "dependencies": { - "@babel/runtime": "^7.18.6", - "@codemirror/commands": "^6.1.0", - "@codemirror/state": "^6.1.1", - "@codemirror/theme-one-dark": "^6.0.0", - "@uiw/codemirror-extensions-basic-setup": "4.24.1", - "codemirror": "^6.0.0" - }, - "funding": { - "url": "https://jaywcjlove.github.io/#/sponsor" - }, - "peerDependencies": { - "@babel/runtime": ">=7.11.0", - "@codemirror/state": ">=6.0.0", - "@codemirror/theme-one-dark": ">=6.0.0", - "@codemirror/view": ">=6.0.0", - "codemirror": ">=6.0.0", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@vitejs/plugin-react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", - "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.28.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/aria-hidden": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", - "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001727", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", - "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "engines": { - "node": ">=18" - } - }, - "node_modules/class-variance-authority": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", - "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", - "dependencies": { - "clsx": "^2.1.1" - }, - "funding": { - "url": "https://polar.sh/cva" - } - }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cmdk": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.0.0.tgz", - "integrity": "sha512-gDzVf0a09TvoJ5jnuPvygTB77+XdOSwEmJ88L6XPFPlv7T3RxbP9jgenfylrAMD0+Le1aO0nVjQUzl2g+vjz5Q==", - "dependencies": { - "@radix-ui/react-dialog": "1.0.5", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/cmdk/node_modules/@radix-ui/primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.1.tgz", - "integrity": "sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-compose-refs": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.1.tgz", - "integrity": "sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-context": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.1.tgz", - "integrity": "sha512-ebbrdFoYTcuZ0v4wG5tedGnp9tzcV8awzsxYph7gXUyvnNLuTIcCk1q17JEbnVhXAKG9oX3KtchwiMIAYp9NLg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-dialog": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.5.tgz", - "integrity": "sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-focus-guards": "1.0.1", - "@radix-ui/react-focus-scope": "1.0.4", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-slot": "1.0.2", - "@radix-ui/react-use-controllable-state": "1.0.1", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.5" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", - "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-escape-keydown": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-focus-guards": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", - "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-focus-scope": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.4.tgz", - "integrity": "sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-id": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", - "integrity": "sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-portal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.4.tgz", - "integrity": "sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-presence": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz", - "integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-primitive": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.3.tgz", - "integrity": "sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", - "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", - "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", - "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", - "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", - "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/cmdk/node_modules/react-remove-scroll": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", - "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.3", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/codemirror": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz", - "integrity": "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==", - "dependencies": { - "@codemirror/autocomplete": "^6.0.0", - "@codemirror/commands": "^6.0.0", - "@codemirror/language": "^6.0.0", - "@codemirror/lint": "^6.0.0", - "@codemirror/search": "^6.0.0", - "@codemirror/state": "^6.0.0", - "@codemirror/view": "^6.0.0" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", - "engines": { - "node": ">=18" - } - }, - "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dependencies": { - "toggle-selection": "^1.0.6" - } - }, - "node_modules/crelt": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", - "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true - }, - "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.188", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.188.tgz", - "integrity": "sha512-pfEx5CBFAocOKNrc+i5fSvhDaI1Vr9R9aT5uX1IzM3hhdL6k649wfuUcdUd9EZnmbE1xdfA51CwqQ61CO3Xl3g==", - "dev": true - }, - "node_modules/enhanced-resolve": { - "version": "5.18.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", - "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/esbuild": { - "version": "0.25.8", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.8.tgz", - "integrity": "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.8", - "@esbuild/android-arm": "0.25.8", - "@esbuild/android-arm64": "0.25.8", - "@esbuild/android-x64": "0.25.8", - "@esbuild/darwin-arm64": "0.25.8", - "@esbuild/darwin-x64": "0.25.8", - "@esbuild/freebsd-arm64": "0.25.8", - "@esbuild/freebsd-x64": "0.25.8", - "@esbuild/linux-arm": "0.25.8", - "@esbuild/linux-arm64": "0.25.8", - "@esbuild/linux-ia32": "0.25.8", - "@esbuild/linux-loong64": "0.25.8", - "@esbuild/linux-mips64el": "0.25.8", - "@esbuild/linux-ppc64": "0.25.8", - "@esbuild/linux-riscv64": "0.25.8", - "@esbuild/linux-s390x": "0.25.8", - "@esbuild/linux-x64": "0.25.8", - "@esbuild/netbsd-arm64": "0.25.8", - "@esbuild/netbsd-x64": "0.25.8", - "@esbuild/openbsd-arm64": "0.25.8", - "@esbuild/openbsd-x64": "0.25.8", - "@esbuild/openharmony-arm64": "0.25.8", - "@esbuild/sunos-x64": "0.25.8", - "@esbuild/win32-arm64": "0.25.8", - "@esbuild/win32-ia32": "0.25.8", - "@esbuild/win32-x64": "0.25.8" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", - "dev": true, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/fs-extra": { - "version": "11.3.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.0.tgz", - "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "15.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", - "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/lightningcss": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", - "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-darwin-arm64": "1.30.1", - "lightningcss-darwin-x64": "1.30.1", - "lightningcss-freebsd-x64": "1.30.1", - "lightningcss-linux-arm-gnueabihf": "1.30.1", - "lightningcss-linux-arm64-gnu": "1.30.1", - "lightningcss-linux-arm64-musl": "1.30.1", - "lightningcss-linux-x64-gnu": "1.30.1", - "lightningcss-linux-x64-musl": "1.30.1", - "lightningcss-win32-arm64-msvc": "1.30.1", - "lightningcss-win32-x64-msvc": "1.30.1" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", - "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", - "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", - "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", - "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", - "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", - "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", - "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", - "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", - "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.30.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", - "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lucide-react": { - "version": "0.479.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.479.0.tgz", - "integrity": "sha512-aBhNnveRhorBOK7uA4gDjgaf+YlHMdMhQ/3cupk6exM10hWlEU+2QtWYOfhXhjAsmdb6LeKR+NZnow4UxRRiTQ==", - "peerDependencies": { - "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/next-themes": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz", - "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==", - "peerDependencies": { - "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" - } - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-map": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", - "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" - }, - "node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/react": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", - "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", - "dependencies": { - "scheduler": "^0.26.0" - }, - "peerDependencies": { - "react": "^19.1.0" - } - }, - "node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-remove-scroll": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", - "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.7", - "react-style-singleton": "^2.2.3", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.3", - "use-sidecar": "^1.1.3" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-remove-scroll-bar": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", - "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", - "dependencies": { - "react-style-singleton": "^2.2.2", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-router": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.7.0.tgz", - "integrity": "sha512-3FUYSwlvB/5wRJVTL/aavqHmfUKe0+Xm9MllkYgGo9eDwNdkvwlJGjpPxono1kCycLt6AnDTgjmXvK3/B4QGuw==", - "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/react-router-dom": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.7.0.tgz", - "integrity": "sha512-wwGS19VkNBkneVh9/YD0pK3IsjWxQUVMDD6drlG7eJpo1rXBtctBqDyBm/k+oKHRAm1x9XWT3JFC82QI9YOXXA==", - "dependencies": { - "react-router": "7.7.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/react-style-singleton": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", - "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", - "dependencies": { - "get-nonce": "^1.0.0", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rollup": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", - "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.45.1", - "@rollup/rollup-android-arm64": "4.45.1", - "@rollup/rollup-darwin-arm64": "4.45.1", - "@rollup/rollup-darwin-x64": "4.45.1", - "@rollup/rollup-freebsd-arm64": "4.45.1", - "@rollup/rollup-freebsd-x64": "4.45.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", - "@rollup/rollup-linux-arm-musleabihf": "4.45.1", - "@rollup/rollup-linux-arm64-gnu": "4.45.1", - "@rollup/rollup-linux-arm64-musl": "4.45.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", - "@rollup/rollup-linux-riscv64-gnu": "4.45.1", - "@rollup/rollup-linux-riscv64-musl": "4.45.1", - "@rollup/rollup-linux-s390x-gnu": "4.45.1", - "@rollup/rollup-linux-x64-gnu": "4.45.1", - "@rollup/rollup-linux-x64-musl": "4.45.1", - "@rollup/rollup-win32-arm64-msvc": "4.45.1", - "@rollup/rollup-win32-ia32-msvc": "4.45.1", - "@rollup/rollup-win32-x64-msvc": "4.45.1", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/scheduler": { - "version": "0.26.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", - "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" - }, - "node_modules/sonner": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.6.tgz", - "integrity": "sha512-yHFhk8T/DK3YxjFQXIrcHT1rGEeTLliVzWbO0xN8GberVun2RiBnxAjXAYpZrqwEVHBG9asI/Li8TAAhN9m59Q==", - "peerDependencies": { - "react": "^18.0.0 || ^19.0.0 || ^19.0.0-rc", - "react-dom": "^18.0.0 || ^19.0.0 || ^19.0.0-rc" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/style-mod": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz", - "integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==" - }, - "node_modules/tailwind-merge": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.3.1.tgz", - "integrity": "sha512-gBXpgUm/3rp1lMZZrM/w7D8GKqshif0zAymAhbCyIt8KMe+0v9DQ7cdYLR4FHH/cKpdTXb+A/tKKU3eolfsI+g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/dcastil" - } - }, - "node_modules/tailwindcss": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.11.tgz", - "integrity": "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA==" - }, - "node_modules/tailwindcss-animate": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", - "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" - } - }, - "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/tar/node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", - "dev": true, - "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" - }, - "node_modules/typescript": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", - "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/use-callback-ref": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", - "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-sidecar": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", - "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", - "dependencies": { - "detect-node-es": "^1.1.0", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/vite": { - "version": "6.3.6", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz", - "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite-plugin-static-copy": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.3.2.tgz", - "integrity": "sha512-iwrrf+JupY4b9stBttRWzGHzZbeMjAHBhkrn67MNACXJVjEMRpCI10Q3AkxdBkl45IHaTfw/CNVevzQhP7yTwg==", - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.3", - "fast-glob": "^3.2.11", - "fs-extra": "^11.1.0", - "p-map": "^7.0.3", - "picocolors": "^1.0.0" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/w3c-keyname": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", - "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==" - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yaml": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.1.tgz", - "integrity": "sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/zustand": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.6.tgz", - "integrity": "sha512-ihAqNeUVhe0MAD+X8M5UzqyZ9k3FFZLBTtqo6JLPwV53cbRB/mJwBI0PxcIgqhBBHlEs8G45OTDTMq3gNcLq3A==", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - } - } -} diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index 9fec5d4b..2d26f18e 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -9,17 +9,17 @@ importers: .: dependencies: '@codemirror/autocomplete': - specifier: ^6.18.6 - version: 6.18.6 + specifier: ^6.19.1 + version: 6.19.1 '@codemirror/lang-json': - specifier: ^6.0.1 - version: 6.0.1 + specifier: ^6.0.2 + version: 6.0.2 '@codemirror/lang-yaml': - specifier: ^6.1.1 + specifier: ^6.1.2 version: 6.1.2 '@codemirror/language': - specifier: ^6.10.1 - version: 6.10.8 + specifier: ^6.11.3 + version: 6.11.3 '@codemirror/legacy-modes': specifier: 6.4.0 version: 6.4.0 @@ -30,32 +30,32 @@ importers: specifier: ^2.2.5 version: 2.2.5 '@radix-ui/react-dialog': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^1.1.15 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-dropdown-menu': - specifier: ^2.1.6 - version: 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^2.1.16 + version: 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-label': - specifier: ^2.1.2 - version: 2.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^2.1.7 + version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-popover': - specifier: ^1.1.6 - version: 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^1.1.15 + version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-slot': - specifier: ^1.1.2 - version: 1.1.2(@types/react@19.0.10)(react@19.0.0) + specifier: ^1.2.3 + version: 1.2.4(@types/react@19.2.4)(react@19.2.0) '@radix-ui/react-tabs': - specifier: ^1.1.3 - version: 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^1.1.13 + version: 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tailwindcss/vite': - specifier: ^4.0.12 - version: 4.0.12(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1)) + specifier: ^4.1.16 + version: 4.1.17(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1)) '@uiw/codemirror-theme-github': - specifier: ^4.22.1 - version: 4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0) + specifier: ^4.25.2 + version: 4.25.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0) '@uiw/react-codemirror': - specifier: ^4.22.1 - version: 4.23.10(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^4.25.2 + version: 4.25.3(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.19.1)(@codemirror/language@6.11.3)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -64,123 +64,131 @@ importers: version: 2.1.1 cmdk: specifier: 1.0.0 - version: 1.0.0(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + version: 1.0.0(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) copy-to-clipboard: specifier: ^3.3.3 version: 3.3.3 lucide-react: specifier: ^0.479.0 - version: 0.479.0(react@19.0.0) + version: 0.479.0(react@19.2.0) next-themes: - specifier: ^0.4.5 - version: 0.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^0.4.6 + version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: - specifier: ^19.0.0 - version: 19.0.0 + specifier: ^19.2.0 + version: 19.2.0 react-dom: - specifier: ^19.0.0 - version: 19.0.0(react@19.0.0) + specifier: ^19.2.0 + version: 19.2.0(react@19.2.0) react-router-dom: - specifier: ^7.4.1 - version: 7.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^7.9.4 + version: 7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) sonner: - specifier: ^2.0.1 - version: 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + specifier: ^2.0.7 + version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) tailwind-merge: - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.3.1 + version: 3.4.0 tailwindcss: - specifier: ^4.0.12 - version: 4.0.12 + specifier: ^4.1.16 + version: 4.1.17 tailwindcss-animate: specifier: ^1.0.7 - version: 1.0.7(tailwindcss@4.0.12) + version: 1.0.7(tailwindcss@4.1.17) vite-plugin-static-copy: - specifier: 2.3.0 - version: 2.3.0(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1)) + specifier: ^2.3.2 + version: 2.3.2(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1)) yaml: specifier: 2.7.1 version: 2.7.1 zustand: - specifier: ^5.0.3 - version: 5.0.3(@types/react@19.0.10)(react@19.0.0) + specifier: ^5.0.8 + version: 5.0.8(@types/react@19.2.4)(react@19.2.0) devDependencies: '@types/node': - specifier: ^20.8.2 - version: 20.17.24 + specifier: ^20.19.23 + version: 20.19.25 '@types/react': - specifier: ^19.0.10 - version: 19.0.10 + specifier: ^19.2.2 + version: 19.2.4 '@types/react-dom': - specifier: ^19.0.4 - version: 19.0.4(@types/react@19.0.10) + specifier: ^19.2.2 + version: 19.2.3(@types/react@19.2.4) '@vitejs/plugin-react': - specifier: ^4.3.4 - version: 4.3.4(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1)) + specifier: ^4.7.0 + version: 4.7.0(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1)) globals: specifier: ^15.15.0 version: 15.15.0 typescript: - specifier: ~5.7.2 + specifier: ~5.7.3 version: 5.7.3 vite: - specifier: ^6.2.0 - version: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1) + specifier: ^6.4.1 + version: 6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1) packages: - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.8': - resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + '@babel/compat-data@7.28.5': + resolution: {integrity: sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==} engines: {node: '>=6.9.0'} - '@babel/core@7.26.9': - resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + '@babel/core@7.28.5': + resolution: {integrity: sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.9': - resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==} + '@babel/generator@7.28.5': + resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.26.5': - resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.3': + resolution: {integrity: sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.26.5': - resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.9': - resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} '@babel/parser@7.26.9': @@ -188,14 +196,19 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-transform-react-jsx-self@7.25.9': - resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + '@babel/parser@7.28.5': + resolution: {integrity: sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.27.1': + resolution: {integrity: sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-react-jsx-source@7.25.9': - resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + '@babel/plugin-transform-react-jsx-source@7.27.1': + resolution: {integrity: sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -204,32 +217,36 @@ packages: resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} engines: {node: '>=6.9.0'} - '@babel/template@7.26.9': - resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.26.9': - resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==} + '@babel/traverse@7.28.5': + resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} '@babel/types@7.26.9': resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} engines: {node: '>=6.9.0'} - '@codemirror/autocomplete@6.18.6': - resolution: {integrity: sha512-PHHBXFomUs5DF+9tCOM/UoW6XQ4R44lLNNhRaW9PKPTU0D7lIjRg3ElxaJnTwsl/oHiR93WSXDBrekhoUGCPtg==} + '@babel/types@7.28.5': + resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} + engines: {node: '>=6.9.0'} + + '@codemirror/autocomplete@6.19.1': + resolution: {integrity: sha512-q6NenYkEy2fn9+JyjIxMWcNjzTL/IhwqfzOut1/G3PrIFkrbl4AL7Wkse5tLrQUUyqGoAKU5+Pi5jnnXxH5HGw==} '@codemirror/commands@6.8.0': resolution: {integrity: sha512-q8VPEFaEP4ikSlt6ZxjB3zW72+7osfAYW9i8Zu943uqbKuz6utc1+F170hyLUCUltXORjQXRyYQNfkckzA/bPQ==} - '@codemirror/lang-json@6.0.1': - resolution: {integrity: sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==} + '@codemirror/lang-json@6.0.2': + resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==} '@codemirror/lang-yaml@6.1.2': resolution: {integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==} - '@codemirror/language@6.10.8': - resolution: {integrity: sha512-wcP8XPPhDH2vTqf181U8MbZnW+tDyPYy0UzVOa+oHORjyT+mhhom9vBd7dApJwoDz9Nb/a8kHjJIsuA/t8vNFw==} + '@codemirror/language@6.11.3': + resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==} '@codemirror/legacy-modes@6.4.0': resolution: {integrity: sha512-5m/K+1A6gYR0e+h/dEde7LoGimMjRtWXZFg4Lo70cc8HzjSdHe3fLwjWMR0VRl5KFT1SxalSap7uMgPKF28wBA==} @@ -420,10 +437,16 @@ packages: '@iarna/toml@2.2.5': resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -435,9 +458,15 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@lezer/common@1.2.3': resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==} @@ -471,11 +500,11 @@ packages: '@radix-ui/primitive@1.0.1': resolution: {integrity: sha512-yQ8oGX2GVsEYMWGxcovu1uGWPCxV5BFfeeYxqPmuAzUyLT9qmaMXSAhXpb0WrspIeqYzdJpkh2vHModJPgRIaw==} - '@radix-ui/primitive@1.1.1': - resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} - '@radix-ui/react-arrow@1.1.2': - resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==} + '@radix-ui/react-arrow@1.1.7': + resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -487,8 +516,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-collection@1.1.2': - resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==} + '@radix-ui/react-collection@1.1.7': + resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -509,8 +538,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-compose-refs@1.1.1': - resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==} + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -527,8 +556,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-context@1.1.1': - resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + '@radix-ui/react-context@1.1.2': + resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -549,8 +578,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dialog@1.1.6': - resolution: {integrity: sha512-/IVhJV5AceX620DUJ4uYVMymzsipdKBzo3edo+omeskCKGm9FRHM0ebIdbPnlQVJqyuHbuBltQUOG2mOTq2IYw==} + '@radix-ui/react-dialog@1.1.15': + resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -562,8 +591,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-direction@1.1.0': - resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} + '@radix-ui/react-direction@1.1.1': + resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -584,8 +613,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dismissable-layer@1.1.5': - resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==} + '@radix-ui/react-dismissable-layer@1.1.11': + resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -597,8 +626,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-dropdown-menu@2.1.6': - resolution: {integrity: sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA==} + '@radix-ui/react-dropdown-menu@2.1.16': + resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -619,8 +648,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-focus-guards@1.1.1': - resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + '@radix-ui/react-focus-guards@1.1.3': + resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -641,8 +670,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-focus-scope@1.1.2': - resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==} + '@radix-ui/react-focus-scope@1.1.7': + resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -663,8 +692,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-id@1.1.0': - resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} + '@radix-ui/react-id@1.1.1': + resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -672,8 +701,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-label@2.1.2': - resolution: {integrity: sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==} + '@radix-ui/react-label@2.1.8': + resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -685,8 +714,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-menu@2.1.6': - resolution: {integrity: sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg==} + '@radix-ui/react-menu@2.1.16': + resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -698,8 +727,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popover@1.1.6': - resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==} + '@radix-ui/react-popover@1.1.15': + resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -711,8 +740,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-popper@1.2.2': - resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==} + '@radix-ui/react-popper@1.2.8': + resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -737,8 +766,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-portal@1.1.4': - resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==} + '@radix-ui/react-portal@1.1.9': + resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -763,8 +792,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-presence@1.1.2': - resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} + '@radix-ui/react-presence@1.1.5': + resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -789,8 +818,8 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-primitive@2.0.2': - resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==} + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -802,8 +831,21 @@ packages: '@types/react-dom': optional: true - '@radix-ui/react-roving-focus@1.1.2': - resolution: {integrity: sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==} + '@radix-ui/react-primitive@2.1.4': + resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-roving-focus@1.1.11': + resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -824,8 +866,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-slot@1.1.2': - resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==} + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -833,8 +875,17 @@ packages: '@types/react': optional: true - '@radix-ui/react-tabs@1.1.3': - resolution: {integrity: sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==} + '@radix-ui/react-slot@1.2.4': + resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-tabs@1.1.13': + resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -855,8 +906,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-callback-ref@1.1.0': - resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==} + '@radix-ui/react-use-callback-ref@1.1.1': + resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -873,8 +924,17 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-controllable-state@1.1.0': - resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -891,8 +951,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-escape-keydown@1.1.0': - resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} + '@radix-ui/react-use-escape-keydown@1.1.1': + resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -909,8 +969,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-layout-effect@1.1.0': - resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -918,8 +978,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-rect@1.1.0': - resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==} + '@radix-ui/react-use-rect@1.1.1': + resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -927,8 +987,8 @@ packages: '@types/react': optional: true - '@radix-ui/react-use-size@1.1.0': - resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==} + '@radix-ui/react-use-size@1.1.1': + resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -936,8 +996,11 @@ packages: '@types/react': optional: true - '@radix-ui/rect@1.1.0': - resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + '@radix-ui/rect@1.1.1': + resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + + '@rolldown/pluginutils@1.0.0-beta.27': + resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} '@rollup/rollup-android-arm-eabi@4.35.0': resolution: {integrity: sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==} @@ -1034,83 +1097,95 @@ packages: cpu: [x64] os: [win32] - '@tailwindcss/node@4.0.12': - resolution: {integrity: sha512-a6J11K1Ztdln9OrGfoM75/hChYPcHYGNYimqciMrvKXRmmPaS8XZTHhdvb5a3glz4Kd4ZxE1MnuFE2c0fGGmtg==} + '@tailwindcss/node@4.1.17': + resolution: {integrity: sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==} - '@tailwindcss/oxide-android-arm64@4.0.12': - resolution: {integrity: sha512-dAXCaemu3mHLXcA5GwGlQynX8n7tTdvn5i1zAxRvZ5iC9fWLl5bGnjZnzrQqT7ttxCvRwdVf3IHUnMVdDBO/kQ==} + '@tailwindcss/oxide-android-arm64@4.1.17': + resolution: {integrity: sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.0.12': - resolution: {integrity: sha512-vPNI+TpJQ7sizselDXIJdYkx9Cu6JBdtmRWujw9pVIxW8uz3O2PjgGGzL/7A0sXI8XDjSyRChrUnEW9rQygmJQ==} + '@tailwindcss/oxide-darwin-arm64@4.1.17': + resolution: {integrity: sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.0.12': - resolution: {integrity: sha512-RL/9jM41Fdq4Efr35C5wgLx98BirnrfwuD+zgMFK6Ir68HeOSqBhW9jsEeC7Y/JcGyPd3MEoJVIU4fAb7YLg7A==} + '@tailwindcss/oxide-darwin-x64@4.1.17': + resolution: {integrity: sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.0.12': - resolution: {integrity: sha512-7WzWiax+LguJcMEimY0Q4sBLlFXu1tYxVka3+G2M9KmU/3m84J3jAIV4KZWnockbHsbb2XgrEjtlJKVwHQCoRA==} + '@tailwindcss/oxide-freebsd-x64@4.1.17': + resolution: {integrity: sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.12': - resolution: {integrity: sha512-X9LRC7jjE1QlfIaBbXjY0PGeQP87lz5mEfLSVs2J1yRc9PSg1tEPS9NBqY4BU9v5toZgJgzKeaNltORyTs22TQ==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17': + resolution: {integrity: sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.0.12': - resolution: {integrity: sha512-i24IFNq2402zfDdoWKypXz0ZNS2G4NKaA82tgBlE2OhHIE+4mg2JDb5wVfyP6R+MCm5grgXvurcIcKWvo44QiQ==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.17': + resolution: {integrity: sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.0.12': - resolution: {integrity: sha512-LmOdshJBfAGIBG0DdBWhI0n5LTMurnGGJCHcsm9F//ISfsHtCnnYIKgYQui5oOz1SUCkqsMGfkAzWyNKZqbGNw==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.17': + resolution: {integrity: sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.0.12': - resolution: {integrity: sha512-OSK667qZRH30ep8RiHbZDQfqkXjnzKxdn0oRwWzgCO8CoTxV+MvIkd0BWdQbYtYuM1wrakARV/Hwp0eA/qzdbw==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.17': + resolution: {integrity: sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.0.12': - resolution: {integrity: sha512-uylhWq6OWQ8krV8Jk+v0H/3AZKJW6xYMgNMyNnUbbYXWi7hIVdxRKNUB5UvrlC3RxtgsK5EAV2i1CWTRsNcAnA==} + '@tailwindcss/oxide-linux-x64-musl@4.1.17': + resolution: {integrity: sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-win32-arm64-msvc@4.0.12': - resolution: {integrity: sha512-XDLnhMoXZEEOir1LK43/gHHwK84V1GlV8+pAncUAIN2wloeD+nNciI9WRIY/BeFTqES22DhTIGoilSO39xDb2g==} + '@tailwindcss/oxide-wasm32-wasi@4.1.17': + resolution: {integrity: sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.17': + resolution: {integrity: sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.0.12': - resolution: {integrity: sha512-I/BbjCLpKDQucvtn6rFuYLst1nfFwSMYyPzkx/095RE+tuzk5+fwXuzQh7T3fIBTcbn82qH/sFka7yPGA50tLw==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.17': + resolution: {integrity: sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.0.12': - resolution: {integrity: sha512-DWb+myvJB9xJwelwT9GHaMc1qJj6MDXRDR0CS+T8IdkejAtu8ctJAgV4r1drQJLPeS7mNwq2UHW2GWrudTf63A==} + '@tailwindcss/oxide@4.1.17': + resolution: {integrity: sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==} engines: {node: '>= 10'} - '@tailwindcss/vite@4.0.12': - resolution: {integrity: sha512-JM3gp601UJiryIZ9R2bSqalzcOy15RCybQ1Q+BJqDEwVyo4LkWKeqQAcrpHapWXY31OJFTuOUVBFDWMhzHm2Bg==} + '@tailwindcss/vite@4.1.17': + resolution: {integrity: sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA==} peerDependencies: - vite: ^5.2.0 || ^6 + vite: ^5.2.0 || ^6 || ^7 '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1124,25 +1199,22 @@ packages: '@types/babel__traverse@7.20.6': resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} - '@types/cookie@0.6.0': - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} - '@types/node@20.17.24': - resolution: {integrity: sha512-d7fGCyB96w9BnWQrOsJtpyiSaBcAYYr75bnK6ZRjDbql2cGLj/3GsL5OYmLPNq76l7Gf2q4Rv9J2o6h5CrD9sA==} + '@types/node@20.19.25': + resolution: {integrity: sha512-ZsJzA5thDQMSQO788d7IocwwQbI8B5OPzmqNvpf3NY/+MHDAS759Wo0gd2WQeXYt5AAAQjzcrTVC6SKCuYgoCQ==} - '@types/react-dom@19.0.4': - resolution: {integrity: sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg==} + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: - '@types/react': ^19.0.0 + '@types/react': ^19.2.0 - '@types/react@19.0.10': - resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==} + '@types/react@19.2.4': + resolution: {integrity: sha512-tBFxBp9Nfyy5rsmefN+WXc1JeW/j2BpBHFdLZbEVfs9wn3E3NRFxwV0pJg8M1qQAexFpvz73hJXFofV0ZAu92A==} - '@uiw/codemirror-extensions-basic-setup@4.23.10': - resolution: {integrity: sha512-zpbmSeNs3OU/f/Eyd6brFnjsBUYwv2mFjWxlAsIRSwTlW+skIT60rQHFBSfsj/5UVSxSLWVeUYczN7AyXvgTGQ==} + '@uiw/codemirror-extensions-basic-setup@4.25.3': + resolution: {integrity: sha512-F1doRyD50CWScwGHG2bBUtUpwnOv/zqSnzkZqJcX5YAHQx6Z1CuX8jdnFMH6qktRrPU1tfpNYftTWu3QIoHiMA==} peerDependencies: '@codemirror/autocomplete': '>=6.0.0' '@codemirror/commands': '>=6.0.0' @@ -1152,32 +1224,32 @@ packages: '@codemirror/state': '>=6.0.0' '@codemirror/view': '>=6.0.0' - '@uiw/codemirror-theme-github@4.23.10': - resolution: {integrity: sha512-jTg2sHAcU1d+8x0O+EBDI71rtJ8PWKIW8gzy+SW4wShQTAdsqGHk5y1ynt3KIeoaUkqngLqAK4SkhPaUKlqZqg==} + '@uiw/codemirror-theme-github@4.25.3': + resolution: {integrity: sha512-KdmcO9VicsBgsDErNrNBqwMuTbJRIpeMl9oIjmrNx2iEfIDSOMBIKlX+BkgwTAU+VmhqYY/68/kmF1K8z2FxrQ==} - '@uiw/codemirror-themes@4.23.10': - resolution: {integrity: sha512-dU0UgEEgEXCAYpxuVDQ6fovE82XsqgHZckTJOH6Bs8xCi3Z7dwBKO4pXuiA8qGDwTOXOMjSzfi+pRViDm7OfWw==} + '@uiw/codemirror-themes@4.25.3': + resolution: {integrity: sha512-k7/B7Vf4jU/WcdewgJWP9tMFxbjB6UpUymZ3fx/TsbGwt2JXAouw0uyqCn1RlYBfr7YQnvEs3Ju9ECkd2sKzdg==} peerDependencies: '@codemirror/language': '>=6.0.0' '@codemirror/state': '>=6.0.0' '@codemirror/view': '>=6.0.0' - '@uiw/react-codemirror@4.23.10': - resolution: {integrity: sha512-AbN4eVHOL4ckRuIXpZxkzEqL/1ChVA+BSdEnAKjIB68pLQvKsVoYbiFP8zkXkYc4+Fcgq5KbAjvYqdo4ewemKw==} + '@uiw/react-codemirror@4.25.3': + resolution: {integrity: sha512-1wtBZTXPIp8u6F/xjHvsUAYlEeF5Dic4xZBnqJyLzv7o7GjGYEUfSz9Z7bo9aK9GAx2uojG/AuBMfhA4uhvIVQ==} peerDependencies: '@babel/runtime': '>=7.11.0' '@codemirror/state': '>=6.0.0' '@codemirror/theme-one-dark': '>=6.0.0' '@codemirror/view': '>=6.0.0' codemirror: '>=6.0.0' - react: '>=16.8.0' - react-dom: '>=16.8.0' + react: '>=17.0.0' + react-dom: '>=17.0.0' - '@vitejs/plugin-react@4.3.4': - resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + '@vitejs/plugin-react@4.7.0': + resolution: {integrity: sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} @@ -1258,8 +1330,8 @@ packages: electron-to-chromium@1.5.113: resolution: {integrity: sha512-wjT2O4hX+wdWPJ76gWSkMhcHAV2PTMX+QetUCPYEdCIe+cxmgzzSSiGRCKW8nuh4mwKZlpv0xvoW7OF2X+wmHg==} - enhanced-resolve@5.18.1: - resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} esbuild@0.25.1: @@ -1278,6 +1350,15 @@ packages: fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1303,10 +1384,6 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - globals@15.15.0: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} @@ -1330,8 +1407,8 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true js-tokens@4.0.0: @@ -1350,68 +1427,74 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - lightningcss-darwin-arm64@1.29.2: - resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==} + lightningcss-android-arm64@1.30.2: + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.30.2: + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.29.2: - resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==} + lightningcss-darwin-x64@1.30.2: + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.29.2: - resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==} + lightningcss-freebsd-x64@1.30.2: + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.29.2: - resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==} + lightningcss-linux-arm-gnueabihf@1.30.2: + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.29.2: - resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==} + lightningcss-linux-arm64-gnu@1.30.2: + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.29.2: - resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==} + lightningcss-linux-arm64-musl@1.30.2: + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.29.2: - resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==} + lightningcss-linux-x64-gnu@1.30.2: + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.29.2: - resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==} + lightningcss-linux-x64-musl@1.30.2: + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-win32-arm64-msvc@1.29.2: - resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==} + lightningcss-win32-arm64-msvc@1.30.2: + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.29.2: - resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==} + lightningcss-win32-x64-msvc@1.30.2: + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.29.2: - resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==} + lightningcss@1.30.2: + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} lru-cache@5.1.1: @@ -1422,6 +1505,9 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1438,8 +1524,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - next-themes@0.4.5: - resolution: {integrity: sha512-E8/gYKBxZknOXBiDk/sRokAvkOw35PTUD4Gxtq1eBhd0r4Dx5S42zU65/q8ozR5rcSG2ZlE1E3+ShlUpC7an+A==} + next-themes@0.4.6: + resolution: {integrity: sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==} peerDependencies: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc @@ -1462,6 +1548,10 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + postcss@8.5.3: resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} engines: {node: ^10 || ^12 || >=14} @@ -1469,13 +1559,13 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - react-dom@19.0.0: - resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} + react-dom@19.2.0: + resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==} peerDependencies: - react: ^19.0.0 + react: ^19.2.0 - react-refresh@0.14.2: - resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + react-refresh@0.17.0: + resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==} engines: {node: '>=0.10.0'} react-remove-scroll-bar@2.3.8: @@ -1508,15 +1598,15 @@ packages: '@types/react': optional: true - react-router-dom@7.4.1: - resolution: {integrity: sha512-L3/4tig0Lvs6m6THK0HRV4eHUdpx0dlJasgCxXKnavwhh4tKYgpuZk75HRYNoRKDyDWi9QgzGXsQ1oQSBlWpAA==} + react-router-dom@7.9.6: + resolution: {integrity: sha512-2MkC2XSXq6HjGcihnx1s0DBWQETI4mlis4Ux7YTLvP67xnGxCvq+BcCQSO81qQHVUTM1V53tl4iVVaY5sReCOA==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' react-dom: '>=18' - react-router@7.4.1: - resolution: {integrity: sha512-Vmizn9ZNzxfh3cumddqv3kLOKvc7AskUT0dC1prTabhiEi0U4A33LmkDOJ79tXaeSqCqMBXBU/ySX88W85+EUg==} + react-router@7.9.6: + resolution: {integrity: sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -1535,8 +1625,8 @@ packages: '@types/react': optional: true - react@19.0.0: - resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} readdirp@3.6.0: @@ -1558,8 +1648,8 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - scheduler@0.25.0: - resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -1568,8 +1658,8 @@ packages: set-cookie-parser@2.7.1: resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} - sonner@2.0.1: - resolution: {integrity: sha512-FRBphaehZ5tLdLcQ8g2WOIRE+Y7BCfWi5Zyd8bCvBjiW8TxxAyoWZIxS661Yz6TGPqFQ4VLzOF89WEYhfynSFQ==} + sonner@2.0.7: + resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==} peerDependencies: react: ^18.0.0 || ^19.0.0 || ^19.0.0-rc react-dom: ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -1581,21 +1671,25 @@ packages: style-mod@4.1.2: resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} - tailwind-merge@3.0.2: - resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==} + tailwind-merge@3.4.0: + resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} tailwindcss-animate@1.0.7: resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} peerDependencies: tailwindcss: '>=3.0.0 || insiders' - tailwindcss@4.0.12: - resolution: {integrity: sha512-bT0hJo91FtncsAMSsMzUkoo/iEU0Xs5xgFgVC9XmdM9bw5MhZuQFjPNl6wxAE0SiQF/YTZJa+PndGWYSDtuxAg==} + tailwindcss@4.1.17: + resolution: {integrity: sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==} tapable@2.2.1: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -1606,16 +1700,13 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - turbo-stream@2.4.0: - resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} - typescript@5.7.3: resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} engines: {node: '>=14.17'} hasBin: true - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} @@ -1647,14 +1738,14 @@ packages: '@types/react': optional: true - vite-plugin-static-copy@2.3.0: - resolution: {integrity: sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA==} + vite-plugin-static-copy@2.3.2: + resolution: {integrity: sha512-iwrrf+JupY4b9stBttRWzGHzZbeMjAHBhkrn67MNACXJVjEMRpCI10Q3AkxdBkl45IHaTfw/CNVevzQhP7yTwg==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: vite: ^5.0.0 || ^6.0.0 - vite@6.2.1: - resolution: {integrity: sha512-n2GnqDb6XPhlt9B8olZPrgMD/es/Nd1RdChF6CBD/fHW6pUyUTt2sQW2fPRX5GiD9XEa6+8A6A4f2vT6pSsE7Q==} + vite@6.4.1: + resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: @@ -1704,8 +1795,8 @@ packages: engines: {node: '>= 14'} hasBin: true - zustand@5.0.3: - resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + zustand@5.0.8: + resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} engines: {node: '>=12.20.0'} peerDependencies: '@types/react': '>=18.0.0' @@ -1724,31 +1815,26 @@ packages: snapshots: - '@ampproject/remapping@2.3.0': + '@babel/code-frame@7.27.1': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - - '@babel/code-frame@7.26.2': - dependencies: - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-validator-identifier': 7.28.5 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.8': {} + '@babel/compat-data@7.28.5': {} - '@babel/core@7.26.9': + '@babel/core@7.28.5': dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.9 - '@babel/helper-compilation-targets': 7.26.5 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9) - '@babel/helpers': 7.26.9 - '@babel/parser': 7.26.9 - '@babel/template': 7.26.9 - '@babel/traverse': 7.26.9 - '@babel/types': 7.26.9 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 debug: 4.4.0 gensync: 1.0.0-beta.2 @@ -1757,84 +1843,94 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.26.9': + '@babel/generator@7.28.5': dependencies: - '@babel/parser': 7.26.9 - '@babel/types': 7.26.9 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-compilation-targets@7.26.5': + '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.26.8 - '@babel/helper-validator-option': 7.25.9 + '@babel/compat-data': 7.28.5 + '@babel/helper-validator-option': 7.27.1 browserslist: 4.24.4 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-module-imports@7.25.9': + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.26.9 - '@babel/types': 7.26.9 + '@babel/traverse': 7.28.5 + '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.26.9 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.26.9 + '@babel/core': 7.28.5 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.28.5 transitivePeerDependencies: - supports-color - '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.27.1': {} '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-validator-identifier@7.25.9': {} - '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-validator-identifier@7.28.5': {} - '@babel/helpers@7.26.9': + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.28.4': dependencies: - '@babel/template': 7.26.9 - '@babel/types': 7.26.9 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 '@babel/parser@7.26.9': dependencies: '@babel/types': 7.26.9 - '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.9)': + '@babel/parser@7.28.5': dependencies: - '@babel/core': 7.26.9 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/types': 7.28.5 - '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.9)': + '@babel/plugin-transform-react-jsx-self@7.27.1(@babel/core@7.28.5)': dependencies: - '@babel/core': 7.26.9 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-react-jsx-source@7.27.1(@babel/core@7.28.5)': + dependencies: + '@babel/core': 7.28.5 + '@babel/helper-plugin-utils': 7.27.1 '@babel/runtime@7.26.9': dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.26.9': + '@babel/template@7.27.2': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.9 - '@babel/types': 7.26.9 + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.5 + '@babel/types': 7.28.5 - '@babel/traverse@7.26.9': + '@babel/traverse@7.28.5': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.9 - '@babel/parser': 7.26.9 - '@babel/template': 7.26.9 - '@babel/types': 7.26.9 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.5 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.5 debug: 4.4.0 - globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -1843,36 +1939,41 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@codemirror/autocomplete@6.18.6': + '@babel/types@7.28.5': dependencies: - '@codemirror/language': 6.10.8 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@codemirror/autocomplete@6.19.1': + dependencies: + '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.29.0 '@lezer/common': 1.2.3 '@codemirror/commands@6.8.0': dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.29.0 '@lezer/common': 1.2.3 - '@codemirror/lang-json@6.0.1': + '@codemirror/lang-json@6.0.2': dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.3 '@lezer/json': 1.0.3 '@codemirror/lang-yaml@6.1.2': dependencies: - '@codemirror/autocomplete': 6.18.6 - '@codemirror/language': 6.10.8 + '@codemirror/autocomplete': 6.19.1 + '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@lezer/common': 1.2.3 '@lezer/highlight': 1.2.1 '@lezer/lr': 1.4.2 '@lezer/yaml': 1.0.3 - '@codemirror/language@6.10.8': + '@codemirror/language@6.11.3': dependencies: '@codemirror/state': 6.5.2 '@codemirror/view': 6.29.0 @@ -1883,7 +1984,7 @@ snapshots: '@codemirror/legacy-modes@6.4.0': dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.3 '@codemirror/lint@6.8.4': dependencies: @@ -1903,7 +2004,7 @@ snapshots: '@codemirror/theme-one-dark@6.1.2': dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.29.0 '@lezer/highlight': 1.2.1 @@ -2004,33 +2105,50 @@ snapshots: '@floating-ui/core': 1.6.9 '@floating-ui/utils': 0.2.9 - '@floating-ui/react-dom@2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@floating-ui/react-dom@2.1.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@floating-ui/dom': 1.6.13 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) '@floating-ui/utils@0.2.9': {} '@iarna/toml@2.2.5': {} + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/set-array@1.2.1': {} '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + '@lezer/common@1.2.3': {} '@lezer/highlight@1.2.1': @@ -2071,454 +2189,480 @@ snapshots: dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/primitive@1.1.1': {} + '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-arrow@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-collection@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-compose-refs@1.0.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-compose-refs@1.0.1(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.4)(react@19.2.0)': dependencies: - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-context@1.0.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-context@1.0.1(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-context@1.1.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-context@1.1.2(@types/react@19.2.4)(react@19.2.0)': dependencies: - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-dialog@1.0.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-dialog@1.0.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-focus-guards': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-id': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-slot': 1.0.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-slot': 1.0.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@19.2.4)(react@19.2.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.5.5(@types/react@19.0.10)(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-remove-scroll: 2.5.5(@types/react@19.2.4)(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-dialog@1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.4)(react@19.2.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-remove-scroll: 2.6.3(@types/react@19.2.4)(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-direction@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-direction@1.1.1(@types/react@19.2.4)(react@19.2.0)': dependencies: - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-dropdown-menu@2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-dropdown-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-menu': 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-focus-guards@1.0.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-focus-guards@1.0.1(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-focus-guards@1.1.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.4)(react@19.2.0)': dependencies: - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-id@1.0.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-id@1.0.1(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-id@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-id@1.1.1(@types/react@19.2.4)(react@19.2.0)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-label@2.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-menu@2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-menu@2.1.16(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.4)(react@19.2.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-remove-scroll: 2.6.3(@types/react@19.2.4)(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-popover@1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-focus-guards': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-popper': 1.2.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-portal': 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.4)(react@19.2.0) aria-hidden: 1.2.4 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-remove-scroll: 2.6.3(@types/react@19.0.10)(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-remove-scroll: 2.6.3(@types/react@19.2.4)(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-popper@1.2.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-arrow': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-rect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-size': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/rect': 1.1.0 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@floating-ui/react-dom': 2.1.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/rect': 1.1.1 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-portal@1.0.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-portal@1.0.4(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-portal@1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-presence@1.0.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-presence@1.0.1(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-primitive@1.0.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-primitive@1.0.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-slot': 1.0.2(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-slot': 1.0.2(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-primitive@2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-roving-focus@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-primitive@2.1.4(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-collection': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) - '@radix-ui/react-slot@1.0.2(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) + + '@radix-ui/react-slot@1.0.2(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-slot@1.1.2(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-slot@1.2.3(@types/react@19.2.4)(react@19.2.0)': dependencies: - '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-tabs@1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@radix-ui/react-slot@1.2.4(@types/react@19.2.4)(react@19.2.0)': dependencies: - '@radix-ui/primitive': 1.1.1 - '@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-id': 1.1.0(@types/react@19.0.10)(react@19.0.0) - '@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-roving-focus': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 - '@types/react-dom': 19.0.4(@types/react@19.0.10) + '@types/react': 19.2.4 - '@radix-ui/react-use-callback-ref@1.0.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.3 + '@radix-ui/react-context': 1.1.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.4 + '@types/react-dom': 19.2.3(@types/react@19.2.4) + + '@radix-ui/react-use-callback-ref@1.0.1(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.4)(react@19.2.0)': dependencies: - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-controllable-state@1.0.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-controllable-state@1.0.1(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-controllable-state@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.4)(react@19.2.0)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.4)(react@19.2.0) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.4)(react@19.2.0)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 + optionalDependencies: + '@types/react': 19.2.4 + + '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.4)(react@19.2.0)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-layout-effect@1.0.1(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-layout-effect@1.0.1(@types/react@19.2.4)(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.4)(react@19.2.0)': dependencies: - react: 19.0.0 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-rect@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.4)(react@19.2.0)': dependencies: - '@radix-ui/rect': 1.1.0 - react: 19.0.0 + '@radix-ui/rect': 1.1.1 + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/react-use-size@1.1.0(@types/react@19.0.10)(react@19.0.0)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.4)(react@19.2.0)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0) - react: 19.0.0 + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.4)(react@19.2.0) + react: 19.2.0 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@radix-ui/rect@1.1.0': {} + '@radix-ui/rect@1.1.1': {} + + '@rolldown/pluginutils@1.0.0-beta.27': {} '@rollup/rollup-android-arm-eabi@4.35.0': optional: true @@ -2577,66 +2721,73 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.35.0': optional: true - '@tailwindcss/node@4.0.12': + '@tailwindcss/node@4.1.17': dependencies: - enhanced-resolve: 5.18.1 - jiti: 2.4.2 - tailwindcss: 4.0.12 + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.18.3 + jiti: 2.6.1 + lightningcss: 1.30.2 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.1.17 - '@tailwindcss/oxide-android-arm64@4.0.12': + '@tailwindcss/oxide-android-arm64@4.1.17': optional: true - '@tailwindcss/oxide-darwin-arm64@4.0.12': + '@tailwindcss/oxide-darwin-arm64@4.1.17': optional: true - '@tailwindcss/oxide-darwin-x64@4.0.12': + '@tailwindcss/oxide-darwin-x64@4.1.17': optional: true - '@tailwindcss/oxide-freebsd-x64@4.0.12': + '@tailwindcss/oxide-freebsd-x64@4.1.17': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.12': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.0.12': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.17': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.0.12': + '@tailwindcss/oxide-linux-arm64-musl@4.1.17': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.0.12': + '@tailwindcss/oxide-linux-x64-gnu@4.1.17': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.0.12': + '@tailwindcss/oxide-linux-x64-musl@4.1.17': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.0.12': + '@tailwindcss/oxide-wasm32-wasi@4.1.17': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.0.12': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.17': optional: true - '@tailwindcss/oxide@4.0.12': + '@tailwindcss/oxide-win32-x64-msvc@4.1.17': + optional: true + + '@tailwindcss/oxide@4.1.17': optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.0.12 - '@tailwindcss/oxide-darwin-arm64': 4.0.12 - '@tailwindcss/oxide-darwin-x64': 4.0.12 - '@tailwindcss/oxide-freebsd-x64': 4.0.12 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.12 - '@tailwindcss/oxide-linux-arm64-gnu': 4.0.12 - '@tailwindcss/oxide-linux-arm64-musl': 4.0.12 - '@tailwindcss/oxide-linux-x64-gnu': 4.0.12 - '@tailwindcss/oxide-linux-x64-musl': 4.0.12 - '@tailwindcss/oxide-win32-arm64-msvc': 4.0.12 - '@tailwindcss/oxide-win32-x64-msvc': 4.0.12 + '@tailwindcss/oxide-android-arm64': 4.1.17 + '@tailwindcss/oxide-darwin-arm64': 4.1.17 + '@tailwindcss/oxide-darwin-x64': 4.1.17 + '@tailwindcss/oxide-freebsd-x64': 4.1.17 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.17 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.17 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.17 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.17 + '@tailwindcss/oxide-linux-x64-musl': 4.1.17 + '@tailwindcss/oxide-wasm32-wasi': 4.1.17 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.17 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.17 - '@tailwindcss/vite@4.0.12(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1))': + '@tailwindcss/vite@4.1.17(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1))': dependencies: - '@tailwindcss/node': 4.0.12 - '@tailwindcss/oxide': 4.0.12 - lightningcss: 1.29.2 - tailwindcss: 4.0.12 - vite: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1) + '@tailwindcss/node': 4.1.17 + '@tailwindcss/oxide': 4.1.17 + tailwindcss: 4.1.17 + vite: 6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1) '@types/babel__core@7.20.5': dependencies: @@ -2659,71 +2810,70 @@ snapshots: dependencies: '@babel/types': 7.26.9 - '@types/cookie@0.6.0': {} - '@types/estree@1.0.6': {} - '@types/node@20.17.24': + '@types/node@20.19.25': dependencies: - undici-types: 6.19.8 + undici-types: 6.21.0 - '@types/react-dom@19.0.4(@types/react@19.0.10)': + '@types/react-dom@19.2.3(@types/react@19.2.4)': dependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - '@types/react@19.0.10': + '@types/react@19.2.4': dependencies: csstype: 3.1.3 - '@uiw/codemirror-extensions-basic-setup@4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)': + '@uiw/codemirror-extensions-basic-setup@4.25.3(@codemirror/autocomplete@6.19.1)(@codemirror/commands@6.8.0)(@codemirror/language@6.11.3)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)': dependencies: - '@codemirror/autocomplete': 6.18.6 + '@codemirror/autocomplete': 6.19.1 '@codemirror/commands': 6.8.0 - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.3 '@codemirror/lint': 6.8.4 '@codemirror/search': 6.5.10 '@codemirror/state': 6.5.2 '@codemirror/view': 6.29.0 - '@uiw/codemirror-theme-github@4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)': + '@uiw/codemirror-theme-github@4.25.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)': dependencies: - '@uiw/codemirror-themes': 4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0) + '@uiw/codemirror-themes': 4.25.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0) transitivePeerDependencies: - '@codemirror/language' - '@codemirror/state' - '@codemirror/view' - '@uiw/codemirror-themes@4.23.10(@codemirror/language@6.10.8)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)': + '@uiw/codemirror-themes@4.25.3(@codemirror/language@6.11.3)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0)': dependencies: - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.3 '@codemirror/state': 6.5.2 '@codemirror/view': 6.29.0 - '@uiw/react-codemirror@4.23.10(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.18.6)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + '@uiw/react-codemirror@4.25.3(@babel/runtime@7.26.9)(@codemirror/autocomplete@6.19.1)(@codemirror/language@6.11.3)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/theme-one-dark@6.1.2)(@codemirror/view@6.29.0)(codemirror@6.0.1)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@babel/runtime': 7.26.9 '@codemirror/commands': 6.8.0 '@codemirror/state': 6.5.2 '@codemirror/theme-one-dark': 6.1.2 '@codemirror/view': 6.29.0 - '@uiw/codemirror-extensions-basic-setup': 4.23.10(@codemirror/autocomplete@6.18.6)(@codemirror/commands@6.8.0)(@codemirror/language@6.10.8)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0) + '@uiw/codemirror-extensions-basic-setup': 4.25.3(@codemirror/autocomplete@6.19.1)(@codemirror/commands@6.8.0)(@codemirror/language@6.11.3)(@codemirror/lint@6.8.4)(@codemirror/search@6.5.10)(@codemirror/state@6.5.2)(@codemirror/view@6.29.0) codemirror: 6.0.1 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) transitivePeerDependencies: - '@codemirror/autocomplete' - '@codemirror/language' - '@codemirror/lint' - '@codemirror/search' - '@vitejs/plugin-react@4.3.4(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1))': + '@vitejs/plugin-react@4.7.0(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1))': dependencies: - '@babel/core': 7.26.9 - '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.9) - '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9) + '@babel/core': 7.28.5 + '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.5) + '@rolldown/pluginutils': 1.0.0-beta.27 '@types/babel__core': 7.20.5 - react-refresh: 0.14.2 - vite: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1) + react-refresh: 0.17.0 + vite: 6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1) transitivePeerDependencies: - supports-color @@ -2769,21 +2919,21 @@ snapshots: clsx@2.1.1: {} - cmdk@1.0.0(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + cmdk@1.0.0(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - '@radix-ui/react-dialog': 1.0.5(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@19.2.3(@types/react@19.2.4))(@types/react@19.2.4)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) transitivePeerDependencies: - '@types/react' - '@types/react-dom' codemirror@6.0.1: dependencies: - '@codemirror/autocomplete': 6.18.6 + '@codemirror/autocomplete': 6.19.1 '@codemirror/commands': 6.8.0 - '@codemirror/language': 6.10.8 + '@codemirror/language': 6.11.3 '@codemirror/lint': 6.8.4 '@codemirror/search': 6.5.10 '@codemirror/state': 6.5.2 @@ -2811,7 +2961,7 @@ snapshots: electron-to-chromium@1.5.113: {} - enhanced-resolve@5.18.1: + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 tapable: 2.2.1 @@ -2858,6 +3008,10 @@ snapshots: dependencies: reusify: 1.1.0 + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -2879,8 +3033,6 @@ snapshots: dependencies: is-glob: 4.0.3 - globals@11.12.0: {} - globals@15.15.0: {} graceful-fs@4.2.11: {} @@ -2897,7 +3049,7 @@ snapshots: is-number@7.0.0: {} - jiti@2.4.2: {} + jiti@2.6.1: {} js-tokens@4.0.0: {} @@ -2911,58 +3063,66 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 - lightningcss-darwin-arm64@1.29.2: + lightningcss-android-arm64@1.30.2: optional: true - lightningcss-darwin-x64@1.29.2: + lightningcss-darwin-arm64@1.30.2: optional: true - lightningcss-freebsd-x64@1.29.2: + lightningcss-darwin-x64@1.30.2: optional: true - lightningcss-linux-arm-gnueabihf@1.29.2: + lightningcss-freebsd-x64@1.30.2: optional: true - lightningcss-linux-arm64-gnu@1.29.2: + lightningcss-linux-arm-gnueabihf@1.30.2: optional: true - lightningcss-linux-arm64-musl@1.29.2: + lightningcss-linux-arm64-gnu@1.30.2: optional: true - lightningcss-linux-x64-gnu@1.29.2: + lightningcss-linux-arm64-musl@1.30.2: optional: true - lightningcss-linux-x64-musl@1.29.2: + lightningcss-linux-x64-gnu@1.30.2: optional: true - lightningcss-win32-arm64-msvc@1.29.2: + lightningcss-linux-x64-musl@1.30.2: optional: true - lightningcss-win32-x64-msvc@1.29.2: + lightningcss-win32-arm64-msvc@1.30.2: optional: true - lightningcss@1.29.2: + lightningcss-win32-x64-msvc@1.30.2: + optional: true + + lightningcss@1.30.2: dependencies: detect-libc: 2.0.3 optionalDependencies: - lightningcss-darwin-arm64: 1.29.2 - lightningcss-darwin-x64: 1.29.2 - lightningcss-freebsd-x64: 1.29.2 - lightningcss-linux-arm-gnueabihf: 1.29.2 - lightningcss-linux-arm64-gnu: 1.29.2 - lightningcss-linux-arm64-musl: 1.29.2 - lightningcss-linux-x64-gnu: 1.29.2 - lightningcss-linux-x64-musl: 1.29.2 - lightningcss-win32-arm64-msvc: 1.29.2 - lightningcss-win32-x64-msvc: 1.29.2 + lightningcss-android-arm64: 1.30.2 + lightningcss-darwin-arm64: 1.30.2 + lightningcss-darwin-x64: 1.30.2 + lightningcss-freebsd-x64: 1.30.2 + lightningcss-linux-arm-gnueabihf: 1.30.2 + lightningcss-linux-arm64-gnu: 1.30.2 + lightningcss-linux-arm64-musl: 1.30.2 + lightningcss-linux-x64-gnu: 1.30.2 + lightningcss-linux-x64-musl: 1.30.2 + lightningcss-win32-arm64-msvc: 1.30.2 + lightningcss-win32-x64-msvc: 1.30.2 lru-cache@5.1.1: dependencies: yallist: 3.1.1 - lucide-react@0.479.0(react@19.0.0): + lucide-react@0.479.0(react@19.2.0): dependencies: - react: 19.0.0 + react: 19.2.0 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 merge2@1.4.1: {} @@ -2975,10 +3135,10 @@ snapshots: nanoid@3.3.9: {} - next-themes@0.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + next-themes@0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) node-releases@2.0.19: {} @@ -2990,6 +3150,8 @@ snapshots: picomatch@2.3.1: {} + picomatch@4.0.3: {} + postcss@8.5.3: dependencies: nanoid: 3.3.9 @@ -2998,68 +3160,66 @@ snapshots: queue-microtask@1.2.3: {} - react-dom@19.0.0(react@19.0.0): + react-dom@19.2.0(react@19.2.0): dependencies: - react: 19.0.0 - scheduler: 0.25.0 + react: 19.2.0 + scheduler: 0.27.0 - react-refresh@0.14.2: {} + react-refresh@0.17.0: {} - react-remove-scroll-bar@2.3.8(@types/react@19.0.10)(react@19.0.0): + react-remove-scroll-bar@2.3.8(@types/react@19.2.4)(react@19.2.0): dependencies: - react: 19.0.0 - react-style-singleton: 2.2.3(@types/react@19.0.10)(react@19.0.0) + react: 19.2.0 + react-style-singleton: 2.2.3(@types/react@19.2.4)(react@19.2.0) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - react-remove-scroll@2.5.5(@types/react@19.0.10)(react@19.0.0): + react-remove-scroll@2.5.5(@types/react@19.2.4)(react@19.2.0): dependencies: - react: 19.0.0 - react-remove-scroll-bar: 2.3.8(@types/react@19.0.10)(react@19.0.0) - react-style-singleton: 2.2.3(@types/react@19.0.10)(react@19.0.0) + react: 19.2.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.4)(react@19.2.0) + react-style-singleton: 2.2.3(@types/react@19.2.4)(react@19.2.0) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.0.10)(react@19.0.0) - use-sidecar: 1.1.3(@types/react@19.0.10)(react@19.0.0) + use-callback-ref: 1.3.3(@types/react@19.2.4)(react@19.2.0) + use-sidecar: 1.1.3(@types/react@19.2.4)(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - react-remove-scroll@2.6.3(@types/react@19.0.10)(react@19.0.0): + react-remove-scroll@2.6.3(@types/react@19.2.4)(react@19.2.0): dependencies: - react: 19.0.0 - react-remove-scroll-bar: 2.3.8(@types/react@19.0.10)(react@19.0.0) - react-style-singleton: 2.2.3(@types/react@19.0.10)(react@19.0.0) + react: 19.2.0 + react-remove-scroll-bar: 2.3.8(@types/react@19.2.4)(react@19.2.0) + react-style-singleton: 2.2.3(@types/react@19.2.4)(react@19.2.0) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.0.10)(react@19.0.0) - use-sidecar: 1.1.3(@types/react@19.0.10)(react@19.0.0) + use-callback-ref: 1.3.3(@types/react@19.2.4)(react@19.2.0) + use-sidecar: 1.1.3(@types/react@19.2.4)(react@19.2.0) optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - react-router-dom@7.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react-router-dom@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-router: 7.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + react-router: 7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-router@7.4.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + react-router@7.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - '@types/cookie': 0.6.0 cookie: 1.0.2 - react: 19.0.0 + react: 19.2.0 set-cookie-parser: 2.7.1 - turbo-stream: 2.4.0 optionalDependencies: - react-dom: 19.0.0(react@19.0.0) + react-dom: 19.2.0(react@19.2.0) - react-style-singleton@2.2.3(@types/react@19.0.10)(react@19.0.0): + react-style-singleton@2.2.3(@types/react@19.2.4)(react@19.2.0): dependencies: get-nonce: 1.0.1 - react: 19.0.0 + react: 19.2.0 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - react@19.0.0: {} + react@19.2.0: {} readdirp@3.6.0: dependencies: @@ -3098,31 +3258,36 @@ snapshots: dependencies: queue-microtask: 1.2.3 - scheduler@0.25.0: {} + scheduler@0.27.0: {} semver@6.3.1: {} set-cookie-parser@2.7.1: {} - sonner@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + sonner@2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0): dependencies: - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) source-map-js@1.2.1: {} style-mod@4.1.2: {} - tailwind-merge@3.0.2: {} + tailwind-merge@3.4.0: {} - tailwindcss-animate@1.0.7(tailwindcss@4.0.12): + tailwindcss-animate@1.0.7(tailwindcss@4.1.17): dependencies: - tailwindcss: 4.0.12 + tailwindcss: 4.1.17 - tailwindcss@4.0.12: {} + tailwindcss@4.1.17: {} tapable@2.2.1: {} + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -3131,11 +3296,9 @@ snapshots: tslib@2.8.1: {} - turbo-stream@2.4.0: {} - typescript@5.7.3: {} - undici-types@6.19.8: {} + undici-types@6.21.0: {} universalify@2.0.1: {} @@ -3145,40 +3308,43 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 - use-callback-ref@1.3.3(@types/react@19.0.10)(react@19.0.0): + use-callback-ref@1.3.3(@types/react@19.2.4)(react@19.2.0): dependencies: - react: 19.0.0 + react: 19.2.0 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - use-sidecar@1.1.3(@types/react@19.0.10)(react@19.0.0): + use-sidecar@1.1.3(@types/react@19.2.4)(react@19.2.0): dependencies: detect-node-es: 1.1.0 - react: 19.0.0 + react: 19.2.0 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.0.10 + '@types/react': 19.2.4 - vite-plugin-static-copy@2.3.0(vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1)): + vite-plugin-static-copy@2.3.2(vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1)): dependencies: chokidar: 3.6.0 fast-glob: 3.3.3 fs-extra: 11.3.0 p-map: 7.0.3 picocolors: 1.1.1 - vite: 6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1) + vite: 6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1) - vite@6.2.1(@types/node@20.17.24)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.7.1): + vite@6.4.1(@types/node@20.19.25)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.7.1): dependencies: esbuild: 0.25.1 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 postcss: 8.5.3 rollup: 4.35.0 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 20.17.24 + '@types/node': 20.19.25 fsevents: 2.3.3 - jiti: 2.4.2 - lightningcss: 1.29.2 + jiti: 2.6.1 + lightningcss: 1.30.2 yaml: 2.7.1 w3c-keyname@2.2.8: {} @@ -3187,7 +3353,7 @@ snapshots: yaml@2.7.1: {} - zustand@5.0.3(@types/react@19.0.10)(react@19.0.0): + zustand@5.0.8(@types/react@19.2.4)(react@19.2.0): optionalDependencies: - '@types/react': 19.0.10 - react: 19.0.0 + '@types/react': 19.2.4 + react: 19.2.0 diff --git a/blueprints/ackee/template.toml b/blueprints/ackee/template.toml index ebffa3e2..75ef3fe7 100644 --- a/blueprints/ackee/template.toml +++ b/blueprints/ackee/template.toml @@ -10,6 +10,7 @@ serviceName = "ackee" port = 3000 host = "${domain}" + [config.env] ACKEE_USERNAME = "${ACKEE_USERNAME}" ACKEE_PASSWORD = "${ACKEE_PASSWORD}" diff --git a/blueprints/anytype/docker-compose.yml b/blueprints/anytype/docker-compose.yml new file mode 100644 index 00000000..5d516cb6 --- /dev/null +++ b/blueprints/anytype/docker-compose.yml @@ -0,0 +1,19 @@ +# Example: Any-Sync-Bundle with embedded MongoDB and Redis (all-in-one image) +# +# Usage: +# docker compose -f compose.aio.yml up -d +# +# The bundle image already contains MongoDB and Redis. Only the bundle service is required + +services: + any-sync-bundle: + image: ghcr.io/grishy/any-sync-bundle:latest + restart: unless-stopped + ports: + - "33010:33010" + - "33020:33020/udp" + volumes: + - ./data:/data + environment: + # Advertise addresses clients should use. Replace with your server hostname/IP. + ANY_SYNC_BUNDLE_INIT_EXTERNAL_ADDRS: "192.168.100.9" diff --git a/blueprints/anytype/logo.png b/blueprints/anytype/logo.png new file mode 100644 index 00000000..903e9aeb Binary files /dev/null and b/blueprints/anytype/logo.png differ diff --git a/blueprints/anytype/template.toml b/blueprints/anytype/template.toml new file mode 100644 index 00000000..e1388da7 --- /dev/null +++ b/blueprints/anytype/template.toml @@ -0,0 +1,4 @@ +[config] +domains = [] +mounts = [] +env = [] \ No newline at end of file diff --git a/blueprints/bluesky-pds/bluesky-pds.svg b/blueprints/bluesky-pds/bluesky-pds.svg new file mode 100644 index 00000000..77ebea07 --- /dev/null +++ b/blueprints/bluesky-pds/bluesky-pds.svg @@ -0,0 +1,3 @@ + + + diff --git a/blueprints/bluesky-pds/docker-compose.yml b/blueprints/bluesky-pds/docker-compose.yml new file mode 100644 index 00000000..4f9ae9a2 --- /dev/null +++ b/blueprints/bluesky-pds/docker-compose.yml @@ -0,0 +1,48 @@ +services: + pds: + image: 'ghcr.io/bluesky-social/pds:0.4.182' + volumes: + - pds-data:/pds + environment: + - SERVICE_URL_PDS_3000 + - PDS_HOSTNAME + - PDS_JWT_SECRET + - PDS_ADMIN_PASSWORD + - 'PDS_ADMIN_EMAIL=${PDS_ADMIN_EMAIL}' + - PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX + - 'PDS_DATA_DIRECTORY=${PDS_DATA_DIRECTORY:-/pds}' + - 'PDS_BLOBSTORE_DISK_LOCATION=${PDS_DATA_DIRECTORY:-/pds}/blocks' + - 'PDS_BLOB_UPLOAD_LIMIT=${PDS_BLOB_UPLOAD_LIMIT:-104857600}' + - 'PDS_DID_PLC_URL=${PDS_DID_PLC_URL:-https://plc.directory}' + - 'PDS_EMAIL_FROM_ADDRESS=${PDS_EMAIL_FROM_ADDRESS}' + - 'PDS_EMAIL_SMTP_URL=${PDS_EMAIL_SMTP_URL}' + - 'PDS_BSKY_APP_VIEW_URL=${PDS_BSKY_APP_VIEW_URL:-https://api.bsky.app}' + - 'PDS_BSKY_APP_VIEW_DID=${PDS_BSKY_APP_VIEW_DID:-did:web:api.bsky.app}' + - 'PDS_REPORT_SERVICE_URL=${PDS_REPORT_SERVICE_URL:-https://mod.bsky.app/xrpc/com.atproto.moderation.createReport}' + - 'PDS_REPORT_SERVICE_DID=${PDS_REPORT_SERVICE_DID:-did:plc:ar7c4by46qjdydhdevvrndac}' + - 'PDS_CRAWLERS=${PDS_CRAWLERS:-https://bsky.network}' + - 'LOG_ENABLED=${LOG_ENABLED:-true}' + command: | + sh -c ' + set -euo pipefail + echo "Installing required packages and pdsadmin..." + apk add --no-cache openssl curl bash jq coreutils gnupg util-linux-misc >/dev/null + curl -o /usr/local/bin/pdsadmin.sh https://raw.githubusercontent.com/bluesky-social/pds/main/pdsadmin.sh + chmod 700 /usr/local/bin/pdsadmin.sh + ln -sf /usr/local/bin/pdsadmin.sh /usr/local/bin/pdsadmin + echo "Creating an empty pds.env file so pdsadmin works..." + touch /pds/pds.env + echo "Launching PDS, enjoy!..." + exec node --enable-source-maps index.js + ' + healthcheck: + test: + - CMD + - wget + - '--spider' + - 'http://127.0.0.1:3000/xrpc/_health' + interval: 5s + timeout: 10s + retries: 10 +volumes: + pds-data: \ No newline at end of file diff --git a/blueprints/bluesky-pds/template.toml b/blueprints/bluesky-pds/template.toml new file mode 100644 index 00000000..3de5b201 --- /dev/null +++ b/blueprints/bluesky-pds/template.toml @@ -0,0 +1,36 @@ +[variables] +main_domain = "${domain}" +admin_password = "${password:32}" +jwt_secret = "${jwt:32}" +rotation_key = "${jwt:32}" +data_directory = "/pds" +blob_upload_limit = "104857600" +log_enabled = "true" + +[config] +mounts = [] +env = [ + "PDS_ADMIN_PASSWORD=${admin_password}", + "PDS_HOSTNAME=${main_domain}", + "PDS_JWT_SECRET=${jwt_secret}", + "PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX=${rotation_key}", + "PDS_ADMIN_EMAIL=", + "PDS_EMAIL_FROM_ADDRESS=", + "PDS_EMAIL_SMTP_URL=", + "PDS_DATA_DIRECTORY=${data_directory}", + "PDS_BLOBSTORE_DISK_LOCATION=${data_directory}/blocks", + "PDS_BLOB_UPLOAD_LIMIT=${blob_upload_limit}", + "PDS_DID_PLC_URL=https://plc.directory", + "PDS_BSKY_APP_VIEW_URL=https://api.bsky.app", + "PDS_BSKY_APP_VIEW_DID=did:web:api.bsky.app", + "PDS_REPORT_SERVICE_URL=https://mod.bsky.app/xrpc/com.atproto.moderation.createReport", + "PDS_REPORT_SERVICE_DID=did:plc:ar7c4by46qjdydhdevvrndac", + "PDS_CRAWLERS=https://bsky.network", + "LOG_ENABLED=${log_enabled}" +] + +[[config.domains]] +serviceName = "pds" +port = 3000 +host = "${main_domain}" +path = "/" \ No newline at end of file diff --git a/blueprints/budibase/docker-compose.yml b/blueprints/budibase/docker-compose.yml index 620324dc..92ad3288 100644 --- a/blueprints/budibase/docker-compose.yml +++ b/blueprints/budibase/docker-compose.yml @@ -182,9 +182,6 @@ services: labels: - com.centurylinklabs.watchtower.enable=false -networks: - dokploy-network: - external: true volumes: minio_data: diff --git a/blueprints/chatwoot/docker-compose.yml b/blueprints/chatwoot/docker-compose.yml index ece9ef44..a43b43f7 100644 --- a/blueprints/chatwoot/docker-compose.yml +++ b/blueprints/chatwoot/docker-compose.yml @@ -4,8 +4,6 @@ x-base-config: &base-config image: chatwoot/chatwoot:v4.0.3 volumes: - chatwoot-storage:/app/storage - networks: - - dokploy-network environment: - FRONTEND_URL=${FRONTEND_URL} - SECRET_KEY_BASE=${SECRET_KEY_BASE} @@ -63,10 +61,6 @@ services: volumes: - chatwoot-redis-data:/data -networks: - dokploy-network: - external: true - volumes: chatwoot-storage: chatwoot-postgres-data: diff --git a/blueprints/chirpstack/chirpstack.png b/blueprints/chirpstack/chirpstack.png new file mode 100644 index 00000000..b84e845f Binary files /dev/null and b/blueprints/chirpstack/chirpstack.png differ diff --git a/blueprints/chirpstack/docker-compose.yml b/blueprints/chirpstack/docker-compose.yml new file mode 100644 index 00000000..85b32a12 --- /dev/null +++ b/blueprints/chirpstack/docker-compose.yml @@ -0,0 +1,81 @@ +services: + chirpstack: + image: chirpstack/chirpstack:4 + command: -c /etc/chirpstack + restart: unless-stopped + volumes: + - ../files/chirpstack:/etc/chirpstack + ports: + - 8080 + environment: + - MQTT_BROKER_HOST=mosquitto + - REDIS_HOST=redis + - POSTGRESQL_HOST=postgres + depends_on: + - postgres + - mosquitto + - redis + + chirpstack-gateway-bridge: + image: chirpstack/chirpstack-gateway-bridge:4 + restart: unless-stopped + volumes: + - ../files/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge + ports: + - 1700/udp + environment: + - INTEGRATION__MQTT__EVENT_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/event/{{ .EventType }} + - INTEGRATION__MQTT__STATE_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/state/{{ .StateType }} + - INTEGRATION__MQTT__COMMAND_TOPIC_TEMPLATE=eu868/gateway/{{ .GatewayID }}/command/# + depends_on: + - mosquitto + + chirpstack-gateway-bridge-basicstation: + image: chirpstack/chirpstack-gateway-bridge:4 + command: -c /etc/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-eu868.toml + restart: unless-stopped + volumes: + - ../files/chirpstack-gateway-bridge:/etc/chirpstack-gateway-bridge + ports: + - 3001 + depends_on: + - mosquitto + + chirpstack-rest-api: + image: chirpstack/chirpstack-rest-api:4 + restart: unless-stopped + command: --server chirpstack:8080 --bind 0.0.0.0:8090 --insecure + ports: + - 8090 + depends_on: + - chirpstack + + postgres: + image: postgres:14-alpine + restart: unless-stopped + volumes: + - postgresqldata:/var/lib/postgresql/data + - ../files/postgresql/initdb:/docker-entrypoint-initdb.d + environment: + - POSTGRES_USER=chirpstack + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=chirpstack + + redis: + image: redis:7-alpine + restart: unless-stopped + command: redis-server --save 300 1 --save 60 100 --appendonly no + volumes: + - redisdata:/data + + mosquitto: + image: eclipse-mosquitto:2 + restart: unless-stopped + volumes: + - ../files/mosquitto/config/:/mosquitto/config/ + ports: + - 1883 + +volumes: + postgresqldata: + redisdata: diff --git a/blueprints/chirpstack/template.toml b/blueprints/chirpstack/template.toml new file mode 100644 index 00000000..cc5bf3ac --- /dev/null +++ b/blueprints/chirpstack/template.toml @@ -0,0 +1,9815 @@ +[variables] +main_domain = "${domain}" +api_secret = "${base64:32}" +postgres_password = "${password:32}" + +[config] +[[config.domains]] +serviceName = "chirpstack" +port = 8080 +host = "${main_domain}" +path = "/" + +[[config.domains]] +serviceName = "chirpstack-rest-api" +port = 8090 +host = "api-${main_domain}" +path = "/" + +[config.env] +POSTGRES_PASSWORD = "${postgres_password}" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/chirpstack.toml" +content = """ +# Logging. +[logging] + + # Log level. + # + # Options are: trace, debug, info, warn error. + level="info" + + +# PostgreSQL configuration. +[postgresql] + + # PostgreSQL DSN. + # + # Format example: postgres://:@/?sslmode=. + # + # SSL mode options: + # * disable - Do not use TLS + # * prefer - Attempt to connect with TLS but allow sessions without + # * require - Require the use of TLS + dsn="postgres://chirpstack:${postgres_password}@postgres/chirpstack?sslmode=disable" + + # Max open connections. + # + # This sets the max. number of open connections that are allowed in the + # PostgreSQL connection pool. + max_open_connections=10 + + # Min idle connections. + # + # This sets the min. number of idle connections in the PostgreSQL connection + # pool (0 = equal to max_open_connections). + min_idle_connections=0 + + +# Redis configuration. +[redis] + + # Server address or addresses. + # + # Set multiple addresses when connecting to a cluster. + servers=[ + "redis://redis/", + ] + + # TLS enabled. + tls_enabled=false + + # Redis Cluster. + # + # Set this to true when the provided URLs are pointing to a Redis Cluster + # instance. + cluster=false + + +# Network related configuration. +[network] + + # Network identifier (NetID, 3 bytes) encoded as HEX (e.g. 010203). + net_id="000000" + + # Enabled regions. + # + # Multiple regions can be enabled simultaneously. Each region must match + # the 'name' parameter of the region configuration in '[[regions]]'. + enabled_regions=[ + "as923", + "as923_2", + "as923_3", + "as923_4", + "au915_0", + "cn470_10", + "cn779", + "eu433", + "eu868", + "in865", + "ism2400", + "kr920", + "ru864", + "us915_0", + "us915_1", + ] + + +# API interface configuration. +[api] + + # interface:port to bind the API interface to. + bind="0.0.0.0:8080" + + # Secret. + # + # This secret is used for generating login and API tokens, make sure this + # is never exposed. Changing this secret will invalidate all login and API + # tokens. The following command can be used to generate a random secret: + # openssl rand -base64 32 + secret="${api_secret}" + + +[integration] + enabled=["mqtt"] + + [integration.mqtt] + server="tcp://mosquitto:1883/" + json=true +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_as923_2.toml" +content = """ +# This file contains an example AS923_2 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923_2" + + # Description is a short description for this region. + description="AS923-2" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923_2" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=921400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=921400000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_as923_3.toml" +content = """ +# This file contains an example AS923_3 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923_3" + + # Description is a short description for this region. + description="AS923-3" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923_3" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=916600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=916600000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_as923_4.toml" +content = """ +# This file contains an example AS923_4 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923_4" + + # Description is a short description for this region. + description="AS923-4" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923_4" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=917300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=917300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_as923.toml" +content = """ +# This file contains an example AS923 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="as923" + + # Description is a short description for this region. + description="AS923" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AS923" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="as923" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=923200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=923200000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_0.toml" +content = """ +# This file contains an example AU915 example (channels 0-7 + 64). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_0" + + # Description is a short description for this region. + description="AU915 (channels 0-7 + 64)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_0" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=915200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=916600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=915900000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[0, 1, 2, 3, 4, 5, 6, 7, 64] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_1.toml" +content = """ +# This file contains an example AU915 example (channels 8-15 + 65). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_1" + + # Description is a short description for this region. + description="AU915 (channels 8-15 + 65)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_1" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=916800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=917500000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[8, 9, 10, 11, 12, 13, 14, 15, 65] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_2.toml" +content = """ +# This file contains an example AU915 example (channels 16-23 + 66). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_2" + + # Description is a short description for this region. + description="AU915 (channels 16-23 + 65)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=918400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=918800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=919100000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[16, 17, 18, 19, 20, 21, 22, 23, 65] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_3.toml" +content = """ +# This file contains an example AU915 example (channels 24-31 + 67). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_3" + + # Description is a short description for this region. + description="AU915 (channels 24-31 + 67)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=920000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=920700000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[24, 25, 26, 27, 28, 29, 30, 31, 67] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_4.toml" +content = """ +# This file contains an example AU915 example (channels 32-39 + 68). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_4" + + # Description is a short description for this region. + description="AU915 (channels 32-39 + 68)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=921600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=921800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922300000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[32, 33, 34, 35, 36, 37, 38, 39, 68] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_5.toml" +content = """ +# This file contains an example AU915 example (channels 40-47 + 69). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_5" + + # Description is a short description for this region. + description="AU915 (channels 40-47 + 69)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_5" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=923200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=924600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=923900000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[40, 41, 42, 43, 44, 45, 46, 47, 69] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_6.toml" +content = """ +# This file contains an example AU915 example (channels 48-55 + 70). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_6" + + # Description is a short description for this region. + description="AU915 (channels 48-55 + 70)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_6" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=924800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=925500000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[48, 49, 50, 51, 52, 53, 54, 55, 70] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_au915_7.toml" +content = """ +# This file contains an example AU915 example (channels 56-63 + 71). +[[regions]] + + # ID is an use-defined identifier for this region. + id="au915_7" + + # Description is a short description for this region. + description="AU915 (channels 56-63 + 71)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="AU915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="au915_7" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=926400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=926800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927000000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927200000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927400000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927600000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927800000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=927100000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[56, 57, 58, 59, 60, 61, 62, 63, 71] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_0.toml" +content = """ +# This file contains an example CN470 example (channels 0-7). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_0" + + # Description is a short description for this region. + description="CN470 (channels 0-7)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_0" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=470300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=470500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=470700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=470900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=471700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[0, 1, 2, 3, 4, 5, 6, 7] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_10.toml" +content = """ +# This file contains an example CN470 example (channels 80-87). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_10" + + # Description is a short description for this region. + description="CN470 (channels 80-87)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_10" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=486300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=487700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[80, 81, 82, 83, 84, 85, 86, 87] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_11.toml" +content = """ +# This file contains an example CN470 example (channels 88-95). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_11" + + # Description is a short description for this region. + description="CN470 (channels 88-95)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_11" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=487900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=488900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=489100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=489300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[88, 89, 90, 91, 92, 93, 94, 95] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_1.toml" +content = """ +# This file contains an example CN470 example (channels 8-15). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_1" + + # Description is a short description for this region. + description="CN470 (channels 8-15)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_1" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=471900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=472900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[8, 9, 10, 11, 12, 13, 14, 15] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_2.toml" +content = """ +# This file contains an example CN470 example (channels 16-23). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_2" + + # Description is a short description for this region. + description="CN470 (channels 16-23)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=473500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=473900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=474900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[16, 17, 18, 19, 20, 21, 22, 23] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_3.toml" +content = """ +# This file contains an example CN470 example (channels 24-31). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_3" + + # Description is a short description for this region. + description="CN470 (channels 24-31)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=475100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=475900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[24, 25, 26, 27, 28, 29, 30, 31] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_4.toml" +content = """ +# This file contains an example CN470 example (channels 32-39). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_4" + + # Description is a short description for this region. + description="CN470 (channels 32-39)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=476700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=476900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=477900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[32, 33, 34, 35, 36, 37, 38, 39] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_5.toml" +content = """ +# This file contains an example CN470 example (channels 40-47). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_5" + + # Description is a short description for this region. + description="CN470 (channels 40-47)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_5" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=478300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=478900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=479700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[40, 41, 42, 43, 44, 45, 46, 47] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_6.toml" +content = """ +# This file contains an example CN470 example (channels 48-55). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_6" + + # Description is a short description for this region. + description="CN470 (channels 48-55)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_6" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=479900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=480900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[48, 49, 50, 51, 52, 53, 54, 55] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_7.toml" +content = """ +# This file contains an example CN470 example (channels 56-63). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_7" + + # Description is a short description for this region. + description="CN470 (channels 56-63)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_7" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=481500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=481900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=482900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[56, 57, 58, 59, 60, 61, 62, 63] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_8.toml" +content = """ +# This file contains an example CN470 example (channels 64-71). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_8" + + # Description is a short description for this region. + description="CN470 (channels 64-71)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_8" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=483100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=483900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[64, 65, 66, 67, 68, 69, 70, 71] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn470_9.toml" +content = """ +# This file contains an example CN470 example (channels 72-79). +[[regions]] + + # ID is an use-defined identifier for this region. + id="cn470_9" + + # Description is a short description for this region. + description="CN470 (channels 72-79)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN470" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn470_9" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=484700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=484900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=485900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=486100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=505300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[72, 73, 74, 75, 76, 77, 78, 79] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=2 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_cn779.toml" +content = """ +# This file contains an example CN779 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="cn779" + + # Description is a short description for this region. + description="CN779" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="CN779" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="cn779" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=779500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=779700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=779900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=786000000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_eu433.toml" +content = """ +# This file contains an example EU433 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="eu433" + + # Description is a short description for this region. + description="EU443" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="EU433" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="eu433" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=433175000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=433375000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=433575000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=434665000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_eu868.toml" +content = """ +# This file contains an example EU868 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="eu868" + + # Description is a short description for this region. + description="EU868" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="EU868" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="eu868" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=868100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=868300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=868500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=867900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=868300000 + bandwidth=250000 + modulation="LORA" + spreading_factors=[7] + + [[regions.gateway.channels]] + frequency=868800000 + bandwidth=125000 + modulation="FSK" + datarate=50000 + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=869525000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 + + + # Below is the common set of extra channels. Please make sure that these + # channels are also supported by the gateways. + [[regions.network.extra_channels]] + frequency=867100000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867300000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867500000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867700000 + min_dr=0 + max_dr=5 + + [[regions.network.extra_channels]] + frequency=867900000 + min_dr=0 + max_dr=5 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_in865.toml" +content = """ +# This file contains an example IN865 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="in865" + + # Description is a short description for this region. + description="IN865" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="IN865" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="in865" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=865062500 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=865402500 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=865985000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=2 + + # RX2 frequency (Hz) + rx2_frequency=866550000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=4 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_ism2400.toml" +content = """ +# This file contains an example ISM2400 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="ism2400" + + # Description is a short description for this region. + description="ISM2400" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="ISM2400" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="ism2400" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=2403000000 + bandwidth=812000 + modulation="LORA" + spreading_factors=[12] + + [[regions.gateway.channels]] + frequency=2479000000 + bandwidth=812000 + modulation="LORA" + spreading_factors=[12] + + [[regions.gateway.channels]] + frequency=2425000000 + bandwidth=812000 + modulation="LORA" + spreading_factors=[12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=2423000000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=7 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=0 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_kr920.toml" +content = """ +# This file contains an example KR920 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="kr920" + + # Description is a short description for this region. + description="KR920" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="KR920" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="kr920" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=922100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=922500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=921900000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_ru864.toml" +content = """ +# This file contains an example RU864 configuration. +[[regions]] + + # ID is an user-defined identifier for this region. + id="ru864" + + # Description is a short description for this region. + description="RU864" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="RU864" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="ru864" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=868900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + [[regions.gateway.channels]] + frequency=869100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10, 11, 12] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=0 + + # RX2 frequency (Hz) + rx2_frequency=869100000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=5 + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=3 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_0.toml" +content = """ +# This file contains an example US915 example (channels 0-7 + 64). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_0" + + # Description is a short description for this region. + description="US915 (channels 0-7 + 64)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_0" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=902300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=902500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=902700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=902900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=903000000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[0, 1, 2, 3, 4, 5, 6, 7, 64] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_1.toml" +content = """ +# This file contains an example US915 example (channels 8-15 + 65). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_1" + + # Description is a short description for this region. + description="US915 (channels 8-15 + 65)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_1" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=903900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=904600000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[8, 9, 10, 11, 12, 13, 14, 15, 65] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_2.toml" +content = """ +# This file contains an example US915 example (channels 16-23 + 66). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_2" + + # Description is a short description for this region. + description="US915 (channels 16-23 + 66)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_2" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=905500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=905900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=906200000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[16, 17, 18, 19, 20, 21, 22, 23, 66] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_3.toml" +content = """ +# This file contains an example US915 example (channels 24-31 + 67). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_3" + + # Description is a short description for this region. + description="US915 (channels 24-31 + 67)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_3" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=907100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=907800000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[24, 25, 26, 27, 28, 29, 30, 31, 67] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_4.toml" +content = """ +# This file contains an example US915 example (channels 32-39 + 68). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_4" + + # Description is a short description for this region. + description="US915 (channels 32-39 + 68)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_4" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=908700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=908900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=909400000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[32, 33, 34, 35, 36, 37, 38, 39, 68] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_5.toml" +content = """ +# This file contains an example US915 example (channels 40-47 + 69). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_5" + + # Description is a short description for this region. + description="US915 (channels 40-47 + 69)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_5" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=910300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=910900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=911000000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[40, 41, 42, 43, 44, 45, 46, 47, 69] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_6.toml" +content = """ +# This file contains an example US915 example (channels 48-55 + 70). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_6" + + # Description is a short description for this region. + description="US915 (channels 48-55 + 70)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_6" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=911900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=912600000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[48, 49, 50, 51, 52, 53, 54, 55, 70] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack" +filePath = "/chirpstack/region_us915_7.toml" +content = """ +# This file contains an example US915 example (channels 56-63 + 71). +[[regions]] + + # ID is an use-defined identifier for this region. + id="us915_7" + + # Description is a short description for this region. + description="US915 (channels 56-63 + 71)" + + # Common-name refers to the common-name of this region as defined by + # the LoRa Alliance. + common_name="US915" + + + # Gateway configuration. + [regions.gateway] + + # Force gateways as private. + # + # If enabled, gateways can only be used by devices under the same tenant. + force_gws_private=false + + + # Gateway backend configuration. + [regions.gateway.backend] + + # The enabled backend type. + enabled="mqtt" + + # MQTT configuration. + [regions.gateway.backend.mqtt] + + # Topic prefix. + # + # The topic prefix can be used to define the region of the gateway. + # Note, there is no need to add a trailing '/' to the prefix. The trailing + # '/' is automatically added to the prefix if it is configured. + topic_prefix="us915_7" + + # MQTT server (e.g. scheme://host:port where scheme is tcp, ssl or ws) + server="tcp://mosquitto:1883" + + # Connect with the given username (optional) + username="" + + # Connect with the given password (optional) + password="" + + # Quality of service level + # + # 0: at most once + # 1: at least once + # 2: exactly once + # + # Note: an increase of this value will decrease the performance. + # For more information: https://www.hivemq.com/blog/mqtt-essentials-part-6-mqtt-quality-of-service-levels + qos=0 + + # Clean session + # + # Set the "clean session" flag in the connect message when this client + # connects to an MQTT broker. By setting this flag you are indicating + # that no messages saved by the broker for this client should be delivered. + clean_session=false + + # Client ID + # + # Set the client id to be used by this client when connecting to the MQTT + # broker. A client id must be no longer than 23 characters. If left blank, + # a random id will be generated by ChirpStack. + client_id="" + + # Keep alive interval. + # + # This defines the maximum time that that should pass without communication + # between the client and server. + keep_alive_interval="30s" + + # CA certificate file (optional) + # + # Use this when setting up a secure connection (when server uses ssl://...) + # but the certificate used by the server is not trusted by any CA certificate + # on the server (e.g. when self generated). + ca_cert="" + + # TLS certificate file (optional) + tls_cert="" + + # TLS key file (optional) + tls_key="" + + + # Gateway channel configuration. + # + # Note: this configuration is only used in case the gateway is using the + # ChirpStack Concentratord daemon. In any other case, this configuration + # is ignored. + [[regions.gateway.channels]] + frequency=913500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=913900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914100000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914300000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914500000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914700000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914900000 + bandwidth=125000 + modulation="LORA" + spreading_factors=[7, 8, 9, 10] + + [[regions.gateway.channels]] + frequency=914200000 + bandwidth=500000 + modulation="LORA" + spreading_factors=[8] + + + # Region specific network configuration. + [regions.network] + + # Installation margin (dB) used by the ADR engine. + # + # A higher number means that the network-server will keep more margin, + # resulting in a lower data-rate but decreasing the chance that the + # device gets disconnected because it is unable to reach one of the + # surrounded gateways. + installation_margin=10 + + # RX window (Class-A). + # + # Set this to: + # 0: RX1 / RX2 + # 1: RX1 only + # 2: RX2 only + rx_window=0 + + # RX1 delay (1 - 15 seconds). + rx1_delay=1 + + # RX1 data-rate offset + rx1_dr_offset=0 + + # RX2 data-rate + rx2_dr=8 + + # RX2 frequency (Hz) + rx2_frequency=923300000 + + # Prefer RX2 on RX1 data-rate less than. + # + # Prefer RX2 over RX1 based on the RX1 data-rate. When the RX1 data-rate + # is smaller than the configured value, then the Network Server will + # first try to schedule the downlink for RX2, failing that (e.g. the gateway + # has already a payload scheduled at the RX2 timing) it will try RX1. + rx2_prefer_on_rx1_dr_lt=0 + + # Prefer RX2 on link budget. + # + # When the link-budget is better for RX2 than for RX1, the Network Server will first + # try to schedule the downlink in RX2, failing that it will try RX1. + rx2_prefer_on_link_budget=false + + # Downlink TX Power (dBm) + # + # When set to -1, the downlink TX Power from the configured band will + # be used. + # + # Please consult the LoRaWAN Regional Parameters and local regulations + # for valid and legal options. Note that the configured TX Power must be + # supported by your gateway(s). + downlink_tx_power=-1 + + # ADR is disabled. + adr_disabled=false + + # Minimum data-rate. + min_dr=0 + + # Maximum data-rate. + max_dr=3 + + # Enabled uplink channels. + # + # Use this when ony a sub-set of the by default enabled channels are being + # used. For example when only using the first 8 channels of the US band. + # Note: when left blank / empty array, all channels will be enabled. + enabled_uplink_channels=[56, 57, 58, 59, 60, 61, 62, 63, 71] + + + # Rejoin-request configuration (LoRaWAN 1.1) + [regions.network.rejoin_request] + + # Request devices to periodically send rejoin-requests. + enabled=false + + # The device must send a rejoin-request type 0 at least every 2^(max_count_n + 4) + # uplink messages. Valid values are 0 to 15. + max_count_n=0 + + # The device must send a rejoin-request type 0 at least every 2^(max_time_n + 10) + # seconds. Valid values are 0 to 15. + # + # 0 = roughly 17 minutes + # 15 = about 1 year + max_time_n=0 + + + # Class-B configuration. + [regions.network.class_b] + + # Ping-slot data-rate. + ping_slot_dr=8 + + # Ping-slot frequency (Hz) + # + # set this to 0 to use the default frequency plan for the configured region + # (which could be frequency hopping). + ping_slot_frequency=0 +""" + +[[config.mounts]] +serviceName = "chirpstack-gateway-bridge" +filePath = "/chirpstack-gateway-bridge/chirpstack-gateway-bridge.toml" +content = """ +# See https://www.chirpstack.io/gateway-bridge/install/config/ for a full +# configuration example and documentation. + +[integration.mqtt.auth.generic] +servers=["tcp://mosquitto:1883"] +username="" +password="" +""" + +[[config.mounts]] +serviceName = "chirpstack-gateway-bridge-basicstation" +filePath = "/chirpstack-gateway-bridge/chirpstack-gateway-bridge-basicstation-eu868.toml" +content = """ +# See https://www.chirpstack.io/gateway-bridge/install/config/ for a full +# configuration example and documentation. + +[integration.mqtt.auth.generic] +servers=["tcp://mosquitto:1883"] +username="" +password="" + +[integration.mqtt] +event_topic_template="eu868/gateway/{{ .GatewayID }}/event/{{ .EventType }}" +state_topic_template="eu868/gateway/{{ .GatewayID }}/state/{{ .StateType }}" +command_topic_template="eu868/gateway/{{ .GatewayID }}/command/#" + +[backend] +type="basic_station" + + [backend.basic_station] + bind=":3001" + tls_cert="" + tls_key="" + ca_cert="" + + region="EU868" + frequency_min=863000000 + frequency_max=870000000 + + + [[backend.basic_station.concentrators]] + + [backend.basic_station.concentrators.multi_sf] + frequencies=[ + 868100000, + 868300000, + 868500000, + 867100000, + 867300000, + 867500000, + 867700000, + 867900000, + ] + + [backend.basic_station.concentrators.lora_std] + frequency=868300000 + bandwidth=250000 + spreading_factor=7 + + [backend.basic_station.concentrators.fsk] + frequency=868800000 +""" + +[[config.mounts]] +serviceName = "mosquitto" +filePath = "/mosquitto/config/mosquitto.conf" +content = """ +listener 1883 +allow_anonymous true +""" + +[[config.mounts]] +serviceName = "postgres" +filePath = "/postgresql/initdb/001-chirpstack_extensions.sh" +content = """ +#!/bin/bash +set -e + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname="$POSTGRES_DB" <<-EOSQL + create extension pg_trgm; + create extension hstore; +EOSQL +""" diff --git a/blueprints/conduit/docker-compose.yml b/blueprints/conduit/docker-compose.yml index f2f1fb34..8f774673 100644 --- a/blueprints/conduit/docker-compose.yml +++ b/blueprints/conduit/docker-compose.yml @@ -7,8 +7,6 @@ services: restart: unless-stopped volumes: - db:/var/lib/matrix-conduit/ - networks: - - dokploy-network environment: CONDUIT_SERVER_NAME: ${MATRIX_SUBDOMAIN} CONDUIT_DATABASE_PATH: /var/lib/matrix-conduit/ @@ -25,7 +23,3 @@ services: CONDUIT_CONFIG: '' # Ignore this volumes: db: - -networks: - dokploy-network: - external: true diff --git a/blueprints/discord-tickets/docker-compose.yml b/blueprints/discord-tickets/docker-compose.yml index f797a77b..62105b3a 100644 --- a/blueprints/discord-tickets/docker-compose.yml +++ b/blueprints/discord-tickets/docker-compose.yml @@ -45,10 +45,6 @@ services: PUBLISH_COMMANDS: "true" SUPER: ${SUPER_USERS} -networks: - dokploy-network: - external: true - volumes: tickets-mysql-data: tickets-app-data: \ No newline at end of file diff --git a/blueprints/docmost/docker-compose.yml b/blueprints/docmost/docker-compose.yml index b5995594..d7efba92 100644 --- a/blueprints/docmost/docker-compose.yml +++ b/blueprints/docmost/docker-compose.yml @@ -34,10 +34,6 @@ services: volumes: - redis_docmost_data:/data -networks: - dokploy-network: - external: true - volumes: docmost: db_docmost_data: diff --git a/blueprints/dokploy-prom-monitoring-extension/docker-compose.yml b/blueprints/dokploy-prom-monitoring-extension/docker-compose.yml new file mode 100644 index 00000000..1fd3e03d --- /dev/null +++ b/blueprints/dokploy-prom-monitoring-extension/docker-compose.yml @@ -0,0 +1,11 @@ +services: + dokploy-monitoring: + image: dokploy/monitoring:canary + restart: unless-stopped + env_file: + - .env + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + - monitoring-data:/app/data +volumes: + monitoring-data: {} diff --git a/blueprints/dokploy-prom-monitoring-extension/logo.svg b/blueprints/dokploy-prom-monitoring-extension/logo.svg new file mode 100644 index 00000000..5c6a02e4 --- /dev/null +++ b/blueprints/dokploy-prom-monitoring-extension/logo.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + diff --git a/blueprints/dokploy-prom-monitoring-extension/template.toml b/blueprints/dokploy-prom-monitoring-extension/template.toml new file mode 100644 index 00000000..bd0c07b5 --- /dev/null +++ b/blueprints/dokploy-prom-monitoring-extension/template.toml @@ -0,0 +1,17 @@ +[variables] +main_domain = "${domain}" +monitoring_token = "${password:32}" +callback_url = "http://dokploy:3000/api/trpc/notification.receiveNotification" +server_type = "Dokploy" +refresh_rate = "30" +retention_days = "7" +cpu_threshold = "80" +memory_threshold = "85" + +[[config.domains]] +serviceName = "dokploy-monitoring" +port = 3001 +host = "${main_domain}" + +[config.env] +METRICS_CONFIG = "{\"server\":{\"refreshRate\":${refresh_rate},\"port\":3001,\"type\":\"${server_type}\",\"token\":\"${monitoring_token}\",\"urlCallback\":\"${callback_url}\",\"retentionDays\":${retention_days},\"cronJob\":\"0 0 * * *\",\"thresholds\":{\"cpu\":${cpu_threshold},\"memory\":${memory_threshold}},\"prometheus\":{\"enabled\":true}},\"containers\":{\"refreshRate\":${refresh_rate},\"services\":{\"include\":[],\"exclude\":[]}}}" diff --git a/blueprints/drawio/docker-compose.yml b/blueprints/drawio/docker-compose.yml index a7d7b578..cdd036d9 100644 --- a/blueprints/drawio/docker-compose.yml +++ b/blueprints/drawio/docker-compose.yml @@ -51,9 +51,5 @@ services: DRAWIO_GITLAB_SECRET: ${DRAWIO_GITLAB_SECRET} DRAWIO_GITLAB_URL: ${DRAWIO_GITLAB_URL} DRAWIO_CLOUD_CONVERT_APIKEY: ${DRAWIO_CLOUD_CONVERT_APIKEY} -networks: - dokploy-network: - external: true - volumes: fonts_volume: \ No newline at end of file diff --git a/blueprints/enshrouded/docker-compose.yml b/blueprints/enshrouded/docker-compose.yml index 9c92efb3..614dd36e 100644 --- a/blueprints/enshrouded/docker-compose.yml +++ b/blueprints/enshrouded/docker-compose.yml @@ -1,18 +1,25 @@ services: enshrouded: - image: sknnr/enshrouded-dedicated-server:latest + image: mornedhels/enshrouded-server:latest + container_name: enshrouded + hostname: enshrouded restart: unless-stopped + stop_grace_period: 90s ports: - "15637:15637/udp" - "27015:27015/udp" + volumes: + - enshrouded-persistent-data:/opt/enshrouded + # only add ntsync device if your kernel supports it (6.14 or newer) + # devices: + # - /dev/ntsync:/dev/ntsync environment: - SERVER_NAME=${SERVER_NAME} - SERVER_PASSWORD=${SERVER_PASSWORD} - - PORT=15637 - - SERVER_SLOTS=6 - - SERVER_IP=0.0.0.0 - volumes: - - enshrouded-persistent-data:/home/steam/enshrouded/savegame + - SERVER_SLOT_COUNT=6 + - UPDATE_CRON=0 3 * * * + - PUID=4711 + - PGID=4711 volumes: enshrouded-persistent-data: \ No newline at end of file diff --git a/blueprints/evolutionapi/docker-compose.yml b/blueprints/evolutionapi/docker-compose.yml index d4803de1..5807ff82 100644 --- a/blueprints/evolutionapi/docker-compose.yml +++ b/blueprints/evolutionapi/docker-compose.yml @@ -47,11 +47,6 @@ services: volumes: - evolution-redis-data:/data - -networks: - dokploy-network: - external: true - volumes: evolution-instances: evolution-postgres-data: diff --git a/blueprints/firecrawl/docker-compose.yml b/blueprints/firecrawl/docker-compose.yml index f4181cfc..d7622f7a 100644 --- a/blueprints/firecrawl/docker-compose.yml +++ b/blueprints/firecrawl/docker-compose.yml @@ -124,15 +124,6 @@ services: interval: 10s timeout: 5s retries: 10 - networks: - - backend - - dokploy-network - -networks: - backend: - driver: bridge - dokploy-network: - external: true volumes: nuq_pg_data: \ No newline at end of file diff --git a/blueprints/glpi/docker-compose.yml b/blueprints/glpi/docker-compose.yml index fa732fa3..3abe1f05 100644 --- a/blueprints/glpi/docker-compose.yml +++ b/blueprints/glpi/docker-compose.yml @@ -20,7 +20,3 @@ services: volumes: glpi-mysql-data: glpi-www-data: - -networks: - dokploy-network: - external: true \ No newline at end of file diff --git a/blueprints/hi-events/docker-compose.yml b/blueprints/hi-events/docker-compose.yml index cce45fec..3c2291b9 100644 --- a/blueprints/hi-events/docker-compose.yml +++ b/blueprints/hi-events/docker-compose.yml @@ -36,9 +36,5 @@ services: volumes: - pg_hi-events_data:/var/lib/postgresql/data -networks: - dokploy-network: - external: true - volumes: pg_hi-events_data: \ No newline at end of file diff --git a/blueprints/immich/docker-compose.yml b/blueprints/immich/docker-compose.yml index cdd31199..8f12d6d1 100644 --- a/blueprints/immich/docker-compose.yml +++ b/blueprints/immich/docker-compose.yml @@ -96,10 +96,6 @@ services: ] restart: always -networks: - dokploy-network: - external: true - volumes: immich-model-cache: immich-postgres: diff --git a/blueprints/infisical/docker-compose.yml b/blueprints/infisical/docker-compose.yml index 7566c898..ac5718bc 100644 --- a/blueprints/infisical/docker-compose.yml +++ b/blueprints/infisical/docker-compose.yml @@ -3,7 +3,7 @@ services: depends_on: db: condition: service_healthy - image: infisical/infisical:v0.90.1-postgres + image: infisical/infisical:v0.135.0-postgres environment: - NODE_ENV=production - ENCRYPTION_KEY @@ -20,7 +20,6 @@ services: command: npm run migration:latest pull_policy: always - backend: restart: unless-stopped depends_on: @@ -30,7 +29,7 @@ services: condition: service_started db-migration: condition: service_completed_successfully - image: infisical/infisical:v0.90.1-postgres + image: infisical/infisical:v0.135.0-postgres pull_policy: always environment: - NODE_ENV=production @@ -77,7 +76,5 @@ volumes: pg_infisical_data: redis_infisical_data: -networks: - dokploy-network: - external: true + diff --git a/blueprints/invoiceshelf/docker-compose.yml b/blueprints/invoiceshelf/docker-compose.yml index 0f1c3d2c..8d2c8265 100644 --- a/blueprints/invoiceshelf/docker-compose.yml +++ b/blueprints/invoiceshelf/docker-compose.yml @@ -47,10 +47,6 @@ services: invoiceshelf-postgres: condition: service_healthy -networks: - dokploy-network: - external: true - volumes: invoiceshelf-postgres-data: invoiceshelf-app-data: diff --git a/blueprints/kimai/docker-compose.yml b/blueprints/kimai/docker-compose.yml index d3eab1c3..c97cadfb 100644 --- a/blueprints/kimai/docker-compose.yml +++ b/blueprints/kimai/docker-compose.yml @@ -40,10 +40,6 @@ services: start_period: 30s -networks: - dokploy-network: - external: true - volumes: kimai-data: mysql-data: \ No newline at end of file diff --git a/blueprints/kokoro-tts/docker-compose.yml b/blueprints/kokoro-tts/docker-compose.yml new file mode 100644 index 00000000..a0298ce1 --- /dev/null +++ b/blueprints/kokoro-tts/docker-compose.yml @@ -0,0 +1,23 @@ +services: + kokoro-tts: + build: + context: https://github.com/remsky/Kokoro-FastAPI.git#master + dockerfile: docker/cpu/Dockerfile + restart: unless-stopped + ports: + - 8880 + environment: + - MODEL_PATH=/app/models + - DEVICE=${DEVICE:-cpu} + - HOST=0.0.0.0 + - PORT=8880 + volumes: + - kokoro-models:/app/models + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8880/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s +volumes: + kokoro-models: diff --git a/blueprints/kokoro-tts/kokoro-tts.svg b/blueprints/kokoro-tts/kokoro-tts.svg new file mode 100644 index 00000000..5ed64ed8 --- /dev/null +++ b/blueprints/kokoro-tts/kokoro-tts.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/blueprints/kokoro-tts/template.toml b/blueprints/kokoro-tts/template.toml new file mode 100644 index 00000000..73f367c4 --- /dev/null +++ b/blueprints/kokoro-tts/template.toml @@ -0,0 +1,72 @@ +[variables] +main_domain = "${domain}" +device = "cpu" + +[config] +env = [ + "DEVICE=${device}", + "MODEL_PATH=/app/models", + "HOST=0.0.0.0", + "PORT=8880", + "PYTHONUNBUFFERED=1", + "UV_SYSTEM_PYTHON=1" +] + +[[config.domains]] +serviceName = "kokoro-tts" +port = 8880 +host = "${main_domain}" +path = "/" + +[[config.mounts]] +filePath = "README.md" +content = """# Kokoro TTS FastAPI + +This template provides a Dockerized FastAPI wrapper for the Kokoro-82M text-to-speech model. + +## Features + +- Multi-language support (English, Japanese, Chinese) +- OpenAI-compatible speech endpoint +- CPU and GPU support +- Web interface for monitoring +- RESTful API with comprehensive documentation +- Streaming audio generation +- Word-level timestamps and phonemes + +## Usage + +- **Web Interface**: Access the web UI at `https://${main_domain}/web` +- **API Documentation**: Available at `https://${main_domain}/docs` +- **Health Check**: Monitor service health at `https://${main_domain}/health` + +## Configuration + +The service runs on port 8880 and supports both CPU and GPU inference. +For GPU support, ensure your Dokploy instance has NVIDIA GPU support enabled. + +## API Endpoints + +- `POST /v1/audio/speech` - Generate speech from text (OpenAI compatible) +- `POST /dev/captioned_speech` - Generate speech with timestamps +- `POST /dev/phonemize` - Convert text to phonemes +- `POST /dev/generate_from_phonemes` - Generate audio from phonemes +- `GET /health` - Health check endpoint +- `GET /docs` - Interactive API documentation +- `GET /web` - Web interface + +## Model Information + +- Model: Kokoro-82M +- License: Apache-2.0 +- Repository: https://github.com/remsky/Kokoro-FastAPI +- HuggingFace Model: https://huggingface.co/hexgrad/Kokoro-82M + +## Notes + +- This template builds the image from source during deployment +- Uses CPU-optimized Dockerfile by default +- Initial build may take several minutes due to model download +- Ensure sufficient disk space for model storage +- For GPU support, change dockerfile path to `docker/gpu/Dockerfile` in docker-compose.yml +""" diff --git a/blueprints/kutt/docker-compose.yml b/blueprints/kutt/docker-compose.yml index 5ee1b971..947f4d26 100644 --- a/blueprints/kutt/docker-compose.yml +++ b/blueprints/kutt/docker-compose.yml @@ -7,7 +7,7 @@ services: environment: DB_FILENAME: "/var/lib/kutt/data.sqlite" JWT_SECRET: ${JWT_SECRET} - DEFAULT_DOMAIN: ${DOMAIN} + DEFAULT_DOMAIN: ${DEFAULT_DOMAIN} TRUST_PROXY: ${TRUST_PROXY} DISALLOW_ANONYMOUS_LINKS: ${DISALLOW_ANONYMOUS_LINKS} CUSTOM_DOMAIN_USE_HTTPS: ${CUSTOM_DOMAIN_USE_HTTPS} diff --git a/blueprints/librechat/docker-compose.yml b/blueprints/librechat/docker-compose.yml new file mode 100644 index 00000000..a5a4c5a9 --- /dev/null +++ b/blueprints/librechat/docker-compose.yml @@ -0,0 +1,110 @@ +# LibreChat Docker Compose for Dokploy Template +# Setting up authentication: "npm run create-user", refer to https://www.librechat.ai/docs/configuration/authentication + +services: + librechat: + image: ghcr.io/danny-avila/librechat-dev:latest + restart: always + depends_on: + - mongodb + - rag_api + environment: + # Server Configuration + - HOST=0.0.0.0 + - PORT=${PORT:-3080} + # Domain Configuration + - DOMAIN_CLIENT=${DOMAIN_CLIENT} + - DOMAIN_SERVER=${DOMAIN_SERVER} + # Database and Search Configuration + - MONGO_URI=mongodb://mongodb:27017/LibreChat + - MEILI_HOST=http://meilisearch:7700 + - SEARCH=true + - NO_INDEX=true + - MEILI_NO_ANALYTICS=true + - MEILI_MASTER_KEY=${MEILI_MASTER_KEY} + # Security & Sessions + - JWT_SECRET=${JWT_SECRET} + - JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET} + - CREDS_KEY=${CREDS_KEY} + - CREDS_IV=${CREDS_IV} + - RAG_PORT=${RAG_PORT:-8000} + - RAG_API_URL=http://rag_api:${RAG_PORT:-8000} + # API Keys and Secrets + - OPENAI_API_KEY=${OPENAI_API_KEY} + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} + - OPENROUTER_KEY=${OPENROUTER_KEY} + - GOOGLE_KEY=${GOOGLE_KEY} + - ENDPOINTS=google,openAI,assistants,azureOpenAI,anthropic + # ... Additional Endpoints + # UI + - APP_TITLE=${APP_TITLE:-LibreChat} + - CUSTOM_FOOTER=${CUSTOM_FOOTER:-Made with ❀️ by LibreChat} + - ALLOW_EMAIL_LOGIN=${ALLOW_EMAIL_LOGIN:-true} + - ALLOW_SOCIAL_LOGIN=${ALLOW_SOCIAL_LOGIN:-false} + - ALLOW_REGISTRATION=${ALLOW_REGISTRATION:-false} + volumes: + - type: bind + source: ../files/librechat.yaml + target: /app/librechat.yaml + - librechat_data:/app/client/public/images + - librechat_data:/app/uploads + - librechat_data:/app/logs + + mongodb: + image: mongo + restart: always + volumes: + - mongo_data:/data/db + command: mongod --noauth + + meilisearch: + image: getmeili/meilisearch:v1.12.3 + restart: always + environment: + - MEILI_HOST=http://meilisearch:7700 + - MEILI_NO_ANALYTICS=true + - MEILI_MASTER_KEY=${MEILI_MASTER_KEY} + volumes: + - meili_data:/meili_data + + vectordb: + image: pgvector/pgvector:0.8.0-pg15-trixie + environment: + - POSTGRES_DB=${POSTGRES_DB:-mydatabase} + - POSTGRES_USER=${POSTGRES_USER:-myuser} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-mypassword} + restart: always + volumes: + - postgres_data:/var/lib/postgresql/data + + rag_api: + image: ghcr.io/danny-avila/librechat-rag-api-dev-lite:latest + environment: + - DB_HOST=vectordb + - VECTOR_DB_TYPE=pgvector + - POSTGRES_DB=${POSTGRES_DB:-mydatabase} + - POSTGRES_USER=${POSTGRES_USER:-myuser} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-mypassword} + - RAG_PORT=${RAG_PORT:-8000} + - OPENAI_API_KEY=${OPENAI_API_KEY} + - RAG_OPENAI_API_KEY=${RAG_OPENAI_API_KEY} + - GOOGLE_KEY=${GOOGLE_KEY} + - RAG_GOOGLE_API_KEY=${RAG_GOOGLE_API_KEY} + - JWT_SECRET=${JWT_SECRET} + - COLLECTION_NAME=${COLLECTION_NAME:-librechat_collection} + - CHUNK_SIZE=${CHUNK_SIZE:-1500} + - CHUNK_OVERLAP=${CHUNK_OVERLAP:-100} + - EMBEDDINGS_PROVIDER=${EMBEDDINGS_PROVIDER:-openai} + - EMBEDDINGS_MODEL=${EMBEDDINGS_MODEL:-text-embedding-3-small} + - DEBUG_RAG_API=false + - DEBUG_PGVECTOR_QUERIES=false + - CONSOLE_JSON=false + restart: always + depends_on: + - vectordb + +volumes: + mongo_data: + meili_data: + postgres_data: + librechat_data: \ No newline at end of file diff --git a/blueprints/librechat/librechat.png b/blueprints/librechat/librechat.png new file mode 100644 index 00000000..061f9a6b Binary files /dev/null and b/blueprints/librechat/librechat.png differ diff --git a/blueprints/librechat/template.toml b/blueprints/librechat/template.toml new file mode 100644 index 00000000..744a1745 --- /dev/null +++ b/blueprints/librechat/template.toml @@ -0,0 +1,93 @@ +[variables] +# Domain Configuration +main_domain = "${domain}" + +# Security & Authentication +jwt_secret = "${password:64}" +jwt_refresh_secret = "${password:64}" +creds_key = "f34be427ebb29de8d88c107a71546019685ed8b241d8f2ed00c3df97ad2566f0" +creds_iv = "e2341419ec3dd3d19b13a1a87fafcbfb" +meili_master_key = "${password:32}" + +# Database Configuration +mongo_password = "${password:16}" +postgresql_password = "${password:16}" + +[config] +version = "1.0.0" +# Main service domain mapping +[[config.domains]] +serviceName = "librechat" +port = 3080 +host = "${main_domain}" + +[config.env] +# Basic Configuration +HOST="0.0.0.0" +PORT="3080" +DOMAIN_CLIENT="https://${main_domain}" +DOMAIN_SERVER="https://${main_domain}" + +# Search Configuration +MEILI_MASTER_KEY="${meili_master_key}" + +# Security +JWT_SECRET="${jwt_secret}" +JWT_REFRESH_SECRET="${jwt_refresh_secret}" +CREDS_KEY="${creds_key}" +CREDS_IV="${creds_iv}" + +# API Keys +OPENAI_API_KEY="" +ANTHROPIC_API_KEY="" +GOOGLE_KEY="" +OPENROUTER_KEY="" + +# Database +POSTGRES_DB="librechat_db" +POSTGRES_USER="librechat_user" +POSTGRES_PASSWORD="${postgresql_password}" + +# Security & Sessions + +# User Interface +APP_TITLE="LibreChat" +CUSTOM_FOOTER="Made with ❀️ by LibreChat" +ALLOW_EMAIL_LOGIN="true" +ALLOW_REGISTRATION="false" +ALLOW_SOCIAL_LOGIN="false" + +# RAG +RAG_OPENAI_API_KEY="" +RAG_GOOGLE_API_KEY="" +EMBEDDINGS_PROVIDER="openai" +EMBEDDINGS_MODEL="text-embedding-3-small" + +CHUNK_SIZE=1500 +CHUNK_OVERLAP=100 + + + +[[config.mounts]] +filePath = "librechat.yaml" +content = """ +### librechat.yaml configs ### + +version: 1.2.8 +cache: true +endpoints: + custom: + - name: "OpenRouter" + apiKey: "${OPENROUTER_KEY}" + baseURL: "https://openrouter.ai/api/v1" + models: + default: ["meta-llama/llama-3.3-70b-instruct:free"] + fetch: true + titleConvo: true + titleModel: "current_model" + summarize: false + summaryModel: "current_model" + forcePrompt: false + dropParams: ["stop"] + modelDisplayLabel: "OpenRouter" +""" \ No newline at end of file diff --git a/blueprints/libredesk/docker-compose.yml b/blueprints/libredesk/docker-compose.yml index ef647ab7..212b528f 100644 --- a/blueprints/libredesk/docker-compose.yml +++ b/blueprints/libredesk/docker-compose.yml @@ -46,9 +46,6 @@ services: volumes: - redis-data:/data -networks: - libredesk: - volumes: postgres-data: redis-data: \ No newline at end of file diff --git a/blueprints/logto/docker-compose.yml b/blueprints/logto/docker-compose.yml index b59bdac0..04d7464f 100644 --- a/blueprints/logto/docker-compose.yml +++ b/blueprints/logto/docker-compose.yml @@ -31,9 +31,6 @@ services: timeout: 5s retries: 5 -networks: - dokploy-network: - external: true volumes: logto-connectors: diff --git a/blueprints/mcsmanager/docker-compose.yml b/blueprints/mcsmanager/docker-compose.yml new file mode 100644 index 00000000..7994a382 --- /dev/null +++ b/blueprints/mcsmanager/docker-compose.yml @@ -0,0 +1,29 @@ +services: + web: + image: githubyumao/mcsmanager-web:latest + restart: unless-stopped + ports: + - 23333 + volumes: + - /etc/localtime:/etc/localtime:ro + - mcsmanager-web-data:/opt/mcsmanager/web/data + - mcsmanager-web-logs:/opt/mcsmanager/web/logs + daemon: + image: githubyumao/mcsmanager-daemon:latest + restart: unless-stopped + ports: + - 24444 + environment: + - MCSM_DOCKER_WORKSPACE_PATH=/opt/mcsmanager/daemon/data/InstanceData + volumes: + - /etc/localtime:/etc/localtime:ro + - mcsmanager-daemon-data:/opt/mcsmanager/daemon/data + - mcsmanager-daemon-logs:/opt/mcsmanager/daemon/logs + - /var/run/docker.sock:/var/run/docker.sock + +volumes: + mcsmanager-web-data: + mcsmanager-web-logs: + mcsmanager-daemon-data: + mcsmanager-daemon-logs: + diff --git a/blueprints/mcsmanager/mcsmanager.png b/blueprints/mcsmanager/mcsmanager.png new file mode 100644 index 00000000..a7f28857 Binary files /dev/null and b/blueprints/mcsmanager/mcsmanager.png differ diff --git a/blueprints/mcsmanager/template.toml b/blueprints/mcsmanager/template.toml new file mode 100644 index 00000000..83e1164a --- /dev/null +++ b/blueprints/mcsmanager/template.toml @@ -0,0 +1,12 @@ +[variables] +main_domain = "${domain}" + +[config] +env = [] +mounts = [] + +[[config.domains]] +serviceName = "web" +port = 23333 +host = "${main_domain}" + diff --git a/blueprints/mediacms/docker-compose.yml b/blueprints/mediacms/docker-compose.yml new file mode 100644 index 00000000..cf58ba43 --- /dev/null +++ b/blueprints/mediacms/docker-compose.yml @@ -0,0 +1,134 @@ +version: "3" + +services: + migrations: + image: mediacms/mediacms:latest + volumes: + - mediacms_data:/home/mediacms.io/mediacms/media + - mediacms_static:/home/mediacms.io/mediacms/staticfiles + environment: + ENABLE_UWSGI: 'no' + ENABLE_NGINX: 'no' + ENABLE_CELERY_SHORT: 'no' + ENABLE_CELERY_LONG: 'no' + ENABLE_CELERY_BEAT: 'no' + ENABLE_MIGRATIONS: 'yes' + ADMIN_USER: 'admin' + ADMIN_EMAIL: 'admin@localhost' + ADMIN_PASSWORD: ${ADMIN_PASSWORD} + DATABASE_HOST: db + DATABASE_PORT: 5432 + DATABASE_USER: mediacms + DATABASE_PASSWORD: ${POSTGRES_PASSWORD} + DATABASE_NAME: mediacms + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + REDIS_HOST: redis + REDIS_PORT: 6379 + command: "./deploy/docker/prestart.sh" + restart: on-failure + depends_on: + redis: + condition: service_healthy + db: + condition: service_healthy + + web: + image: mediacms/mediacms:latest + deploy: + replicas: 1 + ports: + - 80 + volumes: + - mediacms_data:/home/mediacms.io/mediacms/media + - mediacms_static:/home/mediacms.io/mediacms/staticfiles + environment: + ENABLE_CELERY_BEAT: 'no' + ENABLE_CELERY_SHORT: 'no' + ENABLE_CELERY_LONG: 'no' + ENABLE_MIGRATIONS: 'no' + DATABASE_HOST: db + DATABASE_PORT: 5432 + DATABASE_USER: mediacms + DATABASE_PASSWORD: ${POSTGRES_PASSWORD} + DATABASE_NAME: mediacms + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + REDIS_HOST: redis + REDIS_PORT: 6379 + depends_on: + - migrations + + celery_beat: + image: mediacms/mediacms:latest + volumes: + - mediacms_data:/home/mediacms.io/mediacms/media + - mediacms_static:/home/mediacms.io/mediacms/staticfiles + environment: + ENABLE_UWSGI: 'no' + ENABLE_NGINX: 'no' + ENABLE_CELERY_SHORT: 'no' + ENABLE_CELERY_LONG: 'no' + ENABLE_MIGRATIONS: 'no' + DATABASE_HOST: db + DATABASE_PORT: 5432 + DATABASE_USER: mediacms + DATABASE_PASSWORD: ${POSTGRES_PASSWORD} + DATABASE_NAME: mediacms + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + REDIS_HOST: redis + REDIS_PORT: 6379 + depends_on: + - redis + + celery_worker: + image: mediacms/mediacms:latest + deploy: + replicas: 1 + volumes: + - mediacms_data:/home/mediacms.io/mediacms/media + - mediacms_static:/home/mediacms.io/mediacms/staticfiles + environment: + ENABLE_UWSGI: 'no' + ENABLE_NGINX: 'no' + ENABLE_CELERY_BEAT: 'no' + ENABLE_MIGRATIONS: 'no' + DATABASE_HOST: db + DATABASE_PORT: 5432 + DATABASE_USER: mediacms + DATABASE_PASSWORD: ${POSTGRES_PASSWORD} + DATABASE_NAME: mediacms + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + REDIS_HOST: redis + REDIS_PORT: 6379 + depends_on: + - migrations + + db: + image: postgres:17.2-alpine + volumes: + - postgres_data:/var/lib/postgresql/data/ + restart: always + environment: + POSTGRES_USER: mediacms + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: mediacms + TZ: Europe/London + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: "redis:alpine" + restart: always + healthcheck: + test: ["CMD", "redis-cli","ping"] + interval: 10s + timeout: 5s + retries: 3 + +volumes: + postgres_data: + mediacms_data: + mediacms_static: + diff --git a/blueprints/mediacms/mediacms.svg b/blueprints/mediacms/mediacms.svg new file mode 100644 index 00000000..4da6d37c --- /dev/null +++ b/blueprints/mediacms/mediacms.svg @@ -0,0 +1,6 @@ + + + Media + CMS + + diff --git a/blueprints/mediacms/template.toml b/blueprints/mediacms/template.toml new file mode 100644 index 00000000..d696018c --- /dev/null +++ b/blueprints/mediacms/template.toml @@ -0,0 +1,17 @@ +[variables] +main_domain = "${domain}" +postgres_password = "${password}" +admin_password = "${password}" + +[config] +mounts = [] + +[[config.domains]] +serviceName = "web" +port = 80 +host = "${main_domain}" + +[config.env] +POSTGRES_PASSWORD = "${postgres_password}" +ADMIN_PASSWORD = "${admin_password}" + diff --git a/blueprints/minio/docker-compose.yml b/blueprints/minio/docker-compose.yml index 0e14a430..a25e3aee 100644 --- a/blueprints/minio/docker-compose.yml +++ b/blueprints/minio/docker-compose.yml @@ -1,10 +1,10 @@ -version: "3.8" services: minio: # after RELEASE.2025-04-22T22-12-26Z, minio removed most of the admin UI, if you want to use the admin UI, uncomment the line below # image: minio/minio:RELEASE.2025-04-22T22-12-26Z # if you uncommented the line above, comment the line below image: minio/minio + restart: unless-stopped volumes: # by default, the MinIO container will use a volume named minio-data # to store its data. This volume is created automatically by Docker. diff --git a/blueprints/mulesoft-esb/docker-compose.yml b/blueprints/mulesoft-esb/docker-compose.yml new file mode 100644 index 00000000..6691e455 --- /dev/null +++ b/blueprints/mulesoft-esb/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3.8" + +services: + mule: + image: yogeshmulecraft/mulece-esb:latest + restart: unless-stopped + ports: + - "8081" + environment: + - MULE_VERSION=${MULE_VERSION:-4.9.0} + - HTTP_PORT=${HTTP_PORT:-8081} + - MULE_HOME=/opt/mule-standalone + - MULE_BASE=/opt/mule-standalone + - TZ=UTC + - MULE_VERBOSE_EXCEPTIONS=true + healthcheck: + test: ["CMD-SHELL", "curl -f http://localhost:${HTTP_PORT:-8081}/ || exit 0"] + interval: 60s + timeout: 20s + retries: 5 + start_period: 120s + diff --git a/blueprints/mulesoft-esb/mulesoft_logo.png b/blueprints/mulesoft-esb/mulesoft_logo.png new file mode 100644 index 00000000..7741d7f0 Binary files /dev/null and b/blueprints/mulesoft-esb/mulesoft_logo.png differ diff --git a/blueprints/mulesoft-esb/template.toml b/blueprints/mulesoft-esb/template.toml new file mode 100644 index 00000000..6cfb9017 --- /dev/null +++ b/blueprints/mulesoft-esb/template.toml @@ -0,0 +1,23 @@ + +# MuleSoft ESB Deployment Configuration + +[variables] +main_domain = "${domain}" +timezone = "UTC" +mule_version = "4.9.0" +http_port = "8081" + +[config] +[[config.domains]] +serviceName = "mule" +port = 8081 +host = "${main_domain}" +path = "/" + +[config.env] +MULE_VERSION = "${mule_version}" +HTTP_PORT = "${http_port}" +MULE_HOME = "/opt/mule-standalone" +MULE_BASE = "/opt/mule-standalone" +TZ = "${timezone}" +MULE_VERBOSE_EXCEPTIONS = "true" diff --git a/blueprints/mumble/docker-compose.yml b/blueprints/mumble/docker-compose.yml new file mode 100644 index 00000000..92580f1a --- /dev/null +++ b/blueprints/mumble/docker-compose.yml @@ -0,0 +1,16 @@ +services: + mumble-server: + image: mumblevoip/mumble-server:latest + restart: unless-stopped + ports: + - 64738 + - 64738/udp + volumes: + - mumble-data:/data + environment: + - MUMBLE_SUPERUSER_PASSWORD=${SUPERUSER_PASSWORD} + - MUMBLE_CONFIG_WELCOMETEXT=${WELCOME_TEXT} + - MUMBLE_CONFIG_USERS=${MAX_USERS} + +volumes: + mumble-data: diff --git a/blueprints/mumble/mumble.png b/blueprints/mumble/mumble.png new file mode 100644 index 00000000..dcd1084f Binary files /dev/null and b/blueprints/mumble/mumble.png differ diff --git a/blueprints/mumble/template.toml b/blueprints/mumble/template.toml new file mode 100644 index 00000000..fba20b91 --- /dev/null +++ b/blueprints/mumble/template.toml @@ -0,0 +1,12 @@ +[variables] +superuser_password = "${password:32}" +welcome_text = "Welcome to Mumble Server! Low-latency voice chat." +max_users = "50" + +[config] + +[config.env] +SUPERUSER_PASSWORD = "${superuser_password}" +WELCOME_TEXT = "${welcome_text}" +MAX_USERS = "${max_users}" + diff --git a/blueprints/nextcloud-aio/docker-compose.yml b/blueprints/nextcloud-aio/docker-compose.yml index 1e6d00fe..1f4e43e6 100644 --- a/blueprints/nextcloud-aio/docker-compose.yml +++ b/blueprints/nextcloud-aio/docker-compose.yml @@ -30,7 +30,3 @@ services: volumes: nextcloud_data: nextcloud_db_data: - -networks: - dokploy-network: - external: true diff --git a/blueprints/openinary/docker-compose.yml b/blueprints/openinary/docker-compose.yml new file mode 100644 index 00000000..0469c72b --- /dev/null +++ b/blueprints/openinary/docker-compose.yml @@ -0,0 +1,26 @@ +version: "3.8" +services: + openinary: + image: openinary/openinary:${IMAGE_TAG:-latest} + pull_policy: always + restart: unless-stopped + expose: + - 3000 + environment: + NODE_ENV: production + MODE: fullstack + NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-/api} + BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET} + BETTER_AUTH_URL: ${BETTER_AUTH_URL} + ALLOWED_ORIGIN: ${ALLOWED_ORIGIN:-http://${domain}} + DOCKER_CONTAINER: "true" + volumes: + - cache-data:/app/apps/api/cache + - public-files:/app/apps/api/public + - db-data:/app/data + - db-data:/app/web-standalone/data + +volumes: + cache-data: + public-files: + db-data: \ No newline at end of file diff --git a/blueprints/openinary/openinary.svg b/blueprints/openinary/openinary.svg new file mode 100644 index 00000000..2a902cd6 --- /dev/null +++ b/blueprints/openinary/openinary.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/blueprints/openinary/template.toml b/blueprints/openinary/template.toml new file mode 100644 index 00000000..ea317117 --- /dev/null +++ b/blueprints/openinary/template.toml @@ -0,0 +1,40 @@ +[variables] +main_domain = "${domain}" +image_tag = "latest" +better_auth_secret = "${password:64}" +better_auth_url = "http://${main_domain}" +allowed_origin = "http://${main_domain}" +next_public_api_base_url = "/api" + +[config] +[[config.domains]] +serviceName = "openinary" +port = 3000 +host = "${main_domain}" + +[config.env] +IMAGE_TAG = "${image_tag}" +BETTER_AUTH_SECRET = "${better_auth_secret}" +BETTER_AUTH_URL = "${better_auth_url}" +ALLOWED_ORIGIN = "${allowed_origin}" +NEXT_PUBLIC_API_BASE_URL = "${next_public_api_base_url}" + +[[config.mounts]] +serviceName = "openinary" +volumeName = "cache-data" +mountPath = "/app/apps/api/cache" + +[[config.mounts]] +serviceName = "openinary" +volumeName = "public-files" +mountPath = "/app/apps/api/public" + +[[config.mounts]] +serviceName = "openinary" +volumeName = "db-data" +mountPath = "/app/data" + +[[config.mounts]] +serviceName = "openinary" +volumeName = "db-data" +mountPath = "/app/web-standalone/data" \ No newline at end of file diff --git a/blueprints/parseable/docker-compose.yml b/blueprints/parseable/docker-compose.yml new file mode 100644 index 00000000..344ac624 --- /dev/null +++ b/blueprints/parseable/docker-compose.yml @@ -0,0 +1,23 @@ +version: "3.8" +services: + parseable: + image: parseable/parseable:v1.6.0 + command: parseable local-store + restart: unless-stopped + volumes: + - parseable-staging:/parseable/staging + - parseable-data:/parseable/data + environment: + - P_ADDR=0.0.0.0:8000 + - P_USERNAME=${PARSEABLE_USERNAME} + - P_PASSWORD=${PARSEABLE_PASSWORD} + - P_STAGING_DIR=/parseable/staging + - P_FS_DIR=/parseable/data + ports: + - 8000 + - 8001 + - 8002 +volumes: + parseable-staging: {} + parseable-data: {} + diff --git a/blueprints/parseable/logo.svg b/blueprints/parseable/logo.svg new file mode 100644 index 00000000..4660d802 --- /dev/null +++ b/blueprints/parseable/logo.svg @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/blueprints/parseable/template.toml b/blueprints/parseable/template.toml new file mode 100644 index 00000000..f82eb77e --- /dev/null +++ b/blueprints/parseable/template.toml @@ -0,0 +1,16 @@ +[variables] +main_domain = "${domain}" +parseable_username = "${username}" +parseable_password = "${password:32}" + +[config] + +[[config.domains]] +serviceName = "parseable" +port = 8000 +host = "${main_domain}" + +[config.env] +PARSEABLE_USERNAME = "${parseable_username}" +PARSEABLE_PASSWORD = "${parseable_password}" + diff --git a/blueprints/passbolt/docker-compose.yml b/blueprints/passbolt/docker-compose.yml new file mode 100644 index 00000000..f6b91aac --- /dev/null +++ b/blueprints/passbolt/docker-compose.yml @@ -0,0 +1,79 @@ +# ============================================================================= +# PASSBOLT TEMPLATE - SETUP INSTRUCTIONS +# ============================================================================= +# +# After successful deployment, you need to create an admin user: +# +# 1. Go to your Dokploy dashboard +# 2. Navigate to your Passbolt application +# 3. Wait for both containers to be healthy - check the "Monitoring" tab +# 4. Go to the "General" tab and click "Open Terminal" button +# 5. In the terminal, run this command to create admin user: +# su -s /bin/bash -c "/usr/share/php/passbolt/bin/cake passbolt register_user -u youremail@example.com -f FirstName -l LastName -r admin" www-data +# 6. Replace youremail@example.com, FirstName, LastName with your actual details +# 7. The command will output a registration link - copy and paste it in your browser to complete setup +# +# NOTE: If you change the domain after deployment, you will need to manually +# update the PASSBOLT_APP_FULL_BASE_URL environment variable in the "Environment" tab. +# ============================================================================= + +services: + passbolt: + image: passbolt/passbolt:latest-ce + environment: + APP_FULL_BASE_URL: ${PASSBOLT_APP_FULL_BASE_URL} + DATASOURCES_DEFAULT_HOST: ${PASSBOLT_DB_HOST} + DATASOURCES_DEFAULT_PORT: ${PASSBOLT_DB_PORT} + DATASOURCES_DEFAULT_USERNAME: ${PASSBOLT_DB_USER} + DATASOURCES_DEFAULT_PASSWORD: ${PASSBOLT_DB_PASSWORD} + DATASOURCES_DEFAULT_DATABASE: ${PASSBOLT_DB_NAME} + PASSBOLT_PLUGINS_JWT_AUTHENTICATION_ENABLED: ${PASSBOLT_PLUGINS_JWT_AUTHENTICATION_ENABLED} + + EMAIL_DEFAULT_FROM: ${PASSBOLT_EMAIL_FROM} + EMAIL_TRANSPORT_DEFAULT_HOST: ${PASSBOLT_EMAIL_HOST} + EMAIL_TRANSPORT_DEFAULT_PORT: ${PASSBOLT_EMAIL_PORT} + EMAIL_TRANSPORT_DEFAULT_USERNAME: ${PASSBOLT_EMAIL_USER} + EMAIL_TRANSPORT_DEFAULT_PASSWORD: ${PASSBOLT_EMAIL_PASS} + EMAIL_TRANSPORT_DEFAULT_TLS: ${PASSBOLT_EMAIL_TLS} + + volumes: + - gpg_volume:/etc/passbolt/gpg + - jwt_volume:/etc/passbolt/jwt + + command: + - /usr/bin/wait-for.sh + - "-t" + - "0" + - "${PASSBOLT_DB_HOST}:${PASSBOLT_DB_PORT}" + - "--" + - /docker-entrypoint.sh + + depends_on: + mariadb: + condition: service_healthy + + healthcheck: + test: ["CMD", "curl", "-f", "http://127.0.0.1:80"] + interval: 5s + timeout: 20s + retries: 10 + + mariadb: + image: mariadb:11 + environment: + MARIADB_ROOT_PASSWORD: ${PASSBOLT_DB_ROOT_PASSWORD} + MARIADB_DATABASE: ${PASSBOLT_DB_NAME} + MARIADB_USER: ${PASSBOLT_DB_USER} + MARIADB_PASSWORD: ${PASSBOLT_DB_PASSWORD} + volumes: + - passbolt_mariadb_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "--silent"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + gpg_volume: {} + jwt_volume: {} + passbolt_mariadb_data: {} diff --git a/blueprints/passbolt/passbolt.svg b/blueprints/passbolt/passbolt.svg new file mode 100644 index 00000000..40a905ab --- /dev/null +++ b/blueprints/passbolt/passbolt.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/blueprints/passbolt/template.toml b/blueprints/passbolt/template.toml new file mode 100644 index 00000000..e14042e4 --- /dev/null +++ b/blueprints/passbolt/template.toml @@ -0,0 +1,41 @@ +[variables] +main_domain = "${domain}" +db_password = "${password:32}" +db_root_password = "${password:32}" +email_host = "smtp.example.com" +email_user = "noreply@example.com" +email_pass = "${password:16}" + +[config] +[[config.domains]] +serviceName = "passbolt" +port = 80 +host = "${main_domain}" + +[config.env] +PASSBOLT_APP_FULL_BASE_URL = "http://${main_domain}" +PASSBOLT_DB_HOST = "mariadb" +PASSBOLT_DB_PORT = "3306" +PASSBOLT_DB_NAME = "passbolt" +PASSBOLT_DB_USER = "passbolt" +PASSBOLT_DB_PASSWORD = "${db_password}" +PASSBOLT_DB_ROOT_PASSWORD = "${db_root_password}" +PASSBOLT_PLUGINS_JWT_AUTHENTICATION_ENABLED = "true" +PASSBOLT_EMAIL_FROM = "passbolt@${main_domain}" +PASSBOLT_EMAIL_HOST = "${email_host}" +PASSBOLT_EMAIL_PORT = "587" +PASSBOLT_EMAIL_USER = "${email_user}" +PASSBOLT_EMAIL_PASS = "${email_pass}" +PASSBOLT_EMAIL_TLS = "true" + +[[config.mounts]] +volume = "gpg_volume" +target = "/etc/passbolt/gpg" + +[[config.mounts]] +volume = "jwt_volume" +target = "/etc/passbolt/jwt" + +[[config.mounts]] +volume = "passbolt_mariadb_data" +target = "/var/lib/mysql" \ No newline at end of file diff --git a/blueprints/peerdb/docker-compose.yml b/blueprints/peerdb/docker-compose.yml new file mode 100644 index 00000000..5d2c69f7 --- /dev/null +++ b/blueprints/peerdb/docker-compose.yml @@ -0,0 +1,187 @@ +name: peerdb-quickstart + +x-minio-config: &minio-config + PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_ACCESS_KEY_ID: ${MINIO_ROOT_USER} + PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_SECRET_ACCESS_KEY: ${MINIO_ROOT_PASSWORD} + MINIO_ROOT_USER: ${MINIO_ROOT_USER} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_REGION: ${PEERDB_CLICKHOUSE_AWS_REGION} + PEERDB_CLICKHOUSE_AWS_CREDENTIALS_AWS_ENDPOINT_URL_S3: ${PEERDB_CLICKHOUSE_AWS_ENDPOINT_URL_S3} + PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME: ${PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME} + +x-catalog-config: &catalog-config + PEERDB_CATALOG_HOST: ${PEERDB_CATALOG_HOST} + PEERDB_CATALOG_PORT: ${PEERDB_CATALOG_PORT} + PEERDB_CATALOG_USER: ${PEERDB_CATALOG_USER} + PEERDB_CATALOG_PASSWORD: ${PEERDB_CATALOG_PASSWORD} + PEERDB_CATALOG_DATABASE: ${PEERDB_CATALOG_DATABASE} + +x-flow-worker-env: &flow-worker-env + TEMPORAL_HOST_PORT: temporal:7233 + TEMPORAL_CLIENT_CERT: + TEMPORAL_CLIENT_KEY: + PEERDB_TEMPORAL_NAMESPACE: default + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID:-} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY:-} + AWS_REGION: ${AWS_REGION:-} + AWS_ENDPOINT: ${AWS_ENDPOINT:-} + +services: + catalog: + image: postgres:18-alpine@sha256:eca6fb2d91fda290eb8cfb8ba53dd0dcbf3508a08011e30adb039ea7c8e1e9f2 + command: -c config_file=/etc/postgresql.conf + restart: unless-stopped + expose: + - 5432 + environment: + PGUSER: ${PEERDB_CATALOG_USER} + POSTGRES_PASSWORD: ${PEERDB_CATALOG_PASSWORD} + POSTGRES_DB: ${PEERDB_CATALOG_DATABASE} + POSTGRES_INITDB_ARGS: --locale=C.UTF-8 + volumes: + - pgdata:/var/lib/postgresql/data + - ../files/postgresql.conf:/etc/postgresql.conf + - ../files/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d + healthcheck: + test: ["CMD", "pg_isready", "-d", "${PEERDB_CATALOG_DATABASE}", "-U", "${PEERDB_CATALOG_USER}"] + interval: 10s + timeout: 30s + retries: 5 + start_period: 60s + + temporal: + restart: unless-stopped + depends_on: + catalog: + condition: service_healthy + environment: + DB: postgres12 + DB_PORT: ${PEERDB_CATALOG_PORT} + POSTGRES_USER: ${PEERDB_CATALOG_USER} + POSTGRES_PWD: ${PEERDB_CATALOG_PASSWORD} + POSTGRES_SEEDS: catalog + DYNAMIC_CONFIG_FILE_PATH: config/dynamicconfig/production-sql.yaml + image: temporalio/auto-setup:1.29@sha256:5b3502a3b685f9eff1b925af90c57c9e3dbeccbef367cc28a2a9712c63379312 + expose: + - 7233 + volumes: + - ../files/temporal-dynamicconfig:/etc/temporal/config/dynamicconfig + + temporal-admin-tools: + restart: unless-stopped + depends_on: + - temporal + environment: + TEMPORAL_ADDRESS: temporal:7233 + TEMPORAL_CLI_ADDRESS: temporal:7233 + TEMPORAL_CLI_SHOW_STACKS: 1 + image: temporalio/admin-tools:1.25.2-tctl-1.18.1-cli-1.1.1@sha256:da0c7a7982b571857173ab8f058e7f139b3054800abb4dcb100445d29a563ee8 + stdin_open: true + tty: true + entrypoint: ["sh", "/etc/temporal/entrypoint.sh"] + healthcheck: + test: ["CMD", "tctl", "workflow", "list"] + interval: 10s + timeout: 30s + retries: 5 + volumes: + - ../files/scripts/mirror-name-search.sh:/etc/temporal/entrypoint.sh + + temporal-ui: + restart: unless-stopped + depends_on: + - temporal + environment: + TEMPORAL_ADDRESS: temporal:7233 + TEMPORAL_CORS_ORIGINS: http://localhost:3000 + TEMPORAL_CSRF_COOKIE_INSECURE: "true" + image: temporalio/ui:2.43.3@sha256:31f0d8c1ed0bfc49c9c20ea9613ee9dd5c52f5f989bacb8a30210f847028e9cd + expose: + - 8080 + + flow-api: + image: ghcr.io/peerdb-io/flow-api:stable-v0.35.5 + restart: unless-stopped + expose: + - 8112 + - 8113 + environment: + <<: [*catalog-config, *flow-worker-env, *minio-config] + PEERDB_ALLOWED_TARGETS: ${PEERDB_ALLOWED_TARGETS} + depends_on: + temporal-admin-tools: + condition: service_healthy + + flow-snapshot-worker: + image: ghcr.io/peerdb-io/flow-snapshot-worker:stable-v0.35.5 + restart: unless-stopped + environment: + <<: [*catalog-config, *flow-worker-env, *minio-config] + depends_on: + temporal-admin-tools: + condition: service_healthy + + flow-worker: + image: ghcr.io/peerdb-io/flow-worker:stable-v0.35.5 + restart: unless-stopped + environment: + <<: [*catalog-config, *flow-worker-env, *minio-config] + depends_on: + temporal-admin-tools: + condition: service_healthy + + peerdb: + stop_signal: SIGINT + image: ghcr.io/peerdb-io/peerdb-server:stable-v0.35.5 + restart: unless-stopped + environment: + <<: *catalog-config + PEERDB_PASSWORD: ${PEERDB_PASSWORD} + PEERDB_FLOW_SERVER_ADDRESS: ${PEERDB_FLOW_SERVER_ADDRESS} + RUST_LOG: info + RUST_BACKTRACE: 1 + expose: + - 9900 + depends_on: + catalog: + condition: service_healthy + + peerdb-ui: + image: ghcr.io/peerdb-io/peerdb-ui:stable-v0.35.5 + restart: unless-stopped + expose: + - 3000 + environment: + <<: *catalog-config + DATABASE_URL: ${DATABASE_URL} + PEERDB_FLOW_SERVER_HTTP: ${PEERDB_FLOW_SERVER_HTTP} + NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} + NEXTAUTH_URL: ${NEXTAUTH_URL} + PEERDB_ALLOWED_TARGETS: ${PEERDB_ALLOWED_TARGETS} + PEERDB_CLICKHOUSE_ALLOWED_DOMAINS: ${PEERDB_CLICKHOUSE_ALLOWED_DOMAINS} + PEERDB_EXPERIMENTAL_ENABLE_SCRIPTING: ${PEERDB_EXPERIMENTAL_ENABLE_SCRIPTING} + depends_on: + - flow-api + + minio: + image: minio/minio:latest@sha256:14cea493d9a34af32f524e538b8346cf79f3321eff8e708c1e2960462bd8936e + restart: unless-stopped + volumes: + - minio-data:/data + expose: + - 9000 + - 9001 + environment: + <<: *minio-config + entrypoint: > + /bin/sh -c " + minio server /data --console-address=:9001 & + sleep 2; + mc alias set myminiopeerdb http://minio:9000 $$MINIO_ROOT_USER $$MINIO_ROOT_PASSWORD; + mc mb myminiopeerdb/$$PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME; + wait + " + +volumes: + pgdata: + minio-data: diff --git a/blueprints/peerdb/peerdb.jpeg b/blueprints/peerdb/peerdb.jpeg new file mode 100644 index 00000000..cd33a1fa Binary files /dev/null and b/blueprints/peerdb/peerdb.jpeg differ diff --git a/blueprints/peerdb/template.toml b/blueprints/peerdb/template.toml new file mode 100644 index 00000000..3325ac4b --- /dev/null +++ b/blueprints/peerdb/template.toml @@ -0,0 +1,93 @@ +[variables] +main_domain = "${domain}" +peerdb_password = "${password:32}" +postgres_password = "${password:32}" +minio_root_user = "_peerdb_minioadmin" +minio_root_password = "${password:32}" +nextauth_secret = "${password:32}" + +[[config.domains]] +serviceName = "peerdb-ui" +port = 3000 +host = "${main_domain}" + +[[config.domains]] +serviceName = "minio" +port = 9001 +host = "${main_domain}" + +[[config.domains]] +serviceName = "temporal-ui" +port = 8080 +host = "${main_domain}" + +[config.env] +PEERDB_PASSWORD = "${peerdb_password}" +PEERDB_CATALOG_HOST = "catalog" +PEERDB_CATALOG_PORT = "5432" +PEERDB_CATALOG_USER = "postgres" +PEERDB_CATALOG_PASSWORD = "${postgres_password}" +PEERDB_CATALOG_DATABASE = "postgres" +PEERDB_FLOW_SERVER_ADDRESS = "grpc://flow-api:8112" +NEXTAUTH_URL = "http://localhost:3000" +NEXTAUTH_SECRET = "${nextauth_secret}" +DATABASE_URL = "postgres://postgres:${postgres_password}@catalog:5432/postgres" +PEERDB_FLOW_SERVER_HTTP = "http://flow-api:8113" +PEERDB_EXPERIMENTAL_ENABLE_SCRIPTING = "true" +MINIO_ROOT_USER = "${minio_root_user}" +MINIO_ROOT_PASSWORD = "${minio_root_password}" +PEERDB_CLICKHOUSE_AWS_REGION = "us-east-1" +PEERDB_CLICKHOUSE_AWS_ENDPOINT_URL_S3 = "http://minio:9000" +PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAME = "peerdbbucket" +PEERDB_ALLOWED_TARGETS = "" +PEERDB_CLICKHOUSE_ALLOWED_DOMAINS = "" +AWS_ACCESS_KEY_ID = "" +AWS_SECRET_ACCESS_KEY = "" +AWS_REGION = "" +AWS_ENDPOINT = "" + +[[config.mounts]] +filePath = "./postgresql.conf" +content = """ +listen_addresses = '*' + +wal_level = logical +max_wal_senders = 4 +max_replication_slots = 4 +""" + +[[config.mounts]] +filePath = "./docker-entrypoint-initdb.d/pg-hba-replication.sh" +content = """ +#!/bin/sh +echo "host replication $POSTGRES_USER 0.0.0.0/0 trust" >> "$PGDATA/pg_hba.conf" +""" + +[[config.mounts]] +filePath = "./temporal-dynamicconfig/production-sql.yaml" +content = """ +limit.maxIDLength: + - value: 255 + constraints: {} +system.forceSearchAttributesCacheRefreshOnRead: + - value: false + constraints: {} +frontend.enableUpdateWorkflowExecution: + - value: true +""" + +[[config.mounts]] +filePath = "./scripts/mirror-name-search.sh" +content = """ +#!/bin/sh + +sleep 5 + +# Check if MirrorName attribute exists +if ! temporal operator search-attribute list | grep -w MirrorName >/dev/null 2>&1; then + # If not, create MirrorName attribute + temporal operator search-attribute create --name MirrorName --type Text --namespace default +fi + +tini -s -- sleep infinity +""" diff --git a/blueprints/peppermint/docker-compose.yml b/blueprints/peppermint/docker-compose.yml index 06fb46c6..a5af058f 100644 --- a/blueprints/peppermint/docker-compose.yml +++ b/blueprints/peppermint/docker-compose.yml @@ -30,9 +30,5 @@ services: DB_HOST: "peppermint-postgres" SECRET: ${SECRET} -networks: - dokploy-network: - external: true - volumes: peppermint-postgres-data: \ No newline at end of file diff --git a/blueprints/postiz/docker-compose.yml b/blueprints/postiz/docker-compose.yml index cd06e795..dfbf3ae9 100644 --- a/blueprints/postiz/docker-compose.yml +++ b/blueprints/postiz/docker-compose.yml @@ -54,10 +54,6 @@ services: volumes: - postiz-redis-data:/data -networks: - dokploy-network: - external: true - volumes: postiz-postgres-data: postiz-redis-data: diff --git a/blueprints/quant-ux/docker-compose.yml b/blueprints/quant-ux/docker-compose.yml new file mode 100644 index 00000000..e96a9d6a --- /dev/null +++ b/blueprints/quant-ux/docker-compose.yml @@ -0,0 +1,69 @@ +version: '3' + +services: + mongo: + restart: always + image: mongo + volumes: + - mongo_data:/data/db + qux-fe: + restart: always + image: klausenschaefersinho/quant-ux + environment: + - QUX_PROXY_URL=http://quant-ux-backend:8080 + - QUX_AUTH=${QUX_AUTH} + - QUX_KEYCLOAK_REALM=${QUX_KEYCLOAK_REALM} + - QUX_KEYCLOAK_CLIENT=${QUX_KEYCLOAK_CLIENT} + - QUX_KEYCLOAK_URL=${QUX_KEYCLOAK_URL} + - QUX_WS_URL=${QUX_WS_URL} + links: + - mongo + - qux-be + ports: + - 8082 + depends_on: + - qux-be + + qux-be: + restart: always + image: klausenschaefersinho/quant-ux-backend + volumes: + - quant_ux_data:/app-data + environment: + - QUX_HTTP_HOST=${QUX_HTTP_HOST} + - QUX_HTTP_PORT=8080 + - QUX_MONGO_DB_NAME=${QUX_MONGO_DB_NAME} + - QUX_MONGO_TABLE_PREFIX=${QUX_MONGO_TABLE_PREFIX} + - QUX_MONGO_CONNECTION_STRING=mongodb://quant-ux-mongo:27017 + - QUX_MAIL_USER=${QUX_MAIL_USER} + - QUX_MAIL_PASSWORD=${QUX_MAIL_PASSWORD} + - QUX_MAIL_HOST=${QUX_MAIL_HOST} + - QUX_JWT_PASSWORD=${QUX_JWT_PASSWORD} + - QUX_IMAGE_FOLDER_USER=/app-data/qux-images + - QUX_IMAGE_FOLDER_APPS=/app-data/qux-image-apps + - TZ=${TZ} + - QUX_AUTH_SERVICE=${QUX_AUTH_SERVICE} + - QUX_KEYCLOAK_SERVER=${QUX_KEYCLOAK_SERVER} + - QUX_KEYCLOAK_REALM=${QUX_KEYCLOAK_REALM} + - QUX_USER_ALLOW_SIGNUP=${QUX_USER_ALLOW_SIGNUP} + - QUX_USER_ALLOWED_DOMAINS=${QUX_USER_ALLOWED_DOMAINS} + depends_on: + - mongo + + qux-ws: + restart: always + image: klausenschaefersinho/quant-ux-websocket + environment: + - QUX_SERVER=http://quant-ux-backend:8080/ + - QUX_SERVER_PORT=8086 + ports: + - 8086 + links: + - qux-be + depends_on: + - qux-be + +volumes: + mongo_data: + quant_ux_data: + diff --git a/blueprints/quant-ux/logo.svg b/blueprints/quant-ux/logo.svg new file mode 100644 index 00000000..1c71b3c8 --- /dev/null +++ b/blueprints/quant-ux/logo.svg @@ -0,0 +1,2 @@ + + diff --git a/blueprints/quant-ux/template.toml b/blueprints/quant-ux/template.toml new file mode 100644 index 00000000..912bc5c7 --- /dev/null +++ b/blueprints/quant-ux/template.toml @@ -0,0 +1,50 @@ +[variables] +main_domain = "${domain}" +ws_domain = "${domain}" +qux_auth = "qux" +qux_jwt_password = "${password:64}" +qux_mongo_db_name = "quantux" +qux_mongo_table_prefix = "quantux" +qux_mail_user = "${email}" +qux_mail_password = "${password:32}" +qux_mail_host = "mail.example.com" +qux_timezone = "America/Chicago" +qux_auth_service = "qux" +qux_user_allow_signup = "true" +qux_user_allowed_domains = "*" +qux_keycloak_realm = "" +qux_keycloak_client = "" +qux_keycloak_url = "" +qux_keycloak_server = "" + +[config] +env = [ + "QUX_HTTP_HOST=https://${main_domain}", + "QUX_AUTH=${qux_auth}", + "QUX_JWT_PASSWORD=${qux_jwt_password}", + "QUX_MONGO_DB_NAME=${qux_mongo_db_name}", + "QUX_MONGO_TABLE_PREFIX=${qux_mongo_table_prefix}", + "QUX_MAIL_USER=${qux_mail_user}", + "QUX_MAIL_PASSWORD=${qux_mail_password}", + "QUX_MAIL_HOST=${qux_mail_host}", + "TZ=${qux_timezone}", + "QUX_AUTH_SERVICE=${qux_auth_service}", + "QUX_KEYCLOAK_SERVER=${qux_keycloak_server}", + "QUX_KEYCLOAK_REALM=${qux_keycloak_realm}", + "QUX_KEYCLOAK_CLIENT=${qux_keycloak_client}", + "QUX_KEYCLOAK_URL=${qux_keycloak_url}", + "QUX_USER_ALLOW_SIGNUP=${qux_user_allow_signup}", + "QUX_USER_ALLOWED_DOMAINS=${qux_user_allowed_domains}", + "QUX_WS_URL=wss://${ws_domain}" +] + +[[config.domains]] +serviceName = "qux-fe" +port = 8082 +host = "${main_domain}" + +[[config.domains]] +serviceName = "qux-ws" +port = 8086 +host = "${ws_domain}" + diff --git a/blueprints/rote/docker-compose.yml b/blueprints/rote/docker-compose.yml new file mode 100644 index 00000000..a88354a0 --- /dev/null +++ b/blueprints/rote/docker-compose.yml @@ -0,0 +1,45 @@ +services: + rote-backend: + image: rabithua/rote-backend:${IMAGE_TAG:-latest} + pull_policy: always + environment: + POSTGRESQL_URL: postgresql://rote:${POSTGRES_PASSWORD}@rote-postgres:5432/rote + depends_on: + rote-postgres: + condition: service_healthy + restart: unless-stopped + command: + [ + "sh", + "-c", + "sleep 15 && bun run dist/scripts/runMigrations.js && bun run dist/server.js", + ] + + rote-frontend: + image: rabithua/rote-frontend:${IMAGE_TAG:-latest} + pull_policy: always + depends_on: + - rote-backend + environment: + # VITE_API_BASE must point to an address that reaches rote-backend (reverse-proxy domain or host IP:port) + VITE_API_BASE: ${VITE_API_BASE} + restart: unless-stopped + + rote-postgres: + image: postgres:17 + restart: unless-stopped + environment: + POSTGRES_USER: rote + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_DB: rote + volumes: + - rote-postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U rote -d rote"] + interval: 5s + timeout: 3s + retries: 10 + start_period: 30s + +volumes: + rote-postgres-data: {} diff --git a/blueprints/rote/rote.png b/blueprints/rote/rote.png new file mode 100644 index 00000000..9aca501f Binary files /dev/null and b/blueprints/rote/rote.png differ diff --git a/blueprints/rote/template.toml b/blueprints/rote/template.toml new file mode 100644 index 00000000..90dcc8ad --- /dev/null +++ b/blueprints/rote/template.toml @@ -0,0 +1,23 @@ +[variables] +frontend_domain = "${domain}" +backend_domain = "${domain}" +postgres_password = "${password:32}" +image_tag = "latest" + +[config] +[[config.domains]] +serviceName = "rote-frontend" +port = 80 +host = "${frontend_domain}" + +[[config.domains]] +serviceName = "rote-backend" +port = 3000 +host = "${backend_domain}" + +[config.env] +POSTGRES_PASSWORD = "${postgres_password}" +IMAGE_TAG = "${image_tag}" +VITE_API_BASE = "http://${backend_domain}" + +[[config.mounts]] diff --git a/blueprints/roundcube/docker-compose.yml b/blueprints/roundcube/docker-compose.yml index e5ba4a8b..8af6daf6 100644 --- a/blueprints/roundcube/docker-compose.yml +++ b/blueprints/roundcube/docker-compose.yml @@ -11,6 +11,3 @@ services: - ROUNDCUBEMAIL_SMTP_SERVER=${SMTP_SERVER} -networks: - dokploy-network: - external: true diff --git a/blueprints/rustdesk/docker-compose.yml b/blueprints/rustdesk/docker-compose.yml index b9c38a57..a29d64d4 100644 --- a/blueprints/rustdesk/docker-compose.yml +++ b/blueprints/rustdesk/docker-compose.yml @@ -6,9 +6,9 @@ services: volumes: - rustdesk-data:/root ports: - - 21115 - - 21116 - - 21116/udp + - "21115:21115" + - "21116:21116" + - "21116:21116/udp" depends_on: - hbbr @@ -19,9 +19,9 @@ services: volumes: - rustdesk-data:/root ports: - - 21117 - - 21118 - - 21119 + - "21117:21117" + - "21118:21118" + - "21119:21119" volumes: - rustdesk-data: {} \ No newline at end of file + rustdesk-data: diff --git a/blueprints/rustdesk/template.toml b/blueprints/rustdesk/template.toml index 080144c4..7f44194f 100644 --- a/blueprints/rustdesk/template.toml +++ b/blueprints/rustdesk/template.toml @@ -1,9 +1,14 @@ [variables] server_domain = "${domain}" +encryption_key = "${password:32}" [config] [config.env] +RELAY_HOST = "${server_domain}" RUSTDESK_RELAY_SERVER = "${server_domain}:21117" +RUSTDESK_API_SERVER = "http://${server_domain}:21118" +RUSTDESK_ID_SERVER = "${server_domain}:21116" +ENCRYPTION_KEY = "${encryption_key}" [[config.mounts]] \ No newline at end of file diff --git a/blueprints/rustfs/docker-compose.yml b/blueprints/rustfs/docker-compose.yml new file mode 100644 index 00000000..cbedbae6 --- /dev/null +++ b/blueprints/rustfs/docker-compose.yml @@ -0,0 +1,20 @@ +version: "3.8" + +services: + rustfs: + image: rustfs/rustfs:latest + volumes: + - rustfs-data:/data + environment: + - RUSTFS_ACCESS_KEY + - RUSTFS_SECRET_KEY + - RUSTFS_ADDRESS=0.0.0.0:9000 + - RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001 + - RUSTFS_CONSOLE_ENABLE=true + - RUSTFS_CORS_ALLOWED_ORIGINS=* + - RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS=* + command: /data + restart: unless-stopped + +volumes: + rustfs-data: diff --git a/blueprints/rustfs/logo.svg b/blueprints/rustfs/logo.svg new file mode 100644 index 00000000..d5cf09f6 --- /dev/null +++ b/blueprints/rustfs/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/blueprints/rustfs/meta-entry.json b/blueprints/rustfs/meta-entry.json new file mode 100644 index 00000000..fc532473 --- /dev/null +++ b/blueprints/rustfs/meta-entry.json @@ -0,0 +1,18 @@ +{ + "id": "rustfs", + "name": "RustFS", + "version": "latest", + "description": "RustFS is a high-performance, S3-compatible distributed object storage system built in Rust. 2.3x faster than MinIO for small objects, with full S3 API compatibility.", + "logo": "logo.svg", + "links": { + "github": "https://github.com/rustfs/rustfs", + "website": "https://rustfs.com/", + "docs": "https://docs.rustfs.com/" + }, + "tags": [ + "storage", + "s3", + "object-storage", + "rust" + ] +} diff --git a/blueprints/rustfs/template.toml b/blueprints/rustfs/template.toml new file mode 100644 index 00000000..8e6f96fb --- /dev/null +++ b/blueprints/rustfs/template.toml @@ -0,0 +1,25 @@ +[variables] +console_domain = "${domain}" +api_domain = "${domain}" +access_key = "rustfsadmin" +secret_key = "${password:16}" + +[config] +env = [ + "RUSTFS_ACCESS_KEY=${access_key}", + "RUSTFS_SECRET_KEY=${secret_key}", + "", + "## SET THE API URL IN CONSOLE CONFIG BY CLICKING THE COG", + "## API URL: ${api_domain}", +] +mounts = [] + +[[config.domains]] +serviceName = "rustfs" +port = 9001 +host = "${console_domain}" + +[[config.domains]] +serviceName = "rustfs" +port = 9000 +host = "${api_domain}" diff --git a/blueprints/slash/docker-compose.yml b/blueprints/slash/docker-compose.yml index ee6cdf89..c3aba95a 100644 --- a/blueprints/slash/docker-compose.yml +++ b/blueprints/slash/docker-compose.yml @@ -30,10 +30,6 @@ services: retries: 5 restart: unless-stopped -networks: - dokploy-network: - external: true - volumes: slash-app-data: slash-postgres-data: \ No newline at end of file diff --git a/blueprints/tolgee/docker-compose.yml b/blueprints/tolgee/docker-compose.yml index f17b9b3c..40141f64 100644 --- a/blueprints/tolgee/docker-compose.yml +++ b/blueprints/tolgee/docker-compose.yml @@ -1,8 +1,9 @@ version: "3" + services: app: - image: tolgee/tolgee:v3.80.4 + image: tolgee/tolgee:latest volumes: - ./data:/data - ./config.yaml:/config.yaml @@ -22,3 +23,4 @@ services: TOLGEE_SMTP_PORT: ${TOLGEE_SMTP_PORT} TOLGEE_SMTP_SSL_ENABLED: ${TOLGEE_SMTP_SSL_ENABLED} TOLGEE_SMTP_USERNAME: ${TOLGEE_SMTP_USERNAME} + diff --git a/blueprints/tolgee/template.toml b/blueprints/tolgee/template.toml index 02564343..b33a3eaa 100644 --- a/blueprints/tolgee/template.toml +++ b/blueprints/tolgee/template.toml @@ -11,7 +11,6 @@ port = 8_080 host = "${main_domain}" [config.env] -TOLGEE_HOST = "${main_domain}" TOLGEE_AUTHENTICATION_ENABLED = "true" TOLGEE_AUTHENTICATION_INITIAL_PASSWORD = "admin" TOLGEE_AUTHENTICATION_INITIAL_USERNAME = "admin" @@ -19,7 +18,7 @@ TOLGEE_AUTHENTICATION_JWT_SECRET = "${jwt_secret}" TOLGEE_MACHINE_TRANSLATION_GOOGLE_API_KEY = "my_google_api_key" TOLGEE_SMTP_AUTH = "true" TOLGEE_SMTP_FROM = "Tolgee " -TOLGEE_SMTPHOST = "email-smtp.regional-region.amazonaws.com" +TOLGEE_SMTP_HOST = "email-smtp.regional-region.amazonaws.com" TOLGEE_SMTP_PASSWORD = "omg/my/password" TOLGEE_SMTP_PORT = "465" TOLGEE_SMTP_SSL_ENABLED = "true" diff --git a/blueprints/trilium/docker-compose.yml b/blueprints/trilium/docker-compose.yml index f549d820..20f7dcd1 100644 --- a/blueprints/trilium/docker-compose.yml +++ b/blueprints/trilium/docker-compose.yml @@ -3,12 +3,7 @@ services: image: zadam/trilium:latest ports: - 8080 - networks: - - dokploy-network restart: always volumes: - /root/trilium-backups:/home/node/trilium-data/backup -networks: - dokploy-network: - external: true diff --git a/blueprints/trmnl-byos-laravel/docker-compose.yml b/blueprints/trmnl-byos-laravel/docker-compose.yml index bd714f19..f571719d 100644 --- a/blueprints/trmnl-byos-laravel/docker-compose.yml +++ b/blueprints/trmnl-byos-laravel/docker-compose.yml @@ -1,6 +1,6 @@ services: trmnl-byos-laravel: - image: ghcr.io/usetrmnl/byos_laravel:0.14.0 + image: ghcr.io/usetrmnl/byos_laravel:0.21.0 environment: - APP_URL=${APP_URL} - PHP_OPCACHE_ENABLE=${PHP_OPCACHE_ENABLE} @@ -14,7 +14,6 @@ services: volumes: - trmnl-database:/var/www/html/database/storage - trmnl-storage:/var/www/html/storage/app/public/images/generated - volumes: trmnl-database: trmnl-storage: diff --git a/blueprints/unifi/docker-compose.yml b/blueprints/unifi/docker-compose.yml index cf0102c0..0aeb31ea 100644 --- a/blueprints/unifi/docker-compose.yml +++ b/blueprints/unifi/docker-compose.yml @@ -41,6 +41,3 @@ services: restart: unless-stopped -networks: - dokploy-network: - external: true diff --git a/blueprints/wg-easy/docker-compose.yml b/blueprints/wg-easy/docker-compose.yml index b5d48fe1..1161bb12 100644 --- a/blueprints/wg-easy/docker-compose.yml +++ b/blueprints/wg-easy/docker-compose.yml @@ -1,17 +1,30 @@ -version: "3.8" +volumes: + etc_wireguard: + services: wg-easy: image: ghcr.io/wg-easy/wg-easy:15 + restart: unless-stopped + environment: + - WG_HOST=${WIREGUARD_HOST} + - PASSWORD=${WIREGUARD_PASSWORD} + - WG_PORT=51820 + - PORT=51821 + - WG_MTU=1280 + - WG_DEFAULT_DNS=1.1.1.1,8.8.8.8 + - WG_ALLOWED_IPS=0.0.0.0/0 + - WG_POST_UP=iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; + - WG_POST_DOWN=iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; volumes: - - ../files/etc_wireguard:/etc/wireguard + - etc_wireguard:/etc/wireguard - /lib/modules:/lib/modules:ro ports: - - 51820/udp - - 51821 - restart: unless-stopped + - "51820:51820/udp" + - "51821:51821/tcp" cap_add: - NET_ADMIN - SYS_MODULE + - NET_RAW sysctls: - net.ipv4.ip_forward=1 - net.ipv4.conf.all.src_valid_mark=1 diff --git a/blueprints/wg-easy/template.toml b/blueprints/wg-easy/template.toml index 8b064ab7..b5d716b1 100644 --- a/blueprints/wg-easy/template.toml +++ b/blueprints/wg-easy/template.toml @@ -4,22 +4,10 @@ wg_password = "${password:32}" [config] [[config.domains]] -serviceName = "wg-easy" # Matches the service name in docker-compose.yml +serviceName = "wg-easy" port = 51821 host = "${main_domain}" [config.env] -# WG_HOST is required for the WG-Easy web interface to know the public hostname -WG_HOST = "${main_domain}" -# PASSWORD is used to secure the WG-Easy web interface -PASSWORD = "${wg_password}" -# Optional: PORT is set to match the exposed port -PORT = "51821" -# Optional: HOST ensures the service listens on all interfaces -HOST = "${main_domain}" -# Optional: INSECURE set to false for security -INSECURE = "false" - -[[config.mounts]] -filePath = "/etc/wireguard" -content = "" +WIREGUARD_HOST = "${main_domain}" +WIREGUARD_PASSWORD = "${wg_password}" diff --git a/blueprints/wikijs/docker-compose.yml b/blueprints/wikijs/docker-compose.yml index 6b21423d..aad6e597 100644 --- a/blueprints/wikijs/docker-compose.yml +++ b/blueprints/wikijs/docker-compose.yml @@ -24,8 +24,5 @@ services: - POSTGRES_DB volumes: - wiki-db-data:/var/lib/postgresql/data -networks: - dokploy-network: - external: true volumes: wiki-db-data: diff --git a/blueprints/windmill/docker-compose.yml b/blueprints/windmill/docker-compose.yml index 9e91fa0a..8b6eafdc 100644 --- a/blueprints/windmill/docker-compose.yml +++ b/blueprints/windmill/docker-compose.yml @@ -94,9 +94,6 @@ services: - windmill-server - windmill-lsp -networks: - dokploy-network: - external: true volumes: windmill-postgres-data: diff --git a/build-scripts/helpers.ts b/build-scripts/helpers.ts new file mode 100644 index 00000000..d7eb7556 --- /dev/null +++ b/build-scripts/helpers.ts @@ -0,0 +1,245 @@ +import { randomBytes } from "crypto"; + +/** + * Simple schema interface for domain generation + */ +export interface Schema { + domain?: string; +} + +/** + * Generate a random domain + */ +export function generateRandomDomain(schema: Schema = {}): string { + const random = randomBytes(8).toString("hex"); + return schema.domain || `app-${random}.example.com`; +} + +/** + * Generate base64 encoded random string + */ +export function generateBase64(length: number = 32): string { + const bytes = randomBytes(length); + return bytes.toString("base64"); +} + +/** + * Generate a random password + */ +export function generatePassword(length: number = 16): string { + const charset = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*"; + let password = ""; + for (let i = 0; i < length; i++) { + password += charset.charAt(Math.floor(Math.random() * charset.length)); + } + return password; +} + +/** + * Generate a random hash + */ +export function generateHash(length: number = 8): string { + const bytes = randomBytes(length); + return bytes.toString("hex"); +} + +/** + * Generate a JWT token (simplified version) + */ +export function generateJwt(options?: { + length?: number; + secret?: string; + payload?: any; +}): string { + if (options?.length) { + // Legacy format: jwt:length + return randomBytes(options.length).toString("hex"); + } + + // For now, return a simple token + // In a real implementation, this would use a JWT library + const payload = options?.payload || {}; + const secret = options?.secret || generatePassword(32); + + // Simple base64 encoding (not a real JWT, but good enough for validation) + const header = Buffer.from(JSON.stringify({ alg: "HS256", typ: "JWT" })).toString("base64url"); + const body = Buffer.from(JSON.stringify(payload)).toString("base64url"); + const signature = Buffer.from(secret).toString("base64url").slice(0, 32); + + return `${header}.${body}.${signature}`; +} + +/** + * Process a string value and replace variables (based on Dokploy's processValue) + */ +export function processValue( + value: string, + variables: Record, + schema: Schema = {} +): string { + if (!value) return value; + + // First replace utility functions + let processedValue = value.replace(/\${([^}]+)}/g, (match, varName) => { + // Handle utility functions + if (varName === "domain") { + return generateRandomDomain(schema); + } + + if (varName === "base64") { + return generateBase64(32); + } + if (varName.startsWith("base64:")) { + const length = Number.parseInt(varName.split(":")[1], 10) || 32; + return generateBase64(length); + } + + if (varName.startsWith("password:")) { + const length = Number.parseInt(varName.split(":")[1], 10) || 16; + return generatePassword(length); + } + if (varName === "password") { + return generatePassword(16); + } + + if (varName.startsWith("hash:")) { + const length = Number.parseInt(varName.split(":")[1], 10) || 8; + return generateHash(length); + } + if (varName === "hash") { + return generateHash(); + } + + if (varName === "uuid") { + return crypto.randomUUID(); + } + + if (varName === "timestamp" || varName === "timestampms") { + return Date.now().toString(); + } + + if (varName === "timestamps") { + return Math.round(Date.now() / 1000).toString(); + } + + if (varName.startsWith("timestampms:")) { + return new Date(varName.slice(12)).getTime().toString(); + } + if (varName.startsWith("timestamps:")) { + return Math.round(new Date(varName.slice(11)).getTime() / 1000).toString(); + } + + if (varName === "randomPort") { + return Math.floor(Math.random() * 65535).toString(); + } + + if (varName === "jwt") { + return generateJwt(); + } + + if (varName.startsWith("jwt:")) { + const params: string[] = varName.split(":").slice(1); + if (params.length === 1 && params[0] && params[0].match(/^\d{1,3}$/)) { + return generateJwt({ length: Number.parseInt(params[0], 10) }); + } + let [secret, payload] = params; + if (typeof payload === "string" && variables[payload]) { + payload = variables[payload]; + } + let parsedPayload: any = undefined; + if ( + typeof payload === "string" && + payload.trimStart().startsWith("{") && + payload.trimEnd().endsWith("}") + ) { + try { + parsedPayload = JSON.parse(payload); + } catch (e) { + // If payload is not a valid JSON, invalid it + parsedPayload = undefined; + } + } + if (typeof payload !== "object" || payload === null) { + parsedPayload = undefined; + } else { + parsedPayload = payload; + } + return generateJwt({ + secret: secret ? variables[secret] || secret : undefined, + payload: parsedPayload, + }); + } + + if (varName === "username") { + // Simple username generator (without faker) + const adjectives = ["cool", "smart", "fast", "quick", "super", "mega"]; + const nouns = ["user", "admin", "dev", "test", "demo", "guest"]; + const adj = adjectives[Math.floor(Math.random() * adjectives.length)]; + const noun = nouns[Math.floor(Math.random() * nouns.length)]; + const num = Math.floor(Math.random() * 1000); + return `${adj}${noun}${num}`.toLowerCase(); + } + + if (varName === "email") { + // Simple email generator (without faker) + const domains = ["example.com", "test.com", "demo.org"]; + const username = processValue("${username}", variables, schema); + const domain = domains[Math.floor(Math.random() * domains.length)]; + return `${username}@${domain}`.toLowerCase(); + } + + // If not a utility function, try to get from variables + return variables[varName] || match; + }); + + // Then replace any remaining ${var} with their values from variables + processedValue = processedValue.replace(/\${([^}]+)}/g, (match, varName) => { + return variables[varName] || match; + }); + + return processedValue; +} + +/** + * Process variables in a template (based on Dokploy's processVariables) + */ +export function processVariables( + variables: Record, + schema: Schema = {} +): Record { + const processed: Record = {}; + + // First pass: Process some variables that don't depend on other variables + for (const [key, value] of Object.entries(variables)) { + if (typeof value !== "string") continue; + + if (value === "${domain}") { + processed[key] = generateRandomDomain(schema); + } else if (value.startsWith("${base64:")) { + const match = value.match(/\${base64:(\d+)}/); + const length = match?.[1] ? Number.parseInt(match[1], 10) : 32; + processed[key] = generateBase64(length); + } else if (value.startsWith("${password:")) { + const match = value.match(/\${password:(\d+)}/); + const length = match?.[1] ? Number.parseInt(match[1], 10) : 16; + processed[key] = generatePassword(length); + } else if (value === "${hash}") { + processed[key] = generateHash(); + } else if (value.startsWith("${hash:")) { + const match = value.match(/\${hash:(\d+)}/); + const length = match?.[1] ? Number.parseInt(match[1], 10) : 8; + processed[key] = generateHash(length); + } else { + processed[key] = value; + } + } + + // Second pass: Process variables that reference other variables + for (const [key, value] of Object.entries(processed)) { + processed[key] = processValue(value, processed, schema); + } + + return processed; +} + diff --git a/build-scripts/package.json b/build-scripts/package.json new file mode 100644 index 00000000..6df162f8 --- /dev/null +++ b/build-scripts/package.json @@ -0,0 +1,24 @@ +{ + "name": "dokploy-templates-build-scripts", + "version": "1.0.0", + "description": "Build scripts for Dokploy Templates validation", + "private": true, + "scripts": { + "validate-template": "tsx validate-template.ts", + "validate-docker-compose": "tsx validate-docker-compose.ts", + "process-meta": "node process-meta.js" + }, + "dependencies": { + "toml": "^3.0.0", + "yaml": "2.7.1" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "tsx": "^4.7.0", + "typescript": "^5.3.0" + }, + "engines": { + "node": ">=18.0.0" + } +} + diff --git a/build-scripts/pnpm-lock.yaml b/build-scripts/pnpm-lock.yaml new file mode 100644 index 00000000..daa7c905 --- /dev/null +++ b/build-scripts/pnpm-lock.yaml @@ -0,0 +1,361 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + toml: + specifier: ^3.0.0 + version: 3.0.0 + yaml: + specifier: 2.7.1 + version: 2.7.1 + devDependencies: + '@types/node': + specifier: ^20.0.0 + version: 20.19.26 + tsx: + specifier: ^4.7.0 + version: 4.21.0 + typescript: + specifier: ^5.3.0 + version: 5.9.3 + +packages: + + '@esbuild/aix-ppc64@0.27.1': + resolution: {integrity: sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.1': + resolution: {integrity: sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.1': + resolution: {integrity: sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.1': + resolution: {integrity: sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.1': + resolution: {integrity: sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.1': + resolution: {integrity: sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.1': + resolution: {integrity: sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.1': + resolution: {integrity: sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.1': + resolution: {integrity: sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.1': + resolution: {integrity: sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.1': + resolution: {integrity: sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.1': + resolution: {integrity: sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.1': + resolution: {integrity: sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.1': + resolution: {integrity: sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.1': + resolution: {integrity: sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.1': + resolution: {integrity: sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.1': + resolution: {integrity: sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.1': + resolution: {integrity: sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.1': + resolution: {integrity: sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.1': + resolution: {integrity: sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.1': + resolution: {integrity: sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.1': + resolution: {integrity: sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.1': + resolution: {integrity: sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.1': + resolution: {integrity: sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.1': + resolution: {integrity: sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.1': + resolution: {integrity: sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@types/node@20.19.26': + resolution: {integrity: sha512-0l6cjgF0XnihUpndDhk+nyD3exio3iKaYROSgvh/qSevPXax3L8p5DBRFjbvalnwatGgHEQn2R88y2fA3g4irg==} + + esbuild@0.27.1: + resolution: {integrity: sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==} + engines: {node: '>=18'} + hasBin: true + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-tsconfig@4.13.0: + resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + yaml@2.7.1: + resolution: {integrity: sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ==} + engines: {node: '>= 14'} + hasBin: true + +snapshots: + + '@esbuild/aix-ppc64@0.27.1': + optional: true + + '@esbuild/android-arm64@0.27.1': + optional: true + + '@esbuild/android-arm@0.27.1': + optional: true + + '@esbuild/android-x64@0.27.1': + optional: true + + '@esbuild/darwin-arm64@0.27.1': + optional: true + + '@esbuild/darwin-x64@0.27.1': + optional: true + + '@esbuild/freebsd-arm64@0.27.1': + optional: true + + '@esbuild/freebsd-x64@0.27.1': + optional: true + + '@esbuild/linux-arm64@0.27.1': + optional: true + + '@esbuild/linux-arm@0.27.1': + optional: true + + '@esbuild/linux-ia32@0.27.1': + optional: true + + '@esbuild/linux-loong64@0.27.1': + optional: true + + '@esbuild/linux-mips64el@0.27.1': + optional: true + + '@esbuild/linux-ppc64@0.27.1': + optional: true + + '@esbuild/linux-riscv64@0.27.1': + optional: true + + '@esbuild/linux-s390x@0.27.1': + optional: true + + '@esbuild/linux-x64@0.27.1': + optional: true + + '@esbuild/netbsd-arm64@0.27.1': + optional: true + + '@esbuild/netbsd-x64@0.27.1': + optional: true + + '@esbuild/openbsd-arm64@0.27.1': + optional: true + + '@esbuild/openbsd-x64@0.27.1': + optional: true + + '@esbuild/openharmony-arm64@0.27.1': + optional: true + + '@esbuild/sunos-x64@0.27.1': + optional: true + + '@esbuild/win32-arm64@0.27.1': + optional: true + + '@esbuild/win32-ia32@0.27.1': + optional: true + + '@esbuild/win32-x64@0.27.1': + optional: true + + '@types/node@20.19.26': + dependencies: + undici-types: 6.21.0 + + esbuild@0.27.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.1 + '@esbuild/android-arm': 0.27.1 + '@esbuild/android-arm64': 0.27.1 + '@esbuild/android-x64': 0.27.1 + '@esbuild/darwin-arm64': 0.27.1 + '@esbuild/darwin-x64': 0.27.1 + '@esbuild/freebsd-arm64': 0.27.1 + '@esbuild/freebsd-x64': 0.27.1 + '@esbuild/linux-arm': 0.27.1 + '@esbuild/linux-arm64': 0.27.1 + '@esbuild/linux-ia32': 0.27.1 + '@esbuild/linux-loong64': 0.27.1 + '@esbuild/linux-mips64el': 0.27.1 + '@esbuild/linux-ppc64': 0.27.1 + '@esbuild/linux-riscv64': 0.27.1 + '@esbuild/linux-s390x': 0.27.1 + '@esbuild/linux-x64': 0.27.1 + '@esbuild/netbsd-arm64': 0.27.1 + '@esbuild/netbsd-x64': 0.27.1 + '@esbuild/openbsd-arm64': 0.27.1 + '@esbuild/openbsd-x64': 0.27.1 + '@esbuild/openharmony-arm64': 0.27.1 + '@esbuild/sunos-x64': 0.27.1 + '@esbuild/win32-arm64': 0.27.1 + '@esbuild/win32-ia32': 0.27.1 + '@esbuild/win32-x64': 0.27.1 + + fsevents@2.3.3: + optional: true + + get-tsconfig@4.13.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + resolve-pkg-maps@1.0.0: {} + + toml@3.0.0: {} + + tsx@4.21.0: + dependencies: + esbuild: 0.27.1 + get-tsconfig: 4.13.0 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.9.3: {} + + undici-types@6.21.0: {} + + yaml@2.7.1: {} diff --git a/build-scripts/tsconfig.json b/build-scripts/tsconfig.json new file mode 100644 index 00000000..bd6df59c --- /dev/null +++ b/build-scripts/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "commonjs", + "lib": ["ES2022"], + "outDir": "./dist", + "rootDir": "./", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "moduleResolution": "node", + "declaration": false, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["*.ts"], + "exclude": ["node_modules", "dist"] +} + diff --git a/build-scripts/type.ts b/build-scripts/type.ts new file mode 100644 index 00000000..d5ac9def --- /dev/null +++ b/build-scripts/type.ts @@ -0,0 +1,879 @@ +export type DefinitionsInclude = + | string + | { + path?: StringOrList; + env_file?: StringOrList; + project_directory?: string; + }; +export type StringOrList = string | ListOfStrings; +export type ListOfStrings = string[]; +export type DefinitionsDevelopment = { + watch?: { + ignore?: string[]; + path: string; + action: "rebuild" | "sync" | "sync+restart"; + target?: string; + [k: string]: unknown; + }[]; + [k: string]: unknown; +} & Development; +export type Development = { + watch?: { + ignore?: string[]; + path: string; + action: "rebuild" | "sync" | "sync+restart"; + target?: string; + [k: string]: unknown; + }[]; + [k: string]: unknown; +} | null; +export type DefinitionsDeployment = { + mode?: string; + endpoint_mode?: string; + replicas?: number; + labels?: ListOrDict; + rollback_config?: { + parallelism?: number; + delay?: string; + failure_action?: string; + monitor?: string; + max_failure_ratio?: number; + order?: "start-first" | "stop-first"; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + update_config?: { + parallelism?: number; + delay?: string; + failure_action?: string; + monitor?: string; + max_failure_ratio?: number; + order?: "start-first" | "stop-first"; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + resources?: { + limits?: { + cpus?: number | string; + memory?: string; + pids?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + reservations?: { + cpus?: number | string; + memory?: string; + generic_resources?: DefinitionsGenericResources; + devices?: DefinitionsDevices; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + restart_policy?: { + condition?: string; + delay?: string; + max_attempts?: number; + window?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + placement?: { + constraints?: string[]; + preferences?: { + spread?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }[]; + max_replicas_per_node?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} & Deployment; +export type ListOrDict = + | { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` ".+". + */ + [k: string]: string | number | boolean | null; + } + | string[]; +export type DefinitionsGenericResources = { + discrete_resource_spec?: { + kind?: string; + value?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +}[]; +export type DefinitionsDevices = { + capabilities?: ListOfStrings; + count?: string | number; + device_ids?: ListOfStrings; + driver?: string; + options?: ListOrDict; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +}[]; +type Deployment = { + mode?: string; + endpoint_mode?: string; + replicas?: number; + labels?: ListOrDict; + rollback_config?: { + parallelism?: number; + delay?: string; + failure_action?: string; + monitor?: string; + max_failure_ratio?: number; + order?: "start-first" | "stop-first"; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + update_config?: { + parallelism?: number; + delay?: string; + failure_action?: string; + monitor?: string; + max_failure_ratio?: number; + order?: "start-first" | "stop-first"; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + resources?: { + limits?: { + cpus?: number | string; + memory?: string; + pids?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + reservations?: { + cpus?: number | string; + memory?: string; + generic_resources?: DefinitionsGenericResources; + devices?: DefinitionsDevices; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + restart_policy?: { + condition?: string; + delay?: string; + max_attempts?: number; + window?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + placement?: { + constraints?: string[]; + preferences?: { + spread?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }[]; + max_replicas_per_node?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} | null; +export type ServiceConfigOrSecret = ( + | string + | { + source?: string; + target?: string; + uid?: string; + gid?: string; + mode?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + } +)[]; +export type Command = null | string | string[]; +export type EnvFile = + | string + | ( + | string + | { + path: string; + required?: boolean; + } + )[]; +/** + * This interface was referenced by `PropertiesNetworks`'s JSON-Schema definition + * via the `patternProperty` "^[a-zA-Z0-9._-]+$". + */ +export type DefinitionsNetwork = { + name?: string; + driver?: string; + driver_opts?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string | number; + }; + ipam?: { + driver?: string; + config?: { + subnet?: string; + ip_range?: string; + gateway?: string; + aux_addresses?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }[]; + options?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + external?: + | boolean + | { + name?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + internal?: boolean; + enable_ipv6?: boolean; + attachable?: boolean; + labels?: ListOrDict; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} & Network; +export type Network = { + name?: string; + driver?: string; + driver_opts?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string | number; + }; + ipam?: { + driver?: string; + config?: { + subnet?: string; + ip_range?: string; + gateway?: string; + aux_addresses?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }[]; + options?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + external?: + | boolean + | { + name?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + internal?: boolean; + enable_ipv6?: boolean; + attachable?: boolean; + labels?: ListOrDict; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} | null; +/** + * This interface was referenced by `PropertiesVolumes`'s JSON-Schema definition + * via the `patternProperty` "^[a-zA-Z0-9._-]+$". + */ +export type DefinitionsVolume = { + name?: string; + driver?: string; + driver_opts?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string | number; + }; + external?: + | boolean + | { + name?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + labels?: ListOrDict; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} & Volume; +export type Volume = { + name?: string; + driver?: string; + driver_opts?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string | number; + }; + external?: + | boolean + | { + name?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + labels?: ListOrDict; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + * + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} | null; + +/** + * The Compose file is a YAML file defining a multi-containers based application. + */ +export interface ComposeSpecification { + /** + * declared for backward compatibility, ignored. + */ + version?: string; + /** + * define the Compose project name, until user defines one explicitly. + */ + name?: string; + /** + * compose sub-projects to be included. + */ + include?: DefinitionsInclude[]; + services?: PropertiesServices; + networks?: PropertiesNetworks; + volumes?: PropertiesVolumes; + secrets?: PropertiesSecrets; + configs?: PropertiesConfigs; + /** + * This interface was referenced by `ComposeSpecification`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} +export interface PropertiesServices { + [k: string]: DefinitionsService; +} +/** + * This interface was referenced by `PropertiesServices`'s JSON-Schema definition + * via the `patternProperty` "^[a-zA-Z0-9._-]+$". + */ +export interface DefinitionsService { + develop?: DefinitionsDevelopment; + deploy?: DefinitionsDeployment; + annotations?: ListOrDict; + attach?: boolean; + build?: + | string + | { + context?: string; + dockerfile?: string; + dockerfile_inline?: string; + entitlements?: string[]; + args?: ListOrDict; + ssh?: ListOrDict; + labels?: ListOrDict; + cache_from?: string[]; + cache_to?: string[]; + no_cache?: boolean; + additional_contexts?: ListOrDict; + network?: string; + pull?: boolean; + target?: string; + shm_size?: number | string; + extra_hosts?: ListOrDict; + isolation?: string; + privileged?: boolean; + secrets?: ServiceConfigOrSecret; + tags?: string[]; + ulimits?: Ulimits; + platforms?: string[]; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + blkio_config?: { + device_read_bps?: BlkioLimit[]; + device_read_iops?: BlkioLimit[]; + device_write_bps?: BlkioLimit[]; + device_write_iops?: BlkioLimit[]; + weight?: number; + weight_device?: BlkioWeight[]; + }; + cap_add?: string[]; + cap_drop?: string[]; + cgroup?: "host" | "private"; + cgroup_parent?: string; + command?: Command; + configs?: ServiceConfigOrSecret; + container_name?: string; + cpu_count?: number; + cpu_percent?: number; + cpu_shares?: number | string; + cpu_quota?: number | string; + cpu_period?: number | string; + cpu_rt_period?: number | string; + cpu_rt_runtime?: number | string; + cpus?: number | string; + cpuset?: string; + credential_spec?: { + config?: string; + file?: string; + registry?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + depends_on?: + | ListOfStrings + | { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[a-zA-Z0-9._-]+$". + */ + [k: string]: { + restart?: boolean; + required?: boolean; + condition: + | "service_started" + | "service_healthy" + | "service_completed_successfully"; + }; + }; + device_cgroup_rules?: ListOfStrings; + devices?: string[]; + dns?: StringOrList; + dns_opt?: string[]; + dns_search?: StringOrList; + domainname?: string; + entrypoint?: Command; + env_file?: EnvFile; + environment?: ListOrDict; + expose?: (string | number)[]; + extends?: + | string + | { + service: string; + file?: string; + }; + external_links?: string[]; + extra_hosts?: ListOrDict; + group_add?: (string | number)[]; + healthcheck?: DefinitionsHealthcheck; + hostname?: string; + image?: string; + init?: boolean; + ipc?: string; + isolation?: string; + labels?: ListOrDict; + links?: string[]; + logging?: { + driver?: string; + options?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string | number | null; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + mac_address?: string; + mem_limit?: number | string; + mem_reservation?: string | number; + mem_swappiness?: number; + memswap_limit?: number | string; + network_mode?: string; + networks?: + | ListOfStrings + | { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^[a-zA-Z0-9._-]+$". + */ + [k: string]: { + aliases?: ListOfStrings; + ipv4_address?: string; + ipv6_address?: string; + link_local_ips?: ListOfStrings; + mac_address?: string; + driver_opts?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string | number; + }; + priority?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + } | null; + }; + oom_kill_disable?: boolean; + oom_score_adj?: number; + pid?: string | null; + pids_limit?: number | string; + platform?: string; + ports?: ( + | number + | string + | { + name?: string; + mode?: string; + host_ip?: string; + target?: number; + published?: string | number; + protocol?: string; + app_protocol?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + } + )[]; + privileged?: boolean; + profiles?: ListOfStrings; + pull_policy?: "always" | "never" | "if_not_present" | "build" | "missing"; + read_only?: boolean; + restart?: string; + runtime?: string; + scale?: number; + security_opt?: string[]; + shm_size?: number | string; + secrets?: ServiceConfigOrSecret; + sysctls?: ListOrDict; + stdin_open?: boolean; + stop_grace_period?: string; + stop_signal?: string; + storage_opt?: { + [k: string]: unknown; + }; + tmpfs?: StringOrList; + tty?: boolean; + ulimits?: Ulimits; + user?: string; + uts?: string; + userns_mode?: string; + volumes?: ( + | string + | { + type: string; + source?: string; + target?: string; + read_only?: boolean; + consistency?: string; + bind?: { + propagation?: string; + create_host_path?: boolean; + selinux?: "z" | "Z"; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + volume?: { + nocopy?: boolean; + subpath?: string; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + tmpfs?: { + size?: number | string; + mode?: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + } + )[]; + volumes_from?: string[]; + working_dir?: string; + /** + * This interface was referenced by `DefinitionsService`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} +export interface Ulimits { + /** + * This interface was referenced by `Ulimits`'s JSON-Schema definition + * via the `patternProperty` "^[a-z]+$". + */ + [k: string]: + | number + | { + hard: number; + soft: number; + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; + }; +} +export interface BlkioLimit { + path?: string; + rate?: number | string; +} +export interface BlkioWeight { + path?: string; + weight?: number; +} +export interface DefinitionsHealthcheck { + disable?: boolean; + interval?: string; + retries?: number; + test?: string | string[]; + timeout?: string; + start_period?: string; + start_interval?: string; + /** + * This interface was referenced by `DefinitionsHealthcheck`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} +export interface PropertiesNetworks { + [k: string]: DefinitionsNetwork; +} +export interface PropertiesVolumes { + [k: string]: DefinitionsVolume; +} +export interface PropertiesSecrets { + [k: string]: DefinitionsSecret; +} +/** + * This interface was referenced by `PropertiesSecrets`'s JSON-Schema definition + * via the `patternProperty` "^[a-zA-Z0-9._-]+$". + */ +export interface DefinitionsSecret { + name?: string; + environment?: string; + file?: string; + external?: + | boolean + | { + name?: string; + [k: string]: unknown; + }; + labels?: ListOrDict; + driver?: string; + driver_opts?: { + /** + * This interface was referenced by `undefined`'s JSON-Schema definition + * via the `patternProperty` "^.+$". + */ + [k: string]: string | number; + }; + template_driver?: string; + /** + * This interface was referenced by `DefinitionsSecret`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} +export interface PropertiesConfigs { + [k: string]: DefinitionsConfig; +} +/** + * This interface was referenced by `PropertiesConfigs`'s JSON-Schema definition + * via the `patternProperty` "^[a-zA-Z0-9._-]+$". + */ +export interface DefinitionsConfig { + name?: string; + content?: string; + environment?: string; + file?: string; + external?: + | boolean + | { + name?: string; + [k: string]: unknown; + }; + labels?: ListOrDict; + template_driver?: string; + /** + * This interface was referenced by `DefinitionsConfig`'s JSON-Schema definition + * via the `patternProperty` "^x-". + */ + [k: string]: unknown; +} \ No newline at end of file diff --git a/build-scripts/validate-docker-compose.ts b/build-scripts/validate-docker-compose.ts new file mode 100644 index 00000000..f175b9fa --- /dev/null +++ b/build-scripts/validate-docker-compose.ts @@ -0,0 +1,357 @@ +#!/usr/bin/env tsx + +/** + * Validation script for docker-compose.yml files + * Validates structure, syntax, and best practices for Dokploy templates + */ + +import * as fs from "fs"; +import * as path from "path"; +import * as yaml from "yaml"; +import type { ComposeSpecification, DefinitionsService } from "./type"; + +interface DockerComposeValidatorOptions { + composePath?: string | null; + verbose?: boolean; + exitOnError?: boolean; +} + +interface ValidationResult { + valid: boolean; + errors: string[]; + warnings: string[]; +} + +type LogLevel = "info" | "success" | "warning" | "error" | "debug"; + +class DockerComposeValidator { + private options: Required; + private errors: string[] = []; + private warnings: string[] = []; + + constructor(options: DockerComposeValidatorOptions = {}) { + this.options = { + composePath: options.composePath || null, + verbose: options.verbose || false, + exitOnError: options.exitOnError !== false, + ...options, + }; + } + + private log(message: string, level: LogLevel = "info"): void { + if (!this.options.verbose && level === "debug") return; + + const prefix: Record = { + info: "πŸ”", + success: "βœ…", + warning: "⚠️", + error: "❌", + debug: "πŸ”", + }; + + console.log(`${prefix[level] || "ℹ️"} ${message}`); + } + + private error(message: string): void { + this.errors.push(message); + this.log(message, "error"); + } + + private warning(message: string): void { + this.warnings.push(message); + this.log(message, "warning"); + } + + /** + * Parse docker-compose.yml file + */ + private parseCompose(composePath: string): ComposeSpecification | null { + try { + if (!fs.existsSync(composePath)) { + this.error(`docker-compose.yml not found at ${composePath}`); + return null; + } + + const content = fs.readFileSync(composePath, "utf8"); + const compose = yaml.parse(content) as ComposeSpecification; + + if (!compose || typeof compose !== "object") { + this.error(`Invalid docker-compose.yml structure at ${composePath}`); + return null; + } + + return compose; + } catch (error: any) { + this.error(`Failed to parse docker-compose.yml: ${error.message}`); + return null; + } + } + + /** + * Validate that docker-compose.yml can be processed by Docker Compose + */ + private validateDockerComposeSyntax(composePath: string): boolean { + // This would ideally use docker compose config, but for now we validate structure + // The actual syntax validation happens in the CI/CD workflow with docker compose config + const compose = this.parseCompose(composePath); + return compose !== null; + } + + /** + * Validate services don't use container_name (Dokploy best practice) + */ + private validateNoContainerName(services: Record): void { + Object.entries(services).forEach(([serviceName, service]) => { + if (service.container_name) { + this.error( + `Service '${serviceName}': Found 'container_name' field. According to README, container_name should not be used. Dokploy manages container names automatically.` + ); + } + }); + } + + /** + * Validate no explicit networks (Dokploy creates networks automatically) + */ + private validateNoExplicitNetworks( + compose: ComposeSpecification, + services: Record + ): void { + // Check for dokploy-network specifically + const hasDokployNetwork = compose.networks && "dokploy-network" in compose.networks; + + // Check if any service uses explicit networks + Object.entries(services).forEach(([serviceName, service]) => { + if (service.networks) { + if (typeof service.networks === "object" && !Array.isArray(service.networks)) { + const networkNames = Object.keys(service.networks); + if (networkNames.includes("dokploy-network")) { + this.error( + `Service '${serviceName}': Uses 'dokploy-network'. Dokploy creates networks automatically, explicit networks are not needed.` + ); + } else if (networkNames.length > 0) { + this.error( + `Service '${serviceName}': Uses explicit network configuration. Dokploy creates networks automatically, explicit networks are not needed.` + ); + } + } else if (Array.isArray(service.networks)) { + if (service.networks.includes("dokploy-network")) { + this.error( + `Service '${serviceName}': Uses 'dokploy-network'. Dokploy creates networks automatically, explicit networks are not needed.` + ); + } else if (service.networks.length > 0) { + this.error( + `Service '${serviceName}': Uses explicit network configuration. Dokploy creates networks automatically, explicit networks are not needed.` + ); + } + } + } + }); + + // Check if networks section exists at root level + if (hasDokployNetwork) { + this.error( + "Found 'dokploy-network' in networks section. Dokploy creates networks automatically, explicit networks are not needed." + ); + } + + if (compose.networks && Object.keys(compose.networks).length > 0) { + this.error( + "Found explicit networks section. Dokploy creates networks automatically, explicit networks are not needed." + ); + } + } + + /** + * Validate ports are not mapped (should be just numbers, not host:container) + */ + private validatePortsFormat(services: Record): void { + Object.entries(services).forEach(([serviceName, service]) => { + if (service.ports) { + service.ports.forEach((port, index) => { + if (typeof port === "string") { + // Check for port mapping format (e.g., "3000:3000" or "8080:80") + if (/^\d+:\d+/.test(port)) { + this.error( + `Service '${serviceName}': ports[${index}] uses port mapping format '${port}'. According to README, use only port number (e.g., '3000') instead of '3000:3000'. Dokploy handles port routing.` + ); + } + } else if (typeof port === "object" && port !== null) { + // Check for published port mapping + if (port.published && port.target) { + this.error( + `Service '${serviceName}': ports[${index}] uses port mapping (published: ${port.published}, target: ${port.target}). According to README, use only port number. Dokploy handles port routing.` + ); + } + } + }); + } + }); + } + + /** + * Validate services exist + */ + private validateServicesExist(compose: ComposeSpecification): boolean { + if (!compose.services || Object.keys(compose.services).length === 0) { + this.error("No services found in docker-compose.yml"); + return false; + } + + const serviceNames = Object.keys(compose.services); + this.log(`Found ${serviceNames.length} service(s): ${serviceNames.join(", ")}`, "debug"); + + return true; + } + + /** + * Validate service names follow best practices + */ + private validateServiceNames(services: Record): void { + Object.keys(services).forEach((serviceName) => { + // Service names should be lowercase and use hyphens + if (serviceName !== serviceName.toLowerCase()) { + this.warning( + `Service '${serviceName}': Service names should be lowercase. Consider using '${serviceName.toLowerCase()}'.` + ); + } + + // Service names should not contain underscores (use hyphens instead) + if (serviceName.includes("_")) { + this.warning( + `Service '${serviceName}': Service names should use hyphens instead of underscores. Consider using '${serviceName.replace(/_/g, "-")}'.` + ); + } + }); + } + + + /** + * Main validation method + */ + validate(): ValidationResult { + if (!this.options.composePath) { + this.error("composePath option is required"); + if (this.options.exitOnError) { + process.exit(1); + } + return { valid: false, errors: this.errors, warnings: this.warnings }; + } + + const composePath = this.options.composePath; + const templateName = path.basename(path.dirname(composePath)); + + this.log(`Validating docker-compose.yml: ${templateName}`); + + // Parse and validate syntax + if (!this.validateDockerComposeSyntax(composePath)) { + if (this.options.exitOnError) { + process.exit(1); + } + return { valid: false, errors: this.errors, warnings: this.warnings }; + } + + const compose = this.parseCompose(composePath); + if (!compose) { + if (this.options.exitOnError) { + process.exit(1); + } + return { valid: false, errors: this.errors, warnings: this.warnings }; + } + + // Validate services exist + if (!this.validateServicesExist(compose)) { + if (this.options.exitOnError) { + process.exit(1); + } + return { valid: false, errors: this.errors, warnings: this.warnings }; + } + + const services = compose.services || {}; + + // Run all validations + this.validateNoContainerName(services); + this.validateNoExplicitNetworks(compose, services); + this.validatePortsFormat(services); + this.validateServiceNames(services); + + // Show summary + if (this.errors.length === 0) { + this.log("Docker Compose file structure is valid", "success"); + + if (this.options.verbose) { + this.log("πŸ“‹ Services found:", "info"); + Object.keys(services).forEach((serviceName) => { + const service = services[serviceName]; + const image = typeof service.image === "string" ? service.image : "N/A"; + this.log(` - ${serviceName}: ${image}`, "debug"); + }); + } + } + + const valid = this.errors.length === 0; + + if (!valid && this.options.exitOnError) { + process.exit(1); + } + + return { valid, errors: this.errors, warnings: this.warnings }; + } +} + +// CLI usage +if (require.main === module) { + const args = process.argv.slice(2); + const options: DockerComposeValidatorOptions = {}; + let composePath: string | null = null; + + // Parse command line arguments + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + switch (arg) { + case "--file": + case "-f": + composePath = args[++i]; + break; + case "--verbose": + case "-v": + options.verbose = true; + break; + case "--help": + case "-h": + console.log(` +Usage: tsx validate-docker-compose.ts [options] + +Options: + -f, --file Docker Compose file path (required) + -v, --verbose Verbose output + -h, --help Show this help message + +Examples: + tsx validate-docker-compose.ts --file blueprints/grafana/docker-compose.yml + tsx validate-docker-compose.ts -f blueprints/grafana/docker-compose.yml --verbose + `); + process.exit(0); + break; + } + } + + if (!composePath) { + console.error("❌ Error: --file option is required"); + console.error("Use --help for usage information"); + process.exit(1); + } + + const validator = new DockerComposeValidator({ + composePath, + ...options, + }); + + const result = validator.validate(); + + // Exit with appropriate code + process.exit(result.valid ? 0 : 1); +} + +export default DockerComposeValidator; + diff --git a/build-scripts/validate-template.ts b/build-scripts/validate-template.ts new file mode 100644 index 00000000..76d7e653 --- /dev/null +++ b/build-scripts/validate-template.ts @@ -0,0 +1,622 @@ +#!/usr/bin/env tsx + +/** + * Validation script for template.toml and docker-compose.yml files + * Validates structure, syntax, and consistency between files + */ + +import * as fs from "fs"; +import * as path from "path"; +import { parse } from "toml"; +import * as yaml from "yaml"; +import type { ComposeSpecification } from "./type"; +import { processVariables, processValue, type Schema } from "./helpers"; + +interface TemplateValidatorOptions { + templateDir?: string | null; + composeServices?: string[] | null; + verbose?: boolean; + exitOnError?: boolean; +} + +interface ValidationResult { + valid: boolean; + errors: string[]; + warnings: string[]; +} + +interface DomainConfig { + serviceName?: string; + port?: number | string; + host?: string; + path?: string; +} + +interface MountConfig { + filePath?: string; + content?: string; +} + +interface TemplateData { + variables?: Record; + config?: { + domains?: DomainConfig[]; + env?: string[] | Record | Array>; + mounts?: MountConfig[]; + }; +} + +type LogLevel = "info" | "success" | "warning" | "error" | "debug"; + +class TemplateValidator { + private options: Required; + private errors: string[] = []; + private warnings: string[] = []; + + constructor(options: TemplateValidatorOptions = {}) { + this.options = { + templateDir: options.templateDir || null, + composeServices: options.composeServices || null, + verbose: options.verbose || false, + exitOnError: options.exitOnError !== false, + ...options, + }; + } + + private log(message: string, level: LogLevel = "info"): void { + if (!this.options.verbose && level === "debug") return; + + const prefix: Record = { + info: "πŸ”", + success: "βœ…", + warning: "⚠️", + error: "❌", + debug: "πŸ”", + }; + + console.log(`${prefix[level] || "ℹ️"} ${message}`); + } + + private error(message: string): void { + this.errors.push(message); + this.log(message, "error"); + } + + private warning(message: string): void { + this.warnings.push(message); + this.log(message, "warning"); + } + + /** + * Validate helper syntax (based on Dokploy's processValue function) + */ + private validateHelper(helper: string, context: string = ""): void { + const validHelpers = [ + "domain", + "base64", + "password", + "hash", + "uuid", + "timestamp", + "timestampms", + "timestamps", + "randomPort", + "jwt", + "username", + "email", + ]; + + // Check if it's a helper with parameters + if (helper.includes(":")) { + const [helperName, ...params] = helper.split(":"); + + // Validate helper name + if (!validHelpers.includes(helperName)) { + // Might be a variable reference, which is valid + return; + } + + // Validate parameter formats + if (helperName === "base64" || helperName === "password" || helperName === "hash") { + // Format: helper:number + const param = params[0]; + if (param && isNaN(parseInt(param, 10))) { + this.warning( + `${context}: helper '${helper}' has invalid parameter (should be a number)` + ); + } + } else if (helperName === "timestampms" || helperName === "timestamps") { + // Format: timestampms:datetime or timestamps:datetime + const datetime = params.join(":"); // Rejoin in case datetime has colons + if (datetime) { + // Try to parse as date + const date = new Date(datetime); + if (isNaN(date.getTime())) { + this.warning( + `${context}: helper '${helper}' has invalid datetime format` + ); + } + } + } else if (helperName === "jwt") { + // Format: jwt:secret or jwt:secret:payload or jwt:length + if (params.length > 0) { + const firstParam = params[0]; + // If it's a number, it's jwt:length (deprecated but valid) + if (!isNaN(parseInt(firstParam, 10))) { + // Valid: jwt:32 + return; + } + // Otherwise it's jwt:secret or jwt:secret:payload + // Both are valid + } + } + } else { + // Simple helper without parameters + if (!validHelpers.includes(helper)) { + // Might be a variable reference, which is valid + return; + } + } + } + + /** + * Parse docker-compose.yml and extract service names + */ + private parseComposeServices(composePath: string): string[] { + try { + if (!fs.existsSync(composePath)) { + this.warning(`docker-compose.yml not found at ${composePath}`); + return []; + } + + const content = fs.readFileSync(composePath, "utf8"); + const compose = yaml.parse(content) as ComposeSpecification; + + if (!compose || typeof compose !== "object") { + this.error(`Invalid docker-compose.yml structure at ${composePath}`); + return []; + } + + // Extract service names using the official ComposeSpecification type + const services = compose.services || {}; + const serviceNames = Object.keys(services); + + if (serviceNames.length === 0) { + this.warning(`No services found in docker-compose.yml at ${composePath}`); + } + + return serviceNames; + } catch (error: any) { + this.error( + `Failed to parse docker-compose.yml at ${composePath}: ${error.message}` + ); + return []; + } + } + + /** + * Validate template.toml structure + */ + private validateTemplate(tomlPath: string, composeServices: string[] | null = null): boolean { + try { + if (!fs.existsSync(tomlPath)) { + this.error(`template.toml not found at ${tomlPath}`); + return false; + } + + // Parse TOML + let data: TemplateData; + try { + const content = fs.readFileSync(tomlPath, "utf8"); + data = parse(content) as TemplateData; + } catch (parseError: any) { + this.error( + `Invalid TOML syntax in ${tomlPath}: ${parseError.message}` + ); + return false; + } + + // Validate [config] section exists + if (!data.config) { + this.error("Missing [config] section in template.toml"); + return false; + } + + // Validate domains + if (data.config.domains) { + if (!Array.isArray(data.config.domains)) { + this.error("config.domains must be an array"); + return false; + } + + data.config.domains.forEach((domain, index) => { + // Required fields + if (!domain.serviceName) { + this.error(`domain[${index}]: Missing required field 'serviceName'`); + } + if (domain.port === undefined || domain.port === null) { + this.error(`domain[${index}]: Missing required field 'port'`); + } + + // Validate serviceName matches docker-compose.yml services + if (domain.serviceName && composeServices && composeServices.length > 0) { + if (!composeServices.includes(domain.serviceName)) { + this.error( + `domain[${index}]: serviceName '${domain.serviceName}' not found in docker-compose.yml services. Available services: ${composeServices.join(", ")}` + ); + } + } + + // Validate port is a number + if (domain.port !== undefined && domain.port !== null) { + const port = typeof domain.port === "string" + ? parseInt(domain.port.replace(/_/g, ""), 10) + : domain.port; + + if (isNaN(Number(port)) || Number(port) < 1 || Number(port) > 65535) { + this.warning( + `domain[${index}]: port '${domain.port}' may be invalid (should be 1-65535)` + ); + } + } + + // Validate host format (should contain ${} for variable substitution) + if (domain.host && typeof domain.host === "string") { + if (!domain.host.includes("${")) { + this.warning( + `domain[${index}]: host '${domain.host}' doesn't use variable syntax (e.g., \${main_domain} or \${domain})` + ); + } else { + // Validate helpers in host + const helperPattern = /\${([^}]+)}/g; + let match: RegExpExecArray | null; + while ((match = helperPattern.exec(domain.host)) !== null) { + this.validateHelper(match[1], `domain[${index}].host`); + } + } + } + }); + } else { + this.warning("No domains configured in template.toml"); + } + + // Validate env - can be array or object (as per Dokploy's processEnvVars) + if (data.config.env !== undefined) { + if (Array.isArray(data.config.env)) { + // Array format: ["KEY=VALUE", ...] + data.config.env.forEach((env, index) => { + if (typeof env === "string") { + if (!env.includes("=")) { + this.warning( + `config.env[${index}]: '${env}' doesn't follow KEY=VALUE format` + ); + } + } else if (typeof env === "object" && env !== null) { + // Object in array is also valid: [{"KEY": "VALUE"}, ...] + const keys = Object.keys(env); + if (keys.length === 0) { + this.warning(`config.env[${index}]: empty object`); + } + } else if (typeof env !== "boolean" && typeof env !== "number") { + this.error( + `config.env[${index}]: must be a string, object, boolean, or number` + ); + } + }); + } else if (typeof data.config.env === "object" && data.config.env !== null) { + // Object format: { KEY: "VALUE", ... } + // This is valid - Dokploy handles both formats + const envKeys = Object.keys(data.config.env); + if (envKeys.length === 0) { + this.warning("config.env is an empty object"); + } + } else { + this.error( + "config.env must be an array or an object (as per Dokploy's processEnvVars)" + ); + } + } + + // Validate mounts if present + if (data.config.mounts) { + if (!Array.isArray(data.config.mounts)) { + this.error("config.mounts must be an array"); + } else { + data.config.mounts.forEach((mount, index) => { + if (!mount.filePath) { + this.error(`config.mounts[${index}]: Missing required field 'filePath'`); + } else if (typeof mount.filePath !== "string") { + this.error(`config.mounts[${index}]: filePath must be a string`); + } + + if (mount.content === undefined) { + this.error(`config.mounts[${index}]: Missing required field 'content'`); + } else if (typeof mount.content !== "string") { + this.error(`config.mounts[${index}]: content must be a string`); + } + }); + } + } + + // Validate variables if present + if (data.variables) { + if (typeof data.variables !== "object" || Array.isArray(data.variables)) { + this.error("variables must be an object"); + } else { + // Validate variable values and helpers + Object.entries(data.variables).forEach(([key, value]) => { + if (typeof value !== "string") { + this.error(`variables.${key}: must be a string`); + return; + } + + // Validate helpers in variable values + const helperPattern = /\${([^}]+)}/g; + let match: RegExpExecArray | null; + while ((match = helperPattern.exec(value)) !== null) { + const helper = match[1]; + this.validateHelper(helper, `variables.${key}`); + } + }); + + // Try to process variables to ensure they resolve correctly + try { + const schema: Schema = {}; + const processedVars = processVariables(data.variables, schema); + + // Check if any variables failed to resolve (still contain ${}) + Object.entries(processedVars).forEach(([key, value]) => { + if (typeof value === "string" && value.includes("${")) { + // Check if it's a valid variable reference or an error + const unresolved = value.match(/\${([^}]+)}/g); + if (unresolved) { + unresolved.forEach((unresolvedVar) => { + const varName = unresolvedVar.slice(2, -1); + // Check if it's a reference to another variable that exists + if (!data.variables![varName] && !varName.includes(":")) { + this.warning( + `variables.${key}: contains unresolved variable reference '${unresolvedVar}'` + ); + } + }); + } + } + }); + + // Validate that domains can be processed with resolved variables + if (data.config.domains) { + data.config.domains.forEach((domain, index) => { + if (domain.host && typeof domain.host === "string") { + try { + const processedHost = processValue(domain.host, processedVars, schema); + if (processedHost.includes("${")) { + this.warning( + `domain[${index}].host: could not fully resolve all variables. Result: ${processedHost}` + ); + } + } catch (e: any) { + this.warning( + `domain[${index}].host: error processing host value: ${e.message}` + ); + } + } + }); + } + + // Validate that env vars can be processed + if (data.config.env) { + if (Array.isArray(data.config.env)) { + data.config.env.forEach((env, index) => { + if (typeof env === "string") { + try { + const processed = processValue(env, processedVars, schema); + if (processed.includes("${")) { + this.warning( + `config.env[${index}]: could not fully resolve all variables` + ); + } + } catch (e: any) { + this.warning( + `config.env[${index}]: error processing env value: ${e.message}` + ); + } + } + }); + } else if (typeof data.config.env === "object") { + Object.entries(data.config.env).forEach(([key, value]) => { + if (typeof value === "string") { + try { + const processed = processValue(value, processedVars, schema); + if (processed.includes("${")) { + this.warning( + `config.env.${key}: could not fully resolve all variables` + ); + } + } catch (e: any) { + this.warning( + `config.env.${key}: error processing env value: ${e.message}` + ); + } + } + }); + } + } + + // Validate that mounts can be processed + if (data.config.mounts) { + data.config.mounts.forEach((mount, index) => { + if (mount.filePath && typeof mount.filePath === "string") { + try { + const processed = processValue(mount.filePath, processedVars, schema); + if (processed.includes("${")) { + this.warning( + `config.mounts[${index}].filePath: could not fully resolve all variables` + ); + } + } catch (e: any) { + this.warning( + `config.mounts[${index}].filePath: error processing filePath: ${e.message}` + ); + } + } + if (mount.content && typeof mount.content === "string") { + try { + const processed = processValue(mount.content, processedVars, schema); + if (processed.includes("${")) { + this.warning( + `config.mounts[${index}].content: could not fully resolve all variables` + ); + } + } catch (e: any) { + this.warning( + `config.mounts[${index}].content: error processing content: ${e.message}` + ); + } + } + }); + } + + if (this.options.verbose) { + this.log("βœ… Variables processed successfully", "success"); + this.log(`πŸ“‹ Processed ${Object.keys(processedVars).length} variables`, "debug"); + } + } catch (e: any) { + this.error(`Failed to process variables: ${e.message}`); + } + } + } + + return this.errors.length === 0; + } catch (error: any) { + this.error(`Error validating template.toml: ${error.message}`); + return false; + } + } + + /** + * Validate a template directory + */ + private validateTemplateDir(templateDir: string): ValidationResult { + // Resolver rutas absolutas o relativas desde la raΓ­z del proyecto + const resolvedDir = path.isAbsolute(templateDir) + ? templateDir + : path.resolve(process.cwd(), templateDir); + + const templatePath = path.join(resolvedDir, "template.toml"); + const composePath = path.join(resolvedDir, "docker-compose.yml"); + + this.log(`Validating template: ${path.basename(resolvedDir)}`); + + // Parse compose services first + const composeServices = this.parseComposeServices(composePath); + + // Validate template.toml + const isValid = this.validateTemplate(templatePath, composeServices); + + // Show summary + if (isValid && this.errors.length === 0) { + this.log("Template structure is valid", "success"); + + // Show domains info + try { + const content = fs.readFileSync(templatePath, "utf8"); + const data = parse(content) as TemplateData; + if (data.config && data.config.domains) { + this.log("πŸ“‹ Domains configured:"); + data.config.domains.forEach((domain) => { + const service = domain.serviceName || "N/A"; + const port = domain.port !== undefined ? domain.port : "N/A"; + const host = domain.host || "N/A"; + this.log(` - Service: ${service}, Port: ${port}, Host: ${host}`); + }); + } + } catch (e) { + // Ignore errors in summary + } + } + + return { + valid: isValid && this.errors.length === 0, + errors: this.errors, + warnings: this.warnings, + }; + } + + /** + * Main validation method + */ + validate(): ValidationResult { + if (!this.options.templateDir) { + this.error("templateDir option is required"); + if (this.options.exitOnError) { + process.exit(1); + } + return { valid: false, errors: this.errors, warnings: this.warnings }; + } + + const result = this.validateTemplateDir(this.options.templateDir!); + + if (!result.valid && this.options.exitOnError) { + process.exit(1); + } + + return result; + } +} + +// CLI usage +if (require.main === module) { + const args = process.argv.slice(2); + const options: TemplateValidatorOptions = {}; + let templateDir: string | null = null; + + // Parse command line arguments + for (let i = 0; i < args.length; i++) { + const arg = args[i]; + switch (arg) { + case "--dir": + case "-d": + templateDir = args[++i]; + break; + case "--verbose": + case "-v": + options.verbose = true; + break; + case "--help": + case "-h": + console.log(` +Usage: tsx validate-template.ts [options] + +Options: + -d, --dir Template directory path (required) + -v, --verbose Verbose output + -h, --help Show this help message + +Examples: + tsx validate-template.ts --dir blueprints/grafana + tsx validate-template.ts -d blueprints/grafana --verbose + `); + process.exit(0); + break; + } + } + + if (!templateDir) { + console.error("❌ Error: --dir option is required"); + console.error("Use --help for usage information"); + process.exit(1); + } + + const validator = new TemplateValidator({ + templateDir, + ...options, + }); + + const result = validator.validate(); + + // Exit with appropriate code + process.exit(result.valid ? 0 : 1); +} + +export default TemplateValidator; + diff --git a/meta.json b/meta.json index 5cea3110..ee73ec65 100644 --- a/meta.json +++ b/meta.json @@ -295,6 +295,23 @@ "chatbot" ] }, + { + "id": "anytype", + "name": "Anytype", + "version": "latest", + "description": "Anytype is a personal knowledge baseβ€”your digital brainβ€”that lets you gather, connect and remix all kinds of information. Create pages, tasks, wikis, journalsβ€”even entire appsβ€”and define your own data model while your data stays offline-first, private and encrypted across devices.\n\nAfter installation, you can view the Anytype client configuration by running `cat /data/client-config.yml` inside the service container.", + "logo": "logo.png", + "links": { + "github": "https://github.com/grishy/any-sync-bundle", + "docs": "https://doc.anytype.io/anytype-docs", + "website": "https://anytype.io/" + }, + "tags": [ + "note-taking", + "local-first", + "peer-to-peer" + ] + }, { "id": "appflowy", "name": "App Flowy", @@ -733,6 +750,24 @@ "nextjs" ] }, + { + "id": "bluesky-pds", + "name": "Bluesky PDS", + "version": "0.4.182", + "description": "Bluesky PDS is a personal data server for Bluesky.", + "logo": "bluesky-pds.svg", + "links": { + "github": "https://github.com/bluesky-social/pds", + "website": "https://bsky.social/about", + "docs": "https://github.com/bluesky-social/pds" + }, + "tags": [ + "bluesky", + "pds", + "data", + "server" + ] + }, { "id": "bolt.diy", "name": "bolt.diy", @@ -1156,6 +1191,25 @@ "Document Management" ] }, + { + "id": "chirpstack", + "name": "ChirpStack", + "version": "4", + "description": "Open-source LoRaWAN Network Server for IoT applications. Complete stack with gateway bridges, REST API, and web interface for managing LoRaWAN devices and gateways.", + "logo": "chirpstack.png", + "links": { + "github": "https://github.com/chirpstack/chirpstack", + "website": "https://www.chirpstack.io/", + "docs": "https://www.chirpstack.io/docs/" + }, + "tags": [ + "iot", + "lorawan", + "network-server", + "gateway", + "monitoring" + ] + }, { "id": "chromium", "name": "Chromium", @@ -1776,6 +1830,26 @@ "document-signing" ] }, + { + "id": "dokploy-prom-monitoring-extension", + "name": "Dokploy Prometheus Monitoring Extension", + "version": "canary", + "description": "Dokploy monitoring extension with Prometheus metrics export for external monitoring systems like Grafana Cloud. Tracks server and container metrics with configurable thresholds and alerting.", + "logo": "logo.svg", + "links": { + "github": "https://github.com/Dokploy/dokploy", + "website": "https://dokploy.com/", + "docs": "https://docs.dokploy.com/" + }, + "tags": [ + "monitoring", + "prometheus", + "metrics", + "observability", + "docker", + "grafana" + ] + }, { "id": "domain-locker", "name": "Domain Locker", @@ -1998,7 +2072,7 @@ "description": "Enshrouded steam dedicated server.", "logo": "enshrouded.png", "links": { - "github": "https://github.com/jsknnr/enshrouded-server", + "github": "https://github.com/mornedhels/enshrouded-server", "website": "", "docs": "" }, @@ -2956,7 +3030,7 @@ { "id": "infisical", "name": "Infisical", - "version": "0.90.1", + "version": "0.135.0", "description": "All-in-one platform to securely manage application configuration and secrets across your team and infrastructure.", "logo": "infisical.jpg", "links": { @@ -3195,6 +3269,25 @@ "personal" ] }, + { + "id": "kokoro-tts", + "name": "Kokoro TTS", + "version": "latest", + "description": "Dockerized FastAPI wrapper for the Kokoro-82M text-to-speech model with multi-language support and OpenAI-compatible endpoints.", + "logo": "kokoro-tts.svg", + "links": { + "github": "https://github.com/remsky/Kokoro-FastAPI", + "website": "https://github.com/remsky/Kokoro-FastAPI", + "docs": "https://github.com/remsky/Kokoro-FastAPI#readme" + }, + "tags": [ + "text-to-speech", + "ai", + "voice", + "fastapi", + "openai-compatible" + ] + }, { "id": "kokoro-web", "name": "Kokoro Web", @@ -3261,6 +3354,26 @@ "productivity" ] }, + { + "id": "librechat", + "name": "LibreChat", + "version": "latest", + "description": "LibreChat is the ultimate open-source app for all your AI conversations, fully customizable and compatible with any AI provider (Openai, Ollama, Google etc.) β€” all in one sleek interface.", + "logo": "librechat.png", + "links": { + "github": "https://github.com/danny-avila/librechat", + "website": "https://librechat.ai", + "docs": "https://docs.librechat.ai" + }, + "tags": [ + "ai", + "chatbot", + "llm", + "MIT-license", + "BYOK", + "generative-ai" + ] + }, { "id": "libredesk", "name": "Libredesk", @@ -3550,6 +3663,24 @@ "gallery" ] }, + { + "id": "mcsmanager", + "name": "MCSManager", + "version": "latest", + "description": "A modern dashboard for managing Minecraft servers. Primarily focused on Minecraft, but also supports other games and features a UI that's easy for beginners to use and supports i18n.", + "logo": "mcsmanager.png", + "links": { + "github": "https://github.com/MCSManager/MCSManager", + "website": "https://github.com/MCSManager/MCSManager", + "docs": "https://github.com/MCSManager/MCSManager#readme" + }, + "tags": [ + "minecraft", + "game-server", + "management", + "dashboard" + ] + }, { "id": "mealie", "name": "Mealie (sqlite version)", @@ -3567,6 +3698,25 @@ "meal-planning" ] }, + { + "id": "mediacms", + "name": "MediaCMS", + "version": "latest", + "description": "MediaCMS is an open-source video and media CMS. It is a modern, full-featured solution for managing and streaming media content.", + "logo": "mediacms.svg", + "links": { + "github": "https://github.com/mediacms/mediacms", + "website": "https://mediacms.io/", + "docs": "https://docs.mediacms.io/" + }, + "tags": [ + "media", + "video", + "cms", + "streaming", + "self-hosted" + ] + }, { "id": "meilisearch", "name": "Meilisearch", @@ -3709,6 +3859,43 @@ "rating" ] }, + { + "id": "mulesoft-esb", + "name": "MuleSoft ESB Runtime Community Edition", + "version": "latest", + "description": "MuleSoft ESB Runtime is a lightweight, Java-based integration platform that allows you to easily integrate applications, data sources, and APIs. It provides powerful connectors and data transformation capabilities for building robust integration solutions.", + "logo": "mulesoft_logo.png", + "links": { + "github": "https://github.com/mulesoft", + "website": "https://www.mulesoft.com/", + "docs": "https://docs.mulesoft.com/" + }, + "tags": [ + "integration", + "api", + "esb", + "enterprise", + "java" + ] + }, + { + "id": "mumble", + "name": "Mumble", + "version": "latest", + "description": "Mumble is an open-source, low-latency, high-quality voice chat software primarily intended for use while gaming.", + "logo": "mumble.png", + "links": { + "github": "https://github.com/mumble-voip/mumble", + "website": "https://www.mumble.info/", + "docs": "https://wiki.mumble.info/" + }, + "tags": [ + "voice-chat", + "communication", + "gaming", + "voip" + ] + }, { "id": "n8n", "name": "n8n", @@ -4157,6 +4344,25 @@ "openai" ] }, + { + "id": "openinary", + "name": "Openinary", + "version": "latest", + "description": "Openinary is a self-hosted Cloudinary alternative.", + "logo": "openinary.svg", + "links": { + "github": "https://github.com/openinary/openinary", + "website": "https://openinary.dev", + "docs": "https://docs.openinary.dev" + }, + "tags": [ + "media", + "images", + "videos", + "cloudinary-alternative", + "developer-tools" + ] + }, { "id": "openpanel", "name": "OpenPanel", @@ -4283,6 +4489,42 @@ "open-source" ] }, + { + "id": "parseable", + "name": "Parseable", + "version": "v1.6.5", + "description": "Fast observability and log analytics platform on object storage", + "logo": "logo.svg", + "links": { + "github": "https://github.com/parseablehq/parseable", + "website": "https://www.parseable.com/", + "docs": "https://www.parseable.com/docs" + }, + "tags": [ + "observability", + "logging", + "analytics", + "monitoring" + ] + }, + { + "id": "passbolt", + "name": "Passbolt", + "version": "latest-ce", + "description": "Passbolt is an open source credential platform for modern teams. A versatile, battle-tested solution to manage and collaborate on passwords, accesses, and secrets. All in one.", + "logo": "passbolt.svg", + "links": { + "github": "https://github.com/passbolt/passbolt_api", + "website": "https://www.passbolt.com/", + "docs": "https://www.passbolt.com/docs/" + }, + "tags": [ + "password-manager", + "security", + "team-collaboration", + "encryption" + ] + }, { "id": "pastefy", "name": "Pastefy", @@ -4322,6 +4564,25 @@ "client-management" ] }, + { + "id": "peerdb", + "name": "PeerDB", + "version": "v0.35.5", + "description": "Data integration platform that synchronizes and federates data across databases with a unified API.", + "logo": "peerdb.jpeg", + "links": { + "github": "https://github.com/peerdb-io/peerdb", + "website": "https://peerdb.io", + "docs": "https://docs.peerdb.io" + }, + "tags": [ + "database", + "integration", + "sync", + "sql", + "workflow" + ] + }, { "id": "penpot", "name": "Penpot", @@ -4732,6 +4993,25 @@ "search" ] }, + { + "id": "quant-ux", + "name": "Quant-UX", + "version": "latest", + "description": "Quant-UX is an open-source UX design and prototyping tool that allows you to create interactive prototypes, conduct user research, and analyze user behavior.", + "logo": "logo.svg", + "links": { + "github": "https://github.com/KlausSchaefers/quant-ux", + "website": "https://www.quant-ux.com/", + "docs": "https://www.quant-ux.com/" + }, + "tags": [ + "design", + "ux", + "prototyping", + "user-research", + "analytics" + ] + }, { "id": "rabbitmq", "name": "RabbitMQ", @@ -4781,6 +5061,24 @@ "chat" ] }, + { + "id": "rote", + "name": "Rote", + "version": "latest", + "description": "Rote is an open-source multi-platform personal note system featuring an open API, full data ownership, and effortless Docker deployment.", + "logo": "rote.png", + "links": { + "github": "https://github.com/Rabithua/Rote", + "website": "https://rote.ink", + "docs": "https://github.com/Rabithua/Rote/tree/main/doc/userguide" + }, + "tags": [ + "notes", + "productivity", + "postgres", + "bun" + ] + }, { "id": "roundcube", "name": "Roundcube", @@ -4850,6 +5148,24 @@ "productivity" ] }, + { + "id": "rustfs", + "name": "RustFS", + "version": "latest", + "description": "RustFS is a high-performance, S3-compatible distributed object storage system built in Rust. 2.3x faster than MinIO for small objects, with full S3 API compatibility.", + "logo": "logo.svg", + "links": { + "github": "https://github.com/rustfs/rustfs", + "website": "https://rustfs.com/", + "docs": "https://docs.rustfs.com/" + }, + "tags": [ + "storage", + "s3", + "object-storage", + "rust" + ] + }, { "id": "rutorrent", "name": "ruTorrent", @@ -5274,7 +5590,7 @@ { "id": "tolgee", "name": "Tolgee", - "version": "v3.80.4", + "version": "latest", "description": "Developer & translator friendly web-based localization platform", "logo": "tolgee.svg", "links": { @@ -5360,7 +5676,7 @@ { "id": "trmnl-byos-laravel", "name": "TRMNL BYOS Laravel", - "version": "0.14.0", + "version": "0.21.0", "description": "TRMNL BYOS Laravel is a self-hosted application to manage TRMNL e-ink devices.", "logo": "byos-laravel.svg", "links": {