Merge pull request #6372 from menloresearch/rp/api-docs

docs: add first‑class API Reference to Jan docs (Local + Server)
This commit is contained in:
Ramon Perez 2025-09-05 21:44:07 +10:00 committed by GitHub
commit 88fb1acc0a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 53463 additions and 1553 deletions

View File

@ -14,6 +14,18 @@ on:
# Review gh actions docs if you want to further define triggers, paths, etc
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#on
workflow_dispatch:
inputs:
update_cloud_spec:
description: 'Update Jan Server API specification'
required: false
default: 'false'
type: choice
options:
- 'true'
- 'false'
schedule:
# Run daily at 2 AM UTC to sync with Jan Server updates
- cron: '0 2 * * *'
jobs:
deploy:
@ -56,9 +68,44 @@ jobs:
- name: Install dependencies
working-directory: website
run: bun install
- name: Update Jan Server API Spec (Scheduled/Manual)
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.update_cloud_spec == 'true')
working-directory: website
continue-on-error: true
run: |
echo "📡 Updating Jan Server API specification..."
bun run generate:cloud-spec
# Check if the spec file was updated
if git diff --quiet public/openapi/cloud-openapi.json; then
echo "✅ No changes to API specification"
else
echo "📝 API specification updated"
# Commit the changes if this is a scheduled run on main branch
if [ "${{ github.event_name }}" = "schedule" ] && [ "${{ github.ref }}" = "refs/heads/dev" ]; then
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add public/openapi/cloud-openapi.json
git commit -m "chore: update Jan Server API specification [skip ci]"
git push
fi
fi
env:
JAN_SERVER_SPEC_URL: ${{ secrets.JAN_SERVER_SPEC_URL || 'https://api.jan.ai/api/swagger/doc.json' }}
JAN_SERVER_PROD_URL: ${{ secrets.JAN_SERVER_PROD_URL || 'https://api.jan.ai/v1' }}
- name: Build website
working-directory: website
run: bun run build
run: |
# For PR and regular pushes, skip cloud spec generation in prebuild
# It will use the existing committed spec or fallback
if [ "${{ github.event_name }}" = "pull_request" ] || [ "${{ github.event_name }}" = "push" ]; then
echo "Using existing cloud spec for build"
export SKIP_CLOUD_SPEC_UPDATE=true
fi
bun run build
env:
SKIP_CLOUD_SPEC_UPDATE: ${{ github.event_name == 'pull_request' || github.event_name == 'push' }}
- name: copy redirects and headers
continue-on-error: true

View File

@ -0,0 +1,186 @@
name: Update Cloud API Spec
on:
# Manual trigger with options
workflow_dispatch:
inputs:
commit_changes:
description: 'Commit changes to repository'
required: false
default: 'true'
type: choice
options:
- 'true'
- 'false'
spec_url:
description: 'Custom API spec URL (optional)'
required: false
type: string
create_pr:
description: 'Create pull request for changes'
required: false
default: 'false'
type: choice
options:
- 'true'
- 'false'
# Scheduled updates - runs daily at 2 AM UTC
schedule:
- cron: '0 2 * * *'
# Can be triggered by repository dispatch (webhook from Jan Server)
repository_dispatch:
types: [update-api-spec]
jobs:
update-spec:
name: Update Jan Server API Specification
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Install dependencies
working-directory: website
run: bun install
- name: Configure Git
run: |
git config --global user.email "github-actions[bot]@users.noreply.github.com"
git config --global user.name "github-actions[bot]"
- name: Update API Specification
id: update_spec
working-directory: website
run: |
# Set custom spec URL if provided
if [ -n "${{ github.event.inputs.spec_url }}" ]; then
export JAN_SERVER_SPEC_URL="${{ github.event.inputs.spec_url }}"
echo "📡 Using custom spec URL: $JAN_SERVER_SPEC_URL"
elif [ -n "${{ github.event.client_payload.spec_url }}" ]; then
export JAN_SERVER_SPEC_URL="${{ github.event.client_payload.spec_url }}"
echo "📡 Using webhook spec URL: $JAN_SERVER_SPEC_URL"
else
export JAN_SERVER_SPEC_URL="${{ secrets.JAN_SERVER_SPEC_URL || 'https://api.jan.ai/api/swagger/doc.json' }}"
echo "📡 Using default spec URL: $JAN_SERVER_SPEC_URL"
fi
# Force update the spec
export FORCE_UPDATE=true
bun run generate:cloud-spec
# Check if there are changes
if git diff --quiet public/openapi/cloud-openapi.json; then
echo "✅ No changes to API specification"
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "📝 API specification has been updated"
echo "has_changes=true" >> $GITHUB_OUTPUT
# Get summary of changes
echo "### Changes Summary" >> $GITHUB_STEP_SUMMARY
echo '```diff' >> $GITHUB_STEP_SUMMARY
git diff --stat public/openapi/cloud-openapi.json >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
fi
env:
JAN_SERVER_PROD_URL: ${{ secrets.JAN_SERVER_PROD_URL || 'https://api.jan.ai/v1' }}
JAN_SERVER_STAGING_URL: ${{ secrets.JAN_SERVER_STAGING_URL || 'https://staging-api.jan.ai/v1' }}
- name: Create Pull Request
if: |
steps.update_spec.outputs.has_changes == 'true' &&
(github.event.inputs.create_pr == 'true' || github.event_name == 'repository_dispatch')
uses: peter-evans/create-pull-request@v5
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: "chore: update Jan Server API specification"
title: "chore: update Jan Server API specification"
body: |
## 🤖 Automated API Spec Update
This PR updates the Jan Server API specification.
### Trigger Information
- **Event**: ${{ github.event_name }}
- **Triggered by**: ${{ github.actor }}
- **Timestamp**: ${{ github.event.head_commit.timestamp || github.event.repository.updated_at }}
### What's Changed
The OpenAPI specification for Jan Server has been updated with the latest endpoints and schemas.
### Review Checklist
- [ ] API endpoints are correctly documented
- [ ] Authentication requirements are accurate
- [ ] Model examples are up to date
- [ ] Breaking changes are noted (if any)
---
*This PR was automatically generated by the API spec update workflow.*
branch: update-api-spec-${{ github.run_number }}
delete-branch: true
labels: |
documentation
api
automated
- name: Commit and Push Changes
if: |
steps.update_spec.outputs.has_changes == 'true' &&
github.event.inputs.commit_changes != 'false' &&
github.event.inputs.create_pr != 'true' &&
github.event_name != 'repository_dispatch'
run: |
cd website
git add public/openapi/cloud-openapi.json
git commit -m "chore: update Jan Server API specification [skip ci]
Event: ${{ github.event_name }}
Triggered by: ${{ github.actor }}"
# Only push to dev branch if it's a scheduled run
if [ "${{ github.event_name }}" = "schedule" ] && [ "${{ github.ref }}" = "refs/heads/dev" ]; then
git push origin HEAD:dev
echo "✅ Changes committed to dev branch"
elif [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
git push origin HEAD:${{ github.ref_name }}
echo "✅ Changes committed to ${{ github.ref_name }} branch"
else
echo " Changes prepared but not pushed (event: ${{ github.event_name }})"
fi
- name: Send Notification
if: steps.update_spec.outputs.has_changes == 'true'
continue-on-error: true
run: |
echo "📬 API specification updated successfully"
# You can add Slack/Discord notification here if needed
# Example webhook call:
# curl -X POST ${{ secrets.SLACK_WEBHOOK_URL }} \
# -H 'Content-Type: application/json' \
# -d '{"text": "Jan Server API spec has been updated"}'
- name: Summary
if: always()
run: |
echo "## Workflow Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Status**: ${{ steps.update_spec.outputs.has_changes == 'true' && '✅ Updated' || '⏭️ No changes' }}" >> $GITHUB_STEP_SUMMARY
echo "- **Event**: ${{ github.event_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "- **Commit changes**: ${{ github.event.inputs.commit_changes || 'auto' }}" >> $GITHUB_STEP_SUMMARY
echo "- **Create PR**: ${{ github.event.inputs.create_pr || 'false' }}" >> $GITHUB_STEP_SUMMARY

1
.gitignore vendored
View File

@ -57,3 +57,4 @@ Cargo.lock
## test
test-data
llm-docs

183
website/API_SPEC_SYNC.md Normal file
View File

@ -0,0 +1,183 @@
# API Specification Synchronization
This document explains how the Jan Server API specification is kept in sync with the documentation.
## Overview
The Jan documentation automatically synchronizes with the Jan Server API specification to ensure the API reference is always up to date. This is managed through GitHub Actions workflows that can be triggered in multiple ways.
## Synchronization Methods
### 1. Automatic Daily Sync
- **Schedule**: Runs daily at 2 AM UTC
- **Branch**: `dev`
- **Behavior**: Fetches the latest spec and commits changes if any
- **Workflow**: `.github/workflows/update-cloud-api-spec.yml`
### 2. Manual Trigger via GitHub UI
Navigate to Actions → "Update Cloud API Spec" → Run workflow
Options:
- **Commit changes**: Whether to commit changes directly (default: true)
- **Custom spec URL**: Override the default API spec URL
- **Create PR**: Create a pull request instead of direct commit (default: false)
### 3. Webhook Trigger (For Jan Server Team)
Send a repository dispatch event to trigger an update:
```bash
curl -X POST \
-H "Accept: application/vnd.github.v3+json" \
-H "Authorization: token YOUR_GITHUB_TOKEN" \
https://api.github.com/repos/janhq/jan/dispatches \
-d '{
"event_type": "update-api-spec",
"client_payload": {
"spec_url": "https://api.jan.ai/api/swagger/doc.json"
}
}'
```
### 4. Local Development
For local development, the spec is updated conditionally:
```bash
# Force update the cloud spec
bun run generate:cloud-spec-force
# Normal update (checks if update is needed)
bun run generate:cloud-spec
# Update both local and cloud specs
bun run generate:specs
```
## Configuration
### Environment Variables
The following environment variables can be configured in GitHub Secrets:
| Variable | Description | Default |
|----------|-------------|---------|
| `JAN_SERVER_SPEC_URL` | URL to fetch the OpenAPI spec | `https://api.jan.ai/api/swagger/doc.json` |
| `JAN_SERVER_PROD_URL` | Production API base URL | `https://api.jan.ai/v1` |
| `JAN_SERVER_STAGING_URL` | Staging API base URL | `https://staging-api.jan.ai/v1` |
### Build Behavior
| Context | Behavior |
|---------|----------|
| Pull Request | Uses existing spec (no update) |
| Push to dev | Uses existing spec (no update) |
| Scheduled run | Updates spec and commits changes |
| Manual trigger | Updates based on input options |
| Webhook | Updates and creates PR |
| Local dev | Updates if spec is >24hrs old or missing |
## Workflow Integration
### For Jan Server Team
When deploying a new API version:
1. **Option A: Automatic PR**
- Deploy your API changes
- Trigger the webhook (see above)
- Review and merge the created PR
2. **Option B: Manual Update**
- Go to [Actions](https://github.com/janhq/jan/actions/workflows/update-cloud-api-spec.yml)
- Click "Run workflow"
- Select options:
- Set "Create PR" to `true` for review
- Or leave as `false` for direct commit
3. **Option C: Wait for Daily Sync**
- Changes will be picked up automatically at 2 AM UTC
### For Documentation Team
The API spec updates are handled automatically. However, you can:
1. **Force an update**: Run the "Update Cloud API Spec" workflow manually
2. **Test locally**: Use `bun run generate:cloud-spec-force`
3. **Review changes**: Check PRs labeled with `api` and `automated`
## Fallback Mechanism
If the Jan Server API is unavailable:
1. The workflow will use the last known good spec
2. Local builds will fall back to the local OpenAPI spec
3. The build will continue without failing
## Monitoring
### Check Update Status
1. Go to [Actions](https://github.com/janhq/jan/actions/workflows/update-cloud-api-spec.yml)
2. Check the latest run status
3. Review the workflow summary for details
### Notifications
To add Slack/Discord notifications:
1. Add webhook URL to GitHub Secrets
2. Uncomment notification section in workflow
3. Configure message format as needed
## Troubleshooting
### Spec Update Fails
1. Check if the API endpoint is accessible
2. Verify the spec URL is correct
3. Check GitHub Actions logs for errors
4. Ensure proper permissions for the workflow
### Changes Not Appearing
1. Verify the workflow completed successfully
2. Check if changes were committed to the correct branch
3. Ensure the build is using the updated spec
4. Clear CDN cache if using Cloudflare
### Manual Recovery
If automated updates fail:
```bash
# Clone the repository
git clone https://github.com/janhq/jan.git
cd jan/website
# Install dependencies
bun install
# Force update the spec
FORCE_UPDATE=true bun run generate:cloud-spec
# Commit and push
git add public/openapi/cloud-openapi.json
git commit -m "chore: manual update of API spec"
git push
```
## Best Practices
1. **Version Control**: Always review significant API changes before merging
2. **Testing**: Test the updated spec locally before deploying
3. **Communication**: Notify the docs team of breaking API changes
4. **Monitoring**: Set up alerts for failed spec updates
5. **Documentation**: Update this guide when changing the sync process
## Support
For issues or questions:
- Open an issue in the [Jan repository](https://github.com/janhq/jan/issues)
- Contact the documentation team on Discord
- Check the [workflow runs](https://github.com/janhq/jan/actions) for debugging

View File

@ -26,3 +26,23 @@ All commands are run from the root of the project, from a terminal:
| `bun preview` | Preview your build locally, before deploying |
| `bun astro ...` | Run CLI commands like `astro add`, `astro check` |
| `bun astro -- --help` | Get help using the Astro CLI |
## 📖 API Reference Commands
The website includes interactive API documentation. These commands help manage the OpenAPI specifications:
| Command | Action |
| :------------------------------- | :-------------------------------------------------------- |
| `bun run api:dev` | Start dev server with API reference at `/api` |
| `bun run api:local` | Start dev server with local API docs at `/api-reference/local` |
| `bun run api:cloud` | Start dev server with cloud API docs at `/api-reference/cloud` |
| `bun run generate:local-spec` | Generate/fix the local OpenAPI specification |
| `bun run generate:cloud-spec` | Generate the cloud OpenAPI specification from Jan Server |
| `bun run generate:cloud-spec-force` | Force update cloud spec (ignores cache/conditions) |
**API Reference Pages:**
- `/api` - Landing page with Local and Server API options
- `/api-reference/local` - Local API (llama.cpp) documentation
- `/api-reference/cloud` - Jan Server API (vLLM) documentation
The cloud specification is automatically synced via GitHub Actions on a daily schedule and can be manually triggered by the Jan Server team.

View File

@ -3,6 +3,9 @@ import { defineConfig } from 'astro/config'
import starlight from '@astrojs/starlight'
import starlightThemeRapide from 'starlight-theme-rapide'
import starlightSidebarTopics from 'starlight-sidebar-topics'
import starlightUtils from '@lorenzo_lewis/starlight-utils'
import react from '@astrojs/react'
import mermaid from 'astro-mermaid'
import { fileURLToPath } from 'url'
import path, { dirname } from 'path'
@ -15,269 +18,271 @@ export default defineConfig({
// Deploy to the new v2 subdomain
site: 'https://docs.jan.ai',
integrations: [
react(),
mermaid({
theme: 'default',
autoTheme: true,
}),
starlight({
title: '👋 Jan',
favicon: 'jan2.png',
customCss: [
'./src/styles/global.css',
],
favicon: 'favicon.ico',
customCss: ['./src/styles/global.css'],
head: [
{
tag: 'script',
content: `
document.addEventListener('DOMContentLoaded', function() {
const logoLink = document.querySelector('a[href="/"]');
if (logoLink) {
logoLink.href = 'https://jan.ai';
}
});
`,
attrs: { src: '/scripts/inject-navigation.js', defer: true },
},
{
tag: 'link',
attrs: { rel: 'stylesheet', href: '/styles/navigation.css' },
},
],
plugins: [
starlightThemeRapide(),
starlightSidebarTopics([
{
label: 'Jan',
link: '/',
icon: 'rocket',
items: [{ label: 'Ecosystem', slug: 'index' }],
},
{
label: 'Jan Desktop',
link: '/jan/quickstart',
icon: 'rocket',
items: [
{
label: '🚀 QUICK START',
items: [
{ label: 'Getting Started', slug: 'jan/quickstart' },
{
label: 'Install Jan',
collapsed: false,
autogenerate: { directory: 'jan/installation' },
},
{ label: 'AI Assistants', slug: 'jan/assistants' },
],
},
{
label: '🤖 MODELS',
items: [
{ label: 'Overview', slug: 'jan/manage-models' },
{
label: 'Jan Models',
collapsed: false,
items: [
{
label: 'Jan v1',
slug: 'jan/jan-models/jan-v1',
},
{
label: 'Research Models',
collapsed: true,
items: [
{
label: 'Jan Nano 32k',
slug: 'jan/jan-models/jan-nano-32',
},
{
label: 'Jan Nano 128k',
slug: 'jan/jan-models/jan-nano-128',
},
{
label: 'Lucy',
slug: 'jan/jan-models/lucy',
},
],
},
],
},
{
label: 'Cloud Providers',
collapsed: true,
items: [
{ label: 'OpenAI', slug: 'jan/remote-models/openai' },
{
label: 'Anthropic',
slug: 'jan/remote-models/anthropic',
},
{ label: 'Gemini', slug: 'jan/remote-models/google' },
{ label: 'Groq', slug: 'jan/remote-models/groq' },
{
label: 'Mistral',
slug: 'jan/remote-models/mistralai',
},
{ label: 'Cohere', slug: 'jan/remote-models/cohere' },
{
label: 'OpenRouter',
slug: 'jan/remote-models/openrouter',
},
{
label: 'HuggingFace 🤗',
slug: 'jan/remote-models/huggingface',
},
],
},
{
label: 'Custom Providers',
slug: 'jan/custom-provider',
},
{
label: 'Multi-Modal Models',
slug: 'jan/multi-modal',
},
],
},
{
label: '🔧 TOOLS & INTEGRATIONS',
items: [
{ label: 'What is MCP?', slug: 'jan/mcp' },
{
label: 'Examples & Tutorials',
collapsed: true,
items: [
{
label: 'Web & Search',
collapsed: true,
items: [
{
label: 'Browser Control',
slug: 'jan/mcp-examples/browser/browserbase',
},
{
label: 'Serper Search',
slug: 'jan/mcp-examples/search/serper',
},
{
label: 'Exa Search',
slug: 'jan/mcp-examples/search/exa',
},
],
},
{
label: 'Data & Analysis',
collapsed: true,
items: [
{
label: 'Jupyter Notebooks',
slug: 'jan/mcp-examples/data-analysis/jupyter',
},
{
label: 'Code Sandbox (E2B)',
slug: 'jan/mcp-examples/data-analysis/e2b',
},
{
label: 'Deep Financial Research',
slug: 'jan/mcp-examples/deepresearch/octagon',
},
],
},
{
label: 'Productivity',
collapsed: true,
items: [
{
label: 'Linear',
slug: 'jan/mcp-examples/productivity/linear',
},
{
label: 'Todoist',
slug: 'jan/mcp-examples/productivity/todoist',
},
],
},
{
label: 'Creative',
collapsed: true,
items: [
{
label: 'Design with Canva',
slug: 'jan/mcp-examples/design/canva',
},
],
},
],
},
],
},
{
label: '⚙️ DEVELOPER',
items: [
{
label: 'Local API Server',
collapsed: true,
items: [
{ label: 'Overview', slug: 'local-server' },
{
label: 'API Configuration',
slug: 'local-server/api-server',
},
{
label: 'Engine Settings',
slug: 'local-server/llama-cpp',
},
{
label: 'Server Settings',
slug: 'local-server/settings',
},
{
label: 'Integrations',
collapsed: true,
autogenerate: {
directory: 'local-server/integrations',
starlightSidebarTopics(
[
{
label: 'Jan',
link: '/',
icon: 'rocket',
items: [{ label: 'Ecosystem', slug: 'index' }],
},
{
label: 'Jan Desktop',
link: '/jan/quickstart',
icon: 'rocket',
items: [
{
label: '🚀 QUICK START',
items: [
{ label: 'Getting Started', slug: 'jan/quickstart' },
{
label: 'Install Jan',
collapsed: false,
autogenerate: { directory: 'jan/installation' },
},
{ label: 'AI Assistants', slug: 'jan/assistants' },
],
},
{
label: '🤖 MODELS',
items: [
{ label: 'Overview', slug: 'jan/manage-models' },
{
label: 'Jan Models',
collapsed: false,
items: [
{
label: 'Jan v1',
slug: 'jan/jan-models/jan-v1',
},
},
],
},
{
label: 'Technical Details',
collapsed: true,
items: [
{
label: 'Model Parameters',
slug: 'jan/explanation/model-parameters',
},
],
},
],
},
{
label: '📚 REFERENCE',
items: [
{ label: 'Settings', slug: 'jan/settings' },
{ label: 'Data Folder', slug: 'jan/data-folder' },
{ label: 'Troubleshooting', slug: 'jan/troubleshooting' },
{ label: 'Privacy Policy', slug: 'jan/privacy' },
],
},
],
},
{
label: 'Research Models',
collapsed: true,
items: [
{
label: 'Jan Nano 32k',
slug: 'jan/jan-models/jan-nano-32',
},
{
label: 'Jan Nano 128k',
slug: 'jan/jan-models/jan-nano-128',
},
{
label: 'Lucy',
slug: 'jan/jan-models/lucy',
},
],
},
],
},
{
label: 'Cloud Providers',
collapsed: true,
items: [
{ label: 'OpenAI', slug: 'jan/remote-models/openai' },
{
label: 'Anthropic',
slug: 'jan/remote-models/anthropic',
},
{ label: 'Gemini', slug: 'jan/remote-models/google' },
{ label: 'Groq', slug: 'jan/remote-models/groq' },
{
label: 'Mistral',
slug: 'jan/remote-models/mistralai',
},
{ label: 'Cohere', slug: 'jan/remote-models/cohere' },
{
label: 'OpenRouter',
slug: 'jan/remote-models/openrouter',
},
{
label: 'HuggingFace 🤗',
slug: 'jan/remote-models/huggingface',
},
],
},
{
label: 'Custom Providers',
slug: 'jan/custom-provider',
},
{
label: 'Multi-Modal Models',
slug: 'jan/multi-modal',
},
],
},
{
label: '🔧 TOOLS & INTEGRATIONS',
items: [
{ label: 'What is MCP?', slug: 'jan/mcp' },
{
label: 'Examples & Tutorials',
collapsed: true,
items: [
{
label: 'Web & Search',
collapsed: true,
items: [
{
label: 'Browser Control',
slug: 'jan/mcp-examples/browser/browserbase',
},
{
label: 'Serper Search',
slug: 'jan/mcp-examples/search/serper',
},
{
label: 'Exa Search',
slug: 'jan/mcp-examples/search/exa',
},
],
},
{
label: 'Data & Analysis',
collapsed: true,
items: [
{
label: 'Jupyter Notebooks',
slug: 'jan/mcp-examples/data-analysis/jupyter',
},
{
label: 'Code Sandbox (E2B)',
slug: 'jan/mcp-examples/data-analysis/e2b',
},
{
label: 'Deep Financial Research',
slug: 'jan/mcp-examples/deepresearch/octagon',
},
],
},
{
label: 'Productivity',
collapsed: true,
items: [
{
label: 'Linear',
slug: 'jan/mcp-examples/productivity/linear',
},
{
label: 'Todoist',
slug: 'jan/mcp-examples/productivity/todoist',
},
],
},
{
label: 'Creative',
collapsed: true,
items: [
{
label: 'Design with Canva',
slug: 'jan/mcp-examples/design/canva',
},
],
},
],
},
],
},
{
label: '⚙️ DEVELOPER',
items: [
{
label: 'Local API Server',
collapsed: true,
items: [
{ label: 'Overview', slug: 'local-server' },
{
label: 'API Configuration',
slug: 'local-server/api-server',
},
{
label: 'Engine Settings',
slug: 'local-server/llama-cpp',
},
{
label: 'Server Settings',
slug: 'local-server/settings',
},
{
label: 'Integrations',
collapsed: true,
autogenerate: {
directory: 'local-server/integrations',
},
},
],
},
{
label: 'Technical Details',
collapsed: true,
items: [
{
label: 'Model Parameters',
slug: 'jan/explanation/model-parameters',
},
],
},
],
},
{
label: '📚 REFERENCE',
items: [
{ label: 'Settings', slug: 'jan/settings' },
{ label: 'Data Folder', slug: 'jan/data-folder' },
{ label: 'Troubleshooting', slug: 'jan/troubleshooting' },
{ label: 'Privacy Policy', slug: 'jan/privacy' },
],
},
],
},
{
label: 'Browser Extension',
link: '/browser/',
badge: { text: 'Alpha', variant: 'tip' },
icon: 'puzzle',
items: [{ label: 'Overview', slug: 'browser' }],
},
{
label: 'Jan Mobile',
link: '/mobile/',
badge: { text: 'Soon', variant: 'caution' },
icon: 'phone',
items: [{ label: 'Overview', slug: 'mobile' }],
},
{
label: 'Jan Server',
link: '/server/',
badge: { text: 'Soon', variant: 'caution' },
icon: 'forward-slash',
items: [{ label: 'Overview', slug: 'server' }],
},
],
{
label: 'Browser Extension',
link: '/browser/',
badge: { text: 'Alpha', variant: 'tip' },
icon: 'puzzle',
items: [{ label: 'Overview', slug: 'browser' }],
},
{
label: 'Jan Mobile',
link: '/mobile/',
badge: { text: 'Soon', variant: 'caution' },
icon: 'phone',
items: [{ label: 'Overview', slug: 'mobile' }],
},
{
label: 'Jan Server',
link: '/server/',
badge: { text: 'Soon', variant: 'caution' },
icon: 'forward-slash',
items: [{ label: 'Overview', slug: 'server' }],
},
]),
exclude: ['/api-reference', '/api-reference/**/*'],
}
),
],
social: [
{

View File

@ -4,10 +4,16 @@
"": {
"name": "website",
"dependencies": {
"@astrojs/react": "^4.3.0",
"@astrojs/starlight": "^0.35.1",
"@lorenzo_lewis/starlight-utils": "^0.3.2",
"@scalar/api-reference-react": "^0.7.42",
"@types/react": "^19.1.12",
"astro": "^5.6.1",
"astro-mermaid": "^1.0.4",
"mermaid": "^11.9.0",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"sharp": "^0.34.3",
"starlight-openapi": "^0.19.1",
"starlight-sidebar-topics": "^0.6.0",
@ -17,6 +23,8 @@
},
},
"packages": {
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
"@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="],
"@antfu/utils": ["@antfu/utils@8.1.1", "", {}, "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ=="],
@ -33,6 +41,8 @@
"@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="],
"@astrojs/react": ["@astrojs/react@4.3.0", "", { "dependencies": { "@vitejs/plugin-react": "^4.4.1", "ultrahtml": "^1.6.0", "vite": "^6.3.5" }, "peerDependencies": { "@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0", "@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0", "react": "^17.0.2 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0" } }, "sha512-N02aj52Iezn69qHyx5+XvPqgsPMEnel9mI5JMbGiRMTzzLMuNaxRVoQTaq2024Dpr7BLsxCjqMkNvelqMDhaHA=="],
"@astrojs/sitemap": ["@astrojs/sitemap@3.4.1", "", { "dependencies": { "sitemap": "^8.0.0", "stream-replace-string": "^2.0.0", "zod": "^3.24.2" } }, "sha512-VjZvr1e4FH6NHyyHXOiQgLiw94LnCVY4v06wN/D0gZKchTMkg71GrAHJz81/huafcmavtLkIv26HnpfDq6/h/Q=="],
"@astrojs/starlight": ["@astrojs/starlight@0.35.1", "", { "dependencies": { "@astrojs/markdown-remark": "^6.3.1", "@astrojs/mdx": "^4.2.3", "@astrojs/sitemap": "^3.3.0", "@pagefind/default-ui": "^1.3.0", "@types/hast": "^3.0.4", "@types/js-yaml": "^4.0.9", "@types/mdast": "^4.0.4", "astro-expressive-code": "^0.41.1", "bcp-47": "^2.1.0", "hast-util-from-html": "^2.0.1", "hast-util-select": "^6.0.2", "hast-util-to-string": "^3.0.0", "hastscript": "^9.0.0", "i18next": "^23.11.5", "js-yaml": "^4.1.0", "klona": "^2.0.6", "mdast-util-directive": "^3.0.0", "mdast-util-to-markdown": "^2.1.0", "mdast-util-to-string": "^4.0.0", "pagefind": "^1.3.0", "rehype": "^13.0.1", "rehype-format": "^5.0.0", "remark-directive": "^3.0.0", "ultrahtml": "^1.6.0", "unified": "^11.0.5", "unist-util-visit": "^5.0.0", "vfile": "^6.0.2" }, "peerDependencies": { "astro": "^5.5.0" } }, "sha512-/hshlAayMd3B+E+h8wY6JWT1lNmX/K1+ugiZPirW5XFo5QUcNMk/Bsa4oHgg+TFoU6kbxPtijo0VppATfD9XuA=="],
@ -41,14 +51,42 @@
"@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="],
"@babel/compat-data": ["@babel/compat-data@7.28.0", "", {}, "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw=="],
"@babel/core": ["@babel/core@7.28.3", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.28.3", "@babel/helpers": "^7.28.3", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.3", "@babel/types": "^7.28.2", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ=="],
"@babel/generator": ["@babel/generator@7.28.3", "", { "dependencies": { "@babel/parser": "^7.28.3", "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" } }, "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw=="],
"@babel/helper-compilation-targets": ["@babel/helper-compilation-targets@7.27.2", "", { "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" } }, "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ=="],
"@babel/helper-globals": ["@babel/helper-globals@7.28.0", "", {}, "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw=="],
"@babel/helper-module-imports": ["@babel/helper-module-imports@7.27.1", "", { "dependencies": { "@babel/traverse": "^7.27.1", "@babel/types": "^7.27.1" } }, "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w=="],
"@babel/helper-module-transforms": ["@babel/helper-module-transforms@7.28.3", "", { "dependencies": { "@babel/helper-module-imports": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1", "@babel/traverse": "^7.28.3" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw=="],
"@babel/helper-plugin-utils": ["@babel/helper-plugin-utils@7.27.1", "", {}, "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw=="],
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="],
"@babel/helper-validator-option": ["@babel/helper-validator-option@7.27.1", "", {}, "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg=="],
"@babel/helpers": ["@babel/helpers@7.28.3", "", { "dependencies": { "@babel/template": "^7.27.2", "@babel/types": "^7.28.2" } }, "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw=="],
"@babel/parser": ["@babel/parser@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.0" }, "bin": "./bin/babel-parser.js" }, "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g=="],
"@babel/plugin-transform-react-jsx-self": ["@babel/plugin-transform-react-jsx-self@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw=="],
"@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="],
"@babel/runtime": ["@babel/runtime@7.27.6", "", {}, "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q=="],
"@babel/template": ["@babel/template@7.27.2", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/parser": "^7.27.2", "@babel/types": "^7.27.1" } }, "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw=="],
"@babel/traverse": ["@babel/traverse@7.28.3", "", { "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", "@babel/types": "^7.28.2", "debug": "^4.3.1" } }, "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ=="],
"@babel/types": ["@babel/types@7.28.1", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ=="],
"@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.1", "", {}, "sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw=="],
@ -65,6 +103,32 @@
"@chevrotain/utils": ["@chevrotain/utils@11.0.3", "", {}, "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ=="],
"@codemirror/autocomplete": ["@codemirror/autocomplete@6.18.7", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0" } }, "sha512-8EzdeIoWPJDsMBwz3zdzwXnUpCzMiCyz5/A3FIPpriaclFCGDkAzK13sMcnsu5rowqiyeQN2Vs2TsOcoDPZirQ=="],
"@codemirror/commands": ["@codemirror/commands@6.8.1", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.27.0", "@lezer/common": "^1.1.0" } }, "sha512-KlGVYufHMQzxbdQONiLyGQDUW0itrLZwq3CcY7xpv9ZLRHqzkBSoteocBHtMCoY7/Ci4xhzSrToIeLg7FxHuaw=="],
"@codemirror/lang-css": ["@codemirror/lang-css@6.3.1", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@lezer/common": "^1.0.2", "@lezer/css": "^1.1.7" } }, "sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg=="],
"@codemirror/lang-html": ["@codemirror/lang-html@6.4.9", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/lang-css": "^6.0.0", "@codemirror/lang-javascript": "^6.0.0", "@codemirror/language": "^6.4.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0", "@lezer/css": "^1.1.0", "@lezer/html": "^1.3.0" } }, "sha512-aQv37pIMSlueybId/2PVSP6NPnmurFDVmZwzc7jszd2KAF8qd4VBbvNYPXWQq90WIARjsdVkPbw29pszmHws3Q=="],
"@codemirror/lang-javascript": ["@codemirror/lang-javascript@6.2.4", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.6.0", "@codemirror/lint": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.17.0", "@lezer/common": "^1.0.0", "@lezer/javascript": "^1.0.0" } }, "sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA=="],
"@codemirror/lang-json": ["@codemirror/lang-json@6.0.2", "", { "dependencies": { "@codemirror/language": "^6.0.0", "@lezer/json": "^1.0.0" } }, "sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ=="],
"@codemirror/lang-xml": ["@codemirror/lang-xml@6.1.0", "", { "dependencies": { "@codemirror/autocomplete": "^6.0.0", "@codemirror/language": "^6.4.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "@lezer/common": "^1.0.0", "@lezer/xml": "^1.0.0" } }, "sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg=="],
"@codemirror/lang-yaml": ["@codemirror/lang-yaml@6.1.2", "", { "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" } }, "sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw=="],
"@codemirror/language": ["@codemirror/language@6.11.3", "", { "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" } }, "sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA=="],
"@codemirror/lint": ["@codemirror/lint@6.8.5", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.35.0", "crelt": "^1.0.5" } }, "sha512-s3n3KisH7dx3vsoeGMxsbRAgKe4O1vbrnKBClm99PU0fWxmxsx5rR2PfqQgIt+2MMJBHbiJ5rfIdLYfB9NNvsA=="],
"@codemirror/search": ["@codemirror/search@6.5.11", "", { "dependencies": { "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0", "crelt": "^1.0.5" } }, "sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA=="],
"@codemirror/state": ["@codemirror/state@6.5.2", "", { "dependencies": { "@marijn/find-cluster-break": "^1.0.0" } }, "sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA=="],
"@codemirror/view": ["@codemirror/view@6.38.2", "", { "dependencies": { "@codemirror/state": "^6.5.0", "crelt": "^1.0.6", "style-mod": "^4.1.0", "w3c-keyname": "^2.2.4" } }, "sha512-bTWAJxL6EOFLPzTx+O5P5xAO3gTqpatQ2b/ARQ8itfU/v2LlpS3pH2fkL0A3E/Fx8Y2St2KES7ZEV0sHTsSW/A=="],
"@ctrl/tinycolor": ["@ctrl/tinycolor@4.1.0", "", {}, "sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ=="],
"@emnapi/runtime": ["@emnapi/runtime@1.4.5", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg=="],
@ -129,8 +193,30 @@
"@expressive-code/plugin-text-markers": ["@expressive-code/plugin-text-markers@0.41.3", "", { "dependencies": { "@expressive-code/core": "^0.41.3" } }, "sha512-SN8tkIzDpA0HLAscEYD2IVrfLiid6qEdE9QLlGVSxO1KEw7qYvjpbNBQjUjMr5/jvTJ7ys6zysU2vLPHE0sb2g=="],
"@floating-ui/core": ["@floating-ui/core@1.7.3", "", { "dependencies": { "@floating-ui/utils": "^0.2.10" } }, "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w=="],
"@floating-ui/dom": ["@floating-ui/dom@1.7.4", "", { "dependencies": { "@floating-ui/core": "^1.7.3", "@floating-ui/utils": "^0.2.10" } }, "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA=="],
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
"@floating-ui/vue": ["@floating-ui/vue@1.1.9", "", { "dependencies": { "@floating-ui/dom": "^1.7.4", "@floating-ui/utils": "^0.2.10", "vue-demi": ">=0.13.0" } }, "sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ=="],
"@headlessui/tailwindcss": ["@headlessui/tailwindcss@0.2.2", "", { "peerDependencies": { "tailwindcss": "^3.0 || ^4.0" } }, "sha512-xNe42KjdyA4kfUKLLPGzME9zkH7Q3rOZ5huFihWNWOQFxnItxPB3/67yBI8/qBfY8nwBRx5GHn4VprsoluVMGw=="],
"@headlessui/vue": ["@headlessui/vue@1.7.23", "", { "dependencies": { "@tanstack/vue-virtual": "^3.0.0-beta.60" }, "peerDependencies": { "vue": "^3.2.0" } }, "sha512-JzdCNqurrtuu0YW6QaDtR2PIYCKPUWq28csDyMvN4zmGccmE7lz40Is6hc3LA4HFeCI7sekZ/PQMTNmn9I/4Wg=="],
"@humanwhocodes/momoa": ["@humanwhocodes/momoa@2.0.4", "", {}, "sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA=="],
"@hyperjump/browser": ["@hyperjump/browser@1.3.1", "", { "dependencies": { "@hyperjump/json-pointer": "^1.1.0", "@hyperjump/uri": "^1.2.0", "content-type": "^1.0.5", "just-curry-it": "^5.3.0" } }, "sha512-Le5XZUjnVqVjkgLYv6yyWgALat/0HpB1XaCPuCZ+GCFki9NvXloSZITIJ0H+wRW7mb9At1SxvohKBbNQbrr/cw=="],
"@hyperjump/json-pointer": ["@hyperjump/json-pointer@1.1.1", "", {}, "sha512-M0T3s7TC2JepoWPMZQn1W6eYhFh06OXwpMqL+8c5wMVpvnCKNsPgpu9u7WyCI03xVQti8JAeAy4RzUa6SYlJLA=="],
"@hyperjump/json-schema": ["@hyperjump/json-schema@1.16.2", "", { "dependencies": { "@hyperjump/json-pointer": "^1.1.0", "@hyperjump/pact": "^1.2.0", "@hyperjump/uri": "^1.2.0", "content-type": "^1.0.4", "json-stringify-deterministic": "^1.0.12", "just-curry-it": "^5.3.0", "uuid": "^9.0.0" }, "peerDependencies": { "@hyperjump/browser": "^1.1.0" } }, "sha512-MJNvaEFc79+h5rvBPgAJK4OHEUr0RqsKcLC5rc3V9FEsJyQAjnP910deRFoZCE068kX/NrAPPhunMgUMwonPtg=="],
"@hyperjump/pact": ["@hyperjump/pact@1.4.0", "", {}, "sha512-01Q7VY6BcAkp9W31Fv+ciiZycxZHGlR2N6ba9BifgyclHYHdbaZgITo0U6QMhYRlem4k8pf8J31/tApxvqAz8A=="],
"@hyperjump/uri": ["@hyperjump/uri@1.3.1", "", {}, "sha512-2ecKymxf6prQMgrNpAvlx4RhsuM5+PFT6oh6uUTZdv5qmBv0RZvxv8LJ7oR30ZxGhdPdZAl4We/1NFc0nqHeAw=="],
"@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
"@iconify/utils": ["@iconify/utils@2.3.0", "", { "dependencies": { "@antfu/install-pkg": "^1.0.0", "@antfu/utils": "^8.1.0", "@iconify/types": "^2.0.0", "debug": "^4.4.0", "globals": "^15.14.0", "kolorist": "^1.8.0", "local-pkg": "^1.0.0", "mlly": "^1.7.4" } }, "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA=="],
@ -179,10 +265,42 @@
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.3", "", { "os": "win32", "cpu": "x64" }, "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g=="],
"@internationalized/date": ["@internationalized/date@3.9.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-yaN3brAnHRD+4KyyOsJyk49XUvj2wtbNACSqg0bz3u8t2VuzhC8Q5dfRnrSxjnnbDb+ienBnkn1TzQfE154vyg=="],
"@internationalized/number": ["@internationalized/number@3.6.5", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.4", "", {}, "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.30", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q=="],
"@jsdevtools/ono": ["@jsdevtools/ono@7.1.3", "", {}, "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="],
"@lezer/common": ["@lezer/common@1.2.3", "", {}, "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="],
"@lezer/css": ["@lezer/css@1.3.0", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.3.0" } }, "sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw=="],
"@lezer/highlight": ["@lezer/highlight@1.2.1", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA=="],
"@lezer/html": ["@lezer/html@1.3.10", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-dqpT8nISx/p9Do3AchvYGV3qYc4/rKr3IBZxlHmpIKam56P47RSHkSF5f13Vu9hebS1jM0HmtJIwLbWz1VIY6w=="],
"@lezer/javascript": ["@lezer/javascript@1.5.1", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.1.3", "@lezer/lr": "^1.3.0" } }, "sha512-ATOImjeVJuvgm3JQ/bpo2Tmv55HSScE2MTPnKRMRIPx2cLhHGyX2VnqpHhtIV1tVzIjZDbcWQm+NCTF40ggZVw=="],
"@lezer/json": ["@lezer/json@1.0.3", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ=="],
"@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="],
"@lezer/xml": ["@lezer/xml@1.0.6", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww=="],
"@lezer/yaml": ["@lezer/yaml@1.0.3", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.4.0" } }, "sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA=="],
"@lorenzo_lewis/starlight-utils": ["@lorenzo_lewis/starlight-utils@0.3.2", "", { "dependencies": { "astro-integration-kit": "^0.18.0" }, "peerDependencies": { "@astrojs/starlight": ">=0.32.0", "astro": ">=5" } }, "sha512-9GCZLyfIUTkXuE39jHjcCSwnOzm6hSGnC8DrHlo2imegiZmZSdG0eBMA/sTb/shLkvCzE2SGCaKM+EwIeO6oDw=="],
"@marijn/find-cluster-break": ["@marijn/find-cluster-break@1.0.2", "", {}, "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g=="],
"@mdx-js/mdx": ["@mdx-js/mdx@3.1.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw=="],
"@mermaid-js/parser": ["@mermaid-js/parser@0.6.2", "", { "dependencies": { "langium": "3.3.1" } }, "sha512-+PO02uGF6L6Cs0Bw8RpGhikVvMWEysfAyl27qTlroUB8jSWr1lL0Sf6zi78ZxlSnmgSY2AMMKVgghnN9jTtwkQ=="],
@ -201,6 +319,8 @@
"@pagefind/windows-x64": ["@pagefind/windows-x64@1.3.0", "", { "os": "win32", "cpu": "x64" }, "sha512-BR1bIRWOMqkf8IoU576YDhij1Wd/Zf2kX/kCI0b2qzCKC8wcc2GQJaaRMCpzvCCrmliO4vtJ6RITp/AnoYUUmQ=="],
"@phosphor-icons/core": ["@phosphor-icons/core@2.1.1", "", {}, "sha512-v4ARvrip4qBCImOE5rmPUylOEK4iiED9ZyKjcvzuezqMaiRASCHKcRIuvvxL/twvLpkfnEODCOJp5dM4eZilxQ=="],
"@readme/better-ajv-errors": ["@readme/better-ajv-errors@2.3.2", "", { "dependencies": { "@babel/code-frame": "^7.22.5", "@babel/runtime": "^7.22.5", "@humanwhocodes/momoa": "^2.0.3", "jsonpointer": "^5.0.0", "leven": "^3.1.0", "picocolors": "^1.1.1" }, "peerDependencies": { "ajv": "4.11.8 - 8" } }, "sha512-T4GGnRAlY3C339NhoUpgJJFsMYko9vIgFAlhgV+/vEGFw66qEY4a4TRJIAZBcX/qT1pq5DvXSme+SQODHOoBrw=="],
"@readme/json-schema-ref-parser": ["@readme/json-schema-ref-parser@1.2.0", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.6", "call-me-maybe": "^1.0.1", "js-yaml": "^4.1.0" } }, "sha512-Bt3QVovFSua4QmHa65EHUmh2xS0XJ3rgTEUPH998f4OW4VVJke3BuS16f+kM0ZLOGdvIrzrPRqwihuv5BAjtrA=="],
@ -209,6 +329,10 @@
"@readme/openapi-schemas": ["@readme/openapi-schemas@3.1.0", "", {}, "sha512-9FC/6ho8uFa8fV50+FPy/ngWN53jaUu4GRXlAjcxIRrzhltJnpKkBG2Tp0IDraFJeWrOpk84RJ9EMEEYzaI1Bw=="],
"@replit/codemirror-css-color-picker": ["@replit/codemirror-css-color-picker@6.3.0", "", { "peerDependencies": { "@codemirror/language": "^6.0.0", "@codemirror/state": "^6.0.0", "@codemirror/view": "^6.0.0" } }, "sha512-19biDANghUm7Fz7L1SNMIhK48tagaWuCOHj4oPPxc7hxPGkTVY2lU/jVZ8tsbTKQPVG7BO2CBDzs7CBwb20t4A=="],
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.27", "", {}, "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA=="],
"@rollup/pluginutils": ["@rollup/pluginutils@5.2.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", "picomatch": "^4.0.2" }, "peerDependencies": { "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, "optionalPeers": ["rollup"] }, "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.45.1", "", { "os": "android", "cpu": "arm" }, "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA=="],
@ -251,6 +375,50 @@
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.45.1", "", { "os": "win32", "cpu": "x64" }, "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA=="],
"@scalar/api-client": ["@scalar/api-client@2.5.26", "", { "dependencies": { "@headlessui/tailwindcss": "^0.2.2", "@headlessui/vue": "^1.7.23", "@scalar/components": "0.14.27", "@scalar/draggable": "0.2.0", "@scalar/helpers": "0.0.8", "@scalar/icons": "0.4.7", "@scalar/import": "0.4.19", "@scalar/oas-utils": "0.4.22", "@scalar/object-utils": "1.2.4", "@scalar/openapi-parser": "0.20.1", "@scalar/openapi-types": "0.3.7", "@scalar/postman-to-openapi": "0.3.25", "@scalar/snippetz": "0.4.7", "@scalar/themes": "0.13.14", "@scalar/types": "0.2.13", "@scalar/use-codemirror": "0.12.28", "@scalar/use-hooks": "0.2.4", "@scalar/use-toasts": "0.8.0", "@types/har-format": "^1.2.15", "@vueuse/core": "^11.2.0", "@vueuse/integrations": "^11.2.0", "focus-trap": "^7", "fuse.js": "^7.1.0", "microdiff": "^1.5.0", "nanoid": "5.1.5", "pretty-bytes": "^6.1.1", "pretty-ms": "^8.0.0", "shell-quote": "^1.8.1", "type-fest": "4.41.0", "vue": "^3.5.17", "vue-router": "^4.3.0", "whatwg-mimetype": "^4.0.0", "yaml": "2.8.0", "zod": "3.24.1" } }, "sha512-f5NWAr8aRBpANLAWVhIXlO3ehe/lY47nufoltnpR4QLu0xSNwAa8MdL9hQuU9Cka6cGp/h9NE60ad1qM1m/eFA=="],
"@scalar/api-reference": ["@scalar/api-reference@1.34.6", "", { "dependencies": { "@floating-ui/vue": "^1.1.7", "@headlessui/vue": "^1.7.23", "@scalar/api-client": "2.5.26", "@scalar/code-highlight": "0.1.9", "@scalar/components": "0.14.27", "@scalar/helpers": "0.0.8", "@scalar/icons": "0.4.7", "@scalar/json-magic": "0.3.1", "@scalar/oas-utils": "0.4.22", "@scalar/object-utils": "1.2.4", "@scalar/openapi-parser": "0.20.1", "@scalar/openapi-types": "0.3.7", "@scalar/snippetz": "0.4.7", "@scalar/themes": "0.13.14", "@scalar/types": "0.2.13", "@scalar/use-hooks": "0.2.4", "@scalar/use-toasts": "0.8.0", "@scalar/workspace-store": "0.14.2", "@unhead/vue": "^1.11.20", "@vueuse/core": "^11.2.0", "flatted": "^3.3.3", "fuse.js": "^7.1.0", "github-slugger": "^2.0.0", "microdiff": "^1.5.0", "nanoid": "5.1.5", "vue": "^3.5.17", "zod": "3.24.1" } }, "sha512-QOLca2cM9yrbLs+Wy/OGIakit2JJXG4yPJDzUcCxXdVXaKJGb2dax3anUITPl9PObW9UBEKCy27ClJFDJSlXkw=="],
"@scalar/api-reference-react": ["@scalar/api-reference-react@0.7.42", "", { "dependencies": { "@scalar/api-reference": "1.34.6", "@scalar/types": "0.2.13" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-hqy8i7D4DijNbv4MF5ooXP/XkexghBWrtkFf5S9qRUG2VX3JAvhFksyWIqdkpWrOjZ40OPlcashbWKO0s/Hcww=="],
"@scalar/code-highlight": ["@scalar/code-highlight@0.1.9", "", { "dependencies": { "hast-util-to-text": "^4.0.2", "highlight.js": "^11.9.0", "highlightjs-curl": "^1.3.0", "highlightjs-vue": "^1.0.0", "lowlight": "^3.1.0", "rehype-external-links": "^3.0.0", "rehype-format": "^5.0.0", "rehype-parse": "^9.0.0", "rehype-raw": "^7.0.0", "rehype-sanitize": "^6.0.0", "rehype-stringify": "^10.0.0", "remark-gfm": "^4.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.0", "remark-stringify": "^11.0.0", "unified": "^11.0.4", "unist-util-visit": "^5.0.0" } }, "sha512-WUUVDd1Wk7QJVKWXl/Zdn/VINc2pc1NlWW8VJFYZRm3/hKJwBhi0on7+HjVQNKgUaRy7+zluru5Ckl1gcTHHEg=="],
"@scalar/components": ["@scalar/components@0.14.27", "", { "dependencies": { "@floating-ui/utils": "^0.2.2", "@floating-ui/vue": "^1.1.7", "@headlessui/vue": "^1.7.23", "@scalar/code-highlight": "0.1.9", "@scalar/helpers": "0.0.8", "@scalar/icons": "0.4.7", "@scalar/oas-utils": "0.4.22", "@scalar/themes": "0.13.14", "@scalar/use-hooks": "0.2.4", "@scalar/use-toasts": "0.8.0", "@vueuse/core": "^11.2.0", "cva": "1.0.0-beta.2", "nanoid": "5.1.5", "pretty-bytes": "^6.1.1", "radix-vue": "^1.9.3", "vue": "^3.5.17", "vue-component-type-helpers": "^3.0.4" } }, "sha512-XMm3oaGy9oBKO7XAoI3mLnr5wKGacefj358XYPNjYGGN9qx60burOdGuFPzCGPnhS++th+O0h7drCXy1mznPfQ=="],
"@scalar/draggable": ["@scalar/draggable@0.2.0", "", { "dependencies": { "vue": "^3.5.12" } }, "sha512-UetHRB5Bqo5egVYlS21roWBcICmyk8CKh2htsidO+bFGAjl2e7Te+rY0borhNrMclr0xezHlPuLpEs1dvgLS2g=="],
"@scalar/helpers": ["@scalar/helpers@0.0.8", "", {}, "sha512-9A1CxL3jV7Kl9wGu86/cR/wiJN6J+3tK4WuW3252s2gF+upXsgQRx9WLhFF3xifOP1irIGusitZBiojiKmUSVg=="],
"@scalar/icons": ["@scalar/icons@0.4.7", "", { "dependencies": { "@phosphor-icons/core": "^2.1.1", "@types/node": "^22.9.0", "chalk": "^5.4.1", "vue": "^3.5.17" } }, "sha512-0qXPGRdZ180TMfejWCPYy7ILszBrAraq4KBhPtcM12ghc5qkncFWWpTm5yXI/vrbm10t7wvtTK08CLZ36CnXlQ=="],
"@scalar/import": ["@scalar/import@0.4.19", "", { "dependencies": { "@scalar/helpers": "0.0.8", "@scalar/openapi-parser": "0.20.1", "yaml": "2.8.0" } }, "sha512-Y8BB0/msE/y9U1aiU4ioH/sDIVcvxmcEPDfTr2PGcTNamMmwOnAYN7AcEYQarlDo1CVjyzsIdiaEdrgQyZ4y9A=="],
"@scalar/json-magic": ["@scalar/json-magic@0.3.1", "", { "dependencies": { "@scalar/helpers": "0.0.8", "vue": "^3.5.17", "yaml": "2.8.0" } }, "sha512-vQvl4TckiMT8Txo6S82ETJ4OI+K6iSxLZsjPaq4cEqY+9zVfmIMALFGPj/X5BB8tU3FdluV2yEa8LswsMQ68IA=="],
"@scalar/oas-utils": ["@scalar/oas-utils@0.4.22", "", { "dependencies": { "@hyperjump/browser": "^1.1.0", "@hyperjump/json-schema": "^1.9.6", "@scalar/helpers": "0.0.8", "@scalar/json-magic": "0.3.1", "@scalar/object-utils": "1.2.4", "@scalar/openapi-types": "0.3.7", "@scalar/themes": "0.13.14", "@scalar/types": "0.2.13", "@scalar/workspace-store": "0.14.2", "@types/har-format": "^1.2.15", "flatted": "^3.3.3", "microdiff": "^1.5.0", "nanoid": "5.1.5", "type-fest": "4.41.0", "yaml": "2.8.0", "zod": "3.24.1" } }, "sha512-a8qvtU9GnHBKPvfflU2UF4mYi61Fc0V626bEgclCicwomrss7ic2MRyrwODmKR72F50Q2jWw0HeKE0DfqOjSPg=="],
"@scalar/object-utils": ["@scalar/object-utils@1.2.4", "", { "dependencies": { "@scalar/helpers": "0.0.8", "flatted": "^3.3.3", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1", "type-fest": "4.41.0" } }, "sha512-lX/+9Sp6euZvbsikGRZiHwmfbLd0oTLTttKbJF9v2EkahSrQUT0WF835Ct2N0R8xSkyQauDhT2xCfuA0QNqDeA=="],
"@scalar/openapi-parser": ["@scalar/openapi-parser@0.20.1", "", { "dependencies": { "@scalar/json-magic": "0.3.1", "@scalar/openapi-types": "0.3.7", "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "2.8.0" } }, "sha512-rxtuBQ90YsUEDefWU3GAEmvjYr1CvGO6nkDVzbjmWv2aPB3mtK80bCRBgQGTdIdW5XQEWAAmflSKEhcj2Xo5QA=="],
"@scalar/openapi-types": ["@scalar/openapi-types@0.3.7", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-QHSvHBVDze3+dUwAhIGq6l1iOev4jdoqdBK7QpfeN1Q4h+6qpVEw3EEqBiH0AXUSh/iWwObBv4uMgfIx0aNZ5g=="],
"@scalar/postman-to-openapi": ["@scalar/postman-to-openapi@0.3.25", "", { "dependencies": { "@scalar/helpers": "0.0.8", "@scalar/oas-utils": "0.4.22", "@scalar/openapi-types": "0.3.7" } }, "sha512-sMf85+uCjmzgyZ8pS7MbVm5FOVj/9SGOT/RX4xDG8LklpE77SQdYXO1G50kj8XEHMwLpsMh5Ufbt5Wft54DqlQ=="],
"@scalar/snippetz": ["@scalar/snippetz@0.4.7", "", { "dependencies": { "@scalar/types": "0.2.13", "stringify-object": "^5.0.0" } }, "sha512-SvjpZ8qVaGAxoypqsJLAlM95XEjccDXXEvd3ljlCoOYzG06tbMX+g8+Vfsv/FjMXQ0LB3/ZfpYjTrKO8h7ZU4Q=="],
"@scalar/themes": ["@scalar/themes@0.13.14", "", { "dependencies": { "@scalar/types": "0.2.13", "nanoid": "5.1.5" } }, "sha512-uYqWtzQuLaVAEcxRaLzIINRuocds2I+rj8dCHcg3RMdmvSn9oJ8ysEhOZGqzNE7nL5aD7sh2tFa2E4+iScWSyA=="],
"@scalar/types": ["@scalar/types@0.2.13", "", { "dependencies": { "@scalar/openapi-types": "0.3.7", "nanoid": "5.1.5", "zod": "3.24.1" } }, "sha512-rO6KGMJqOsBnN/2R4fErMFLpRSPVJElni+HABDpf+ZlLJp2lvxuPn0IXLumK5ytfplUH9iqKgSXjndnZfxSYLQ=="],
"@scalar/use-codemirror": ["@scalar/use-codemirror@0.12.28", "", { "dependencies": { "@codemirror/autocomplete": "^6.18.3", "@codemirror/commands": "^6.7.1", "@codemirror/lang-css": "^6.3.1", "@codemirror/lang-html": "^6.4.8", "@codemirror/lang-json": "^6.0.0", "@codemirror/lang-xml": "^6.0.0", "@codemirror/lang-yaml": "^6.1.2", "@codemirror/language": "^6.10.7", "@codemirror/lint": "^6.8.4", "@codemirror/state": "^6.5.0", "@codemirror/view": "^6.35.3", "@lezer/common": "^1.2.3", "@lezer/highlight": "^1.2.1", "@replit/codemirror-css-color-picker": "^6.3.0", "@scalar/components": "0.14.27", "codemirror": "^6.0.0", "vue": "^3.5.17" } }, "sha512-4hxuSI1lKmOpEMI5Xvv88wWKj6e3KV6RJUsi46Sb5fOsO3aRgYMDopWvo96nk/4wXD+g2QJIITsSL2Ic7NVnxA=="],
"@scalar/use-hooks": ["@scalar/use-hooks@0.2.4", "", { "dependencies": { "@scalar/use-toasts": "0.8.0", "@vueuse/core": "^10.10.0", "cva": "1.0.0-beta.2", "tailwind-merge": "^2.5.5", "vue": "^3.5.12", "zod": "3.24.1" } }, "sha512-TXviVV9Cfmei6g24QadnfuFj2r1YkZY56ufsSnwHgLNbtDRd9U9jXGIswXAuA+k7whaEVEgcoZ3Zmq2v5ZLF8w=="],
"@scalar/use-toasts": ["@scalar/use-toasts@0.8.0", "", { "dependencies": { "nanoid": "^5.1.5", "vue": "^3.5.12", "vue-sonner": "^1.0.3" } }, "sha512-u+o77cdTNZ5ePqHPu8ZcFw1BLlISv+cthN0bR1zJHXmqBjvanFTy2kL+Gmv3eW9HxZiHdqycKVETlYd0mWiqJQ=="],
"@scalar/workspace-store": ["@scalar/workspace-store@0.14.2", "", { "dependencies": { "@scalar/code-highlight": "0.1.9", "@scalar/helpers": "0.0.8", "@scalar/json-magic": "0.3.1", "@scalar/openapi-parser": "0.20.1", "@scalar/types": "0.2.13", "@sinclair/typebox": "https://raw.githubusercontent.com/DemonHa/typebox/refs/heads/amrit/build-2/target/sinclair-typebox-0.34.40.tgz", "github-slugger": "^2.0.0", "type-fest": "4.41.0", "vue": "^3.5.17", "yaml": "2.8.0" } }, "sha512-FLI//S2kxS4NxdKZ+SaMTUoMI7n2hZID/JznAid02+WU35QVA+Y3ioose7VzPRpDmPxeF3lhXgcPpcZ811yIjA=="],
"@shikijs/core": ["@shikijs/core@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-uTSXzUBQ/IgFcUa6gmGShCHr4tMdR3pxUiiWKDm8pd42UKJdYhkAYsAmHX5mTwybQ5VyGDgTjW4qKSsRvGSang=="],
"@shikijs/engine-javascript": ["@shikijs/engine-javascript@3.8.1", "", { "dependencies": { "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^4.3.3" } }, "sha512-rZRp3BM1llrHkuBPAdYAzjlF7OqlM0rm/7EWASeCcY7cRYZIrOnGIHE9qsLz5TCjGefxBFnwgIECzBs2vmOyKA=="],
@ -265,8 +433,22 @@
"@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="],
"@sinclair/typebox": ["@sinclair/typebox@https://raw.githubusercontent.com/DemonHa/typebox/refs/heads/amrit/build-2/target/sinclair-typebox-0.34.40.tgz", {}],
"@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="],
"@tanstack/virtual-core": ["@tanstack/virtual-core@3.13.12", "", {}, "sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA=="],
"@tanstack/vue-virtual": ["@tanstack/vue-virtual@3.13.12", "", { "dependencies": { "@tanstack/virtual-core": "3.13.12" }, "peerDependencies": { "vue": "^2.7.0 || ^3.0.0" } }, "sha512-vhF7kEU9EXWXh+HdAwKJ2m3xaOnTTmgcdXcF2pim8g4GvI7eRrk2YRuV5nUlZnd/NbCIX4/Ja2OZu5EjJL06Ww=="],
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
"@types/babel__template": ["@types/babel__template@7.4.4", "", { "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A=="],
"@types/babel__traverse": ["@types/babel__traverse@7.28.0", "", { "dependencies": { "@babel/types": "^7.28.2" } }, "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q=="],
"@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="],
"@types/d3-array": ["@types/d3-array@3.2.1", "", {}, "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="],
@ -339,6 +521,8 @@
"@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="],
"@types/har-format": ["@types/har-format@1.2.16", "", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="],
"@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="],
"@types/js-yaml": ["@types/js-yaml@4.0.9", "", {}, "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg=="],
@ -355,14 +539,58 @@
"@types/node": ["@types/node@17.0.45", "", {}, "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw=="],
"@types/react": ["@types/react@19.1.12", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w=="],
"@types/react-dom": ["@types/react-dom@19.1.9", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ=="],
"@types/sax": ["@types/sax@1.2.7", "", { "dependencies": { "@types/node": "*" } }, "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A=="],
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
"@types/web-bluetooth": ["@types/web-bluetooth@0.0.20", "", {}, "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="],
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
"@unhead/dom": ["@unhead/dom@1.11.20", "", { "dependencies": { "@unhead/schema": "1.11.20", "@unhead/shared": "1.11.20" } }, "sha512-jgfGYdOH+xHJF/j8gudjsYu3oIjFyXhCWcgKaw3vQnT616gSqyqnGQGOItL+BQtQZACKNISwIfx5PuOtztMKLA=="],
"@unhead/schema": ["@unhead/schema@1.11.20", "", { "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" } }, "sha512-0zWykKAaJdm+/Y7yi/Yds20PrUK7XabLe9c3IRcjnwYmSWY6z0Cr19VIs3ozCj8P+GhR+/TI2mwtGlueCEYouA=="],
"@unhead/shared": ["@unhead/shared@1.11.20", "", { "dependencies": { "@unhead/schema": "1.11.20", "packrup": "^0.1.2" } }, "sha512-1MOrBkGgkUXS+sOKz/DBh4U20DNoITlJwpmvSInxEUNhghSNb56S0RnaHRq0iHkhrO/cDgz2zvfdlRpoPLGI3w=="],
"@unhead/vue": ["@unhead/vue@1.11.20", "", { "dependencies": { "@unhead/schema": "1.11.20", "@unhead/shared": "1.11.20", "hookable": "^5.5.3", "unhead": "1.11.20" }, "peerDependencies": { "vue": ">=2.7 || >=3" } }, "sha512-sqQaLbwqY9TvLEGeq8Fd7+F2TIuV3nZ5ihVISHjWpAM3y7DwNWRU7NmT9+yYT+2/jw1Vjwdkv5/HvDnvCLrgmg=="],
"@vitejs/plugin-react": ["@vitejs/plugin-react@4.7.0", "", { "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" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA=="],
"@vue/compiler-core": ["@vue/compiler-core@3.5.21", "", { "dependencies": { "@babel/parser": "^7.28.3", "@vue/shared": "3.5.21", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-8i+LZ0vf6ZgII5Z9XmUvrCyEzocvWT+TeR2VBUVlzIH6Tyv57E20mPZ1bCS+tbejgUgmjrEh7q/0F0bibskAmw=="],
"@vue/compiler-dom": ["@vue/compiler-dom@3.5.21", "", { "dependencies": { "@vue/compiler-core": "3.5.21", "@vue/shared": "3.5.21" } }, "sha512-jNtbu/u97wiyEBJlJ9kmdw7tAr5Vy0Aj5CgQmo+6pxWNQhXZDPsRr1UWPN4v3Zf82s2H3kF51IbzZ4jMWAgPlQ=="],
"@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.21", "", { "dependencies": { "@babel/parser": "^7.28.3", "@vue/compiler-core": "3.5.21", "@vue/compiler-dom": "3.5.21", "@vue/compiler-ssr": "3.5.21", "@vue/shared": "3.5.21", "estree-walker": "^2.0.2", "magic-string": "^0.30.18", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-SXlyk6I5eUGBd2v8Ie7tF6ADHE9kCR6mBEuPyH1nUZ0h6Xx6nZI29i12sJKQmzbDyr2tUHMhhTt51Z6blbkTTQ=="],
"@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.21", "", { "dependencies": { "@vue/compiler-dom": "3.5.21", "@vue/shared": "3.5.21" } }, "sha512-vKQ5olH5edFZdf5ZrlEgSO1j1DMA4u23TVK5XR1uMhvwnYvVdDF0nHXJUblL/GvzlShQbjhZZ2uvYmDlAbgo9w=="],
"@vue/devtools-api": ["@vue/devtools-api@6.6.4", "", {}, "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g=="],
"@vue/reactivity": ["@vue/reactivity@3.5.21", "", { "dependencies": { "@vue/shared": "3.5.21" } }, "sha512-3ah7sa+Cwr9iiYEERt9JfZKPw4A2UlbY8RbbnH2mGCE8NwHkhmlZt2VsH0oDA3P08X3jJd29ohBDtX+TbD9AsA=="],
"@vue/runtime-core": ["@vue/runtime-core@3.5.21", "", { "dependencies": { "@vue/reactivity": "3.5.21", "@vue/shared": "3.5.21" } }, "sha512-+DplQlRS4MXfIf9gfD1BOJpk5RSyGgGXD/R+cumhe8jdjUcq/qlxDawQlSI8hCKupBlvM+3eS1se5xW+SuNAwA=="],
"@vue/runtime-dom": ["@vue/runtime-dom@3.5.21", "", { "dependencies": { "@vue/reactivity": "3.5.21", "@vue/runtime-core": "3.5.21", "@vue/shared": "3.5.21", "csstype": "^3.1.3" } }, "sha512-3M2DZsOFwM5qI15wrMmNF5RJe1+ARijt2HM3TbzBbPSuBHOQpoidE+Pa+XEaVN+czbHf81ETRoG1ltztP2em8w=="],
"@vue/server-renderer": ["@vue/server-renderer@3.5.21", "", { "dependencies": { "@vue/compiler-ssr": "3.5.21", "@vue/shared": "3.5.21" }, "peerDependencies": { "vue": "3.5.21" } }, "sha512-qr8AqgD3DJPJcGvLcJKQo2tAc8OnXRcfxhOJCPF+fcfn5bBGz7VCcO7t+qETOPxpWK1mgysXvVT/j+xWaHeMWA=="],
"@vue/shared": ["@vue/shared@3.5.21", "", {}, "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw=="],
"@vueuse/core": ["@vueuse/core@11.3.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "11.3.0", "@vueuse/shared": "11.3.0", "vue-demi": ">=0.14.10" } }, "sha512-7OC4Rl1f9G8IT6rUfi9JrKiXy4bfmHhZ5x2Ceojy0jnd3mHNEvV4JaRygH362ror6/NZ+Nl+n13LPzGiPN8cKA=="],
"@vueuse/integrations": ["@vueuse/integrations@11.3.0", "", { "dependencies": { "@vueuse/core": "11.3.0", "@vueuse/shared": "11.3.0", "vue-demi": ">=0.14.10" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7" }, "optionalPeers": ["async-validator", "axios", "change-case", "drauu", "focus-trap", "fuse.js", "idb-keyval", "jwt-decode", "nprogress", "qrcode", "sortablejs", "universal-cookie"] }, "sha512-5fzRl0apQWrDezmobchoiGTkGw238VWESxZHazfhP3RM7pDSiyXy18QbfYkILoYNTd23HPAfQTJpkUc5QbkwTw=="],
"@vueuse/metadata": ["@vueuse/metadata@11.3.0", "", {}, "sha512-pwDnDspTqtTo2HwfLw4Rp6yywuuBdYnPYDq+mO38ZYKGebCUQC/nVj/PXSiK9HX5otxLz8Fn7ECPbjiRz2CC3g=="],
"@vueuse/shared": ["@vueuse/shared@11.3.0", "", { "dependencies": { "vue-demi": ">=0.14.10" } }, "sha512-P8gSSWQeucH5821ek2mn/ciCk+MS/zoRKqdQIM3bHq6p7GXDAJLmnRRKmF5F65sAVJIfzQlwR3aDzwCn10s8hA=="],
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
@ -371,6 +599,8 @@
"ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="],
"ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
"ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
"ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
@ -383,16 +613,22 @@
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"aria-hidden": ["aria-hidden@1.2.6", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA=="],
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
"array-iterate": ["array-iterate@2.0.1", "", {}, "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg=="],
"ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="],
"astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="],
"astro": ["astro@5.12.1", "", { "dependencies": { "@astrojs/compiler": "^2.12.2", "@astrojs/internal-helpers": "0.6.1", "@astrojs/markdown-remark": "6.3.3", "@astrojs/telemetry": "3.3.0", "@capsizecss/unpack": "^2.4.0", "@oslojs/encoding": "^1.1.0", "@rollup/pluginutils": "^5.1.4", "acorn": "^8.14.1", "aria-query": "^5.3.2", "axobject-query": "^4.1.0", "boxen": "8.0.1", "ci-info": "^4.2.0", "clsx": "^2.1.1", "common-ancestor-path": "^1.0.1", "cookie": "^1.0.2", "cssesc": "^3.0.0", "debug": "^4.4.0", "deterministic-object-hash": "^2.0.2", "devalue": "^5.1.1", "diff": "^5.2.0", "dlv": "^1.1.3", "dset": "^3.1.4", "es-module-lexer": "^1.6.0", "esbuild": "^0.25.0", "estree-walker": "^3.0.3", "flattie": "^1.1.1", "fontace": "~0.3.0", "github-slugger": "^2.0.0", "html-escaper": "3.0.3", "http-cache-semantics": "^4.1.1", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.17", "magicast": "^0.3.5", "mrmime": "^2.0.1", "neotraverse": "^0.6.18", "p-limit": "^6.2.0", "p-queue": "^8.1.0", "package-manager-detector": "^1.1.0", "picomatch": "^4.0.2", "prompts": "^2.4.2", "rehype": "^13.0.2", "semver": "^7.7.1", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.12", "tsconfck": "^3.1.5", "ultrahtml": "^1.6.0", "unifont": "~0.5.0", "unist-util-visit": "^5.0.0", "unstorage": "^1.15.0", "vfile": "^6.0.3", "vite": "^6.3.4", "vitefu": "^1.0.6", "xxhash-wasm": "^1.1.0", "yargs-parser": "^21.1.1", "yocto-spinner": "^0.2.1", "zod": "^3.24.2", "zod-to-json-schema": "^3.24.5", "zod-to-ts": "^1.2.0" }, "optionalDependencies": { "sharp": "^0.33.3" }, "bin": { "astro": "astro.js" } }, "sha512-/gH9cLIp6UNdbJO1FPBVN/Ea+1I9hJdQoLJKYUsXIRIfHcyF/3NCg0QVDJGw1oWkyQT6x6poQsnbgY9UXitjiw=="],
"astro-expressive-code": ["astro-expressive-code@0.41.3", "", { "dependencies": { "rehype-expressive-code": "^0.41.3" }, "peerDependencies": { "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0" } }, "sha512-u+zHMqo/QNLE2eqYRCrK3+XMlKakv33Bzuz+56V1gs8H0y6TZ0hIi3VNbIxeTn51NLn+mJfUV/A0kMNfE4rANw=="],
"astro-integration-kit": ["astro-integration-kit@0.18.0", "", { "dependencies": { "pathe": "^1.1.2", "recast": "^0.23.7" }, "peerDependencies": { "astro": "^4.12.0 || ^5.0.0" } }, "sha512-Z0QW5IQjosuKQDEGYYkvUX6EhEtrmE4/oViqWz23QveV8U7AuyFsTdg00WRNPevWZl/5a4lLUeDpv4bCRynRRg=="],
"astro-mermaid": ["astro-mermaid@1.0.4", "", { "dependencies": { "mdast-util-to-string": "^4.0.0", "unist-util-visit": "^5.0.0" }, "peerDependencies": { "astro": "^4.0.0 || ^5.0.0", "mermaid": "^10.0.0 || ^11.0.0" } }, "sha512-2M4bVjqLpDB2EZ4EfD6Utzs7VEEORmlt5hNZcMK54IcKWzflohKvowCzg79RHoAdu30W8a4aECAExH8mF7wG4w=="],
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
@ -415,10 +651,14 @@
"brotli": ["brotli@1.3.3", "", { "dependencies": { "base64-js": "^1.1.2" } }, "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg=="],
"browserslist": ["browserslist@4.25.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001737", "electron-to-chromium": "^1.5.211", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.3" }, "bin": { "browserslist": "cli.js" } }, "sha512-4jYpcjabC606xJ3kw2QwGEZKX0Aw7sgQdZCvIK9dhVSPh76BKo+C+btT1RRofH7B+8iNpEbgGNVWiLki5q93yg=="],
"call-me-maybe": ["call-me-maybe@1.0.2", "", {}, "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ=="],
"camelcase": ["camelcase@8.0.0", "", {}, "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA=="],
"caniuse-lite": ["caniuse-lite@1.0.30001739", "", {}, "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA=="],
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
"chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="],
@ -445,6 +685,8 @@
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
"codemirror": ["codemirror@6.0.2", "", { "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" } }, "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw=="],
"collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="],
"color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
@ -463,12 +705,18 @@
"confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="],
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
"cookie-es": ["cookie-es@1.2.2", "", {}, "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg=="],
"cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="],
"crelt": ["crelt@1.0.6", "", {}, "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="],
"cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="],
"crossws": ["crossws@0.3.5", "", { "dependencies": { "uncrypto": "^0.1.3" } }, "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA=="],
@ -479,6 +727,10 @@
"cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"cva": ["cva@1.0.0-beta.2", "", { "dependencies": { "clsx": "^2.1.1" }, "peerDependencies": { "typescript": ">= 4.5.5 < 6" }, "optionalPeers": ["typescript"] }, "sha512-dqcOFe247I5pKxfuzqfq3seLL5iMYsTgo40Uw7+pKZAntPgFtR7Tmy59P5IVIq/XgB0NQWoIvYDt9TwHkuK8Cg=="],
"cytoscape": ["cytoscape@3.32.1", "", {}, "sha512-dbeqFTLYEwlFg7UGtcZhCCG/2WayX72zK3Sq323CEX29CY81tYfVhw1MIdduCtpstB0cTOhJswWlM/OEB3Xp+Q=="],
"cytoscape-cose-bilkent": ["cytoscape-cose-bilkent@4.1.0", "", { "dependencies": { "cose-base": "^1.0.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ=="],
@ -585,6 +837,8 @@
"dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="],
"electron-to-chromium": ["electron-to-chromium@1.5.212", "", {}, "sha512-gE7ErIzSW+d8jALWMcOIgf+IB6lpfsg6NwOhPVwKzDtN2qcBix47vlin4yzSregYDxTCXOUqAZjVY/Z3naS7ww=="],
"emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
@ -597,8 +851,12 @@
"esbuild": ["esbuild@0.25.8", "", { "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" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
"escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
"estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="],
"estree-util-build-jsx": ["estree-util-build-jsx@3.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-walker": "^3.0.0" } }, "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ=="],
@ -627,16 +885,26 @@
"fdir": ["fdir@6.4.6", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w=="],
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
"flattie": ["flattie@1.1.1", "", {}, "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ=="],
"focus-trap": ["focus-trap@7.6.5", "", { "dependencies": { "tabbable": "^6.2.0" } }, "sha512-7Ke1jyybbbPZyZXFxEftUtxFGLMpE2n6A+z//m4CRDlj0hW+o3iYSmh8nFlYMurOiJVDmJRilUQtJr08KfIxlg=="],
"fontace": ["fontace@0.3.0", "", { "dependencies": { "@types/fontkit": "^2.0.8", "fontkit": "^2.0.4" } }, "sha512-czoqATrcnxgWb/nAkfyIrRp6Q8biYj7nGnL6zfhTcX+JKKpWHFBnb8uNMw/kZr7u++3Y3wYSYoZgHkCcsuBpBg=="],
"fontkit": ["fontkit@2.0.4", "", { "dependencies": { "@swc/helpers": "^0.5.12", "brotli": "^1.3.2", "clone": "^2.1.2", "dfa": "^1.2.0", "fast-deep-equal": "^3.1.3", "restructure": "^3.0.0", "tiny-inflate": "^1.0.3", "unicode-properties": "^1.4.0", "unicode-trie": "^2.0.0" } }, "sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"fuse.js": ["fuse.js@7.1.0", "", {}, "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ=="],
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
"get-east-asian-width": ["get-east-asian-width@1.3.0", "", {}, "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ=="],
"get-own-enumerable-keys": ["get-own-enumerable-keys@1.0.0", "", {}, "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA=="],
"github-slugger": ["github-slugger@2.0.0", "", {}, "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="],
"globals": ["globals@15.15.0", "", {}, "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg=="],
@ -667,6 +935,8 @@
"hast-util-raw": ["hast-util-raw@9.1.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-from-parse5": "^8.0.0", "hast-util-to-parse5": "^8.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "parse5": "^7.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0", "web-namespaces": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw=="],
"hast-util-sanitize": ["hast-util-sanitize@5.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "unist-util-position": "^5.0.0" } }, "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg=="],
"hast-util-select": ["hast-util-select@6.0.4", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "bcp-47-match": "^2.0.0", "comma-separated-tokens": "^2.0.0", "css-selector-parser": "^3.0.0", "devlop": "^1.0.0", "direction": "^2.0.0", "hast-util-has-property": "^3.0.0", "hast-util-to-string": "^3.0.0", "hast-util-whitespace": "^3.0.0", "nth-check": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw=="],
"hast-util-to-estree": ["hast-util-to-estree@3.1.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-attach-comments": "^3.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="],
@ -685,6 +955,14 @@
"hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="],
"highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="],
"highlightjs-curl": ["highlightjs-curl@1.3.0", "", {}, "sha512-50UEfZq1KR0Lfk2Tr6xb/MUIZH3h10oNC0OTy9g7WELcs5Fgy/mKN1vEhuKTkKbdo8vr5F9GXstu2eLhApfQ3A=="],
"highlightjs-vue": ["highlightjs-vue@1.0.0", "", {}, "sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA=="],
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
"html-escaper": ["html-escaper@3.0.3", "", {}, "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ=="],
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
@ -705,6 +983,8 @@
"iron-webcrypto": ["iron-webcrypto@1.2.1", "", {}, "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg=="],
"is-absolute-url": ["is-absolute-url@4.0.1", "", {}, "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A=="],
"is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="],
"is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="],
@ -721,18 +1001,32 @@
"is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="],
"is-obj": ["is-obj@3.0.0", "", {}, "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ=="],
"is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="],
"is-regexp": ["is-regexp@3.1.0", "", {}, "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA=="],
"is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"json-stringify-deterministic": ["json-stringify-deterministic@1.0.12", "", {}, "sha512-q3PN0lbUdv0pmurkBNdJH3pfFvOTL/Zp0lquqpvcjfKzt6Y0j49EPHAmVHCAS4Ceq/Y+PejWTzyiVpoY71+D6g=="],
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
"jsonpointer": ["jsonpointer@5.0.1", "", {}, "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ=="],
"just-clone": ["just-clone@6.2.0", "", {}, "sha512-1IynUYEc/HAwxhi3WDpIpxJbZpMCvvrrmZVqvj9EhpvbH8lls7HhdhiByjL7DkAaWlLIzpC0Xc/VPvy/UxLNjA=="],
"just-curry-it": ["just-curry-it@5.3.0", "", {}, "sha512-silMIRiFjUWlfaDhkgSzpuAyQ6EX/o09Eu8ZBfmFwQMbax7+LQzeIU2CBrICT6Ne4l86ITCGvUCBpCubWYy0Yw=="],
"katex": ["katex@0.16.22", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg=="],
"khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="],
@ -747,7 +1041,7 @@
"layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="],
"leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
"leven": ["leven@4.0.0", "", {}, "sha512-puehA3YKku3osqPlNuzGDUHq8WpwXupUg1V6NXdV38G+gr+gkBwFC8g1b/+YcIvp8gnqVIus+eJCH/eGsRmJNw=="],
"local-pkg": ["local-pkg@1.1.1", "", { "dependencies": { "mlly": "^1.7.4", "pkg-types": "^2.0.1", "quansync": "^0.2.8" } }, "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg=="],
@ -755,6 +1049,8 @@
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
"lowlight": ["lowlight@3.3.0", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "highlight.js": "~11.11.0" } }, "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ=="],
"lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"magic-string": ["magic-string@0.30.17", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } }, "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA=="],
@ -807,6 +1103,8 @@
"mermaid": ["mermaid@11.9.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.0.4", "@iconify/utils": "^2.1.33", "@mermaid-js/parser": "^0.6.2", "@types/d3": "^7.4.3", "cytoscape": "^3.29.3", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.11", "dayjs": "^1.11.13", "dompurify": "^3.2.5", "katex": "^0.16.22", "khroma": "^2.1.0", "lodash-es": "^4.17.21", "marked": "^16.0.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-YdPXn9slEwO0omQfQIsW6vS84weVQftIyyTGAZCwM//MGhPzL1+l6vO6bkf0wnP4tHigH1alZ5Ooy3HXI2gOag=="],
"microdiff": ["microdiff@1.5.0", "", {}, "sha512-Drq+/THMvDdzRYrK0oxJmOKiC24ayUV8ahrt8l3oRK51PWt6gdtrIGrlIH3pT/lFh1z93FbAcidtsHcWbnRz8Q=="],
"micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="],
"micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="],
@ -885,7 +1183,7 @@
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"nanoid": ["nanoid@5.1.5", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw=="],
"neotraverse": ["neotraverse@0.6.18", "", {}, "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA=="],
@ -897,6 +1195,8 @@
"node-mock-http": ["node-mock-http@1.0.1", "", {}, "sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ=="],
"node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
@ -919,6 +1219,8 @@
"package-manager-detector": ["package-manager-detector@1.3.0", "", {}, "sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ=="],
"packrup": ["packrup@0.1.2", "", {}, "sha512-ZcKU7zrr5GlonoS9cxxrb5HVswGnyj6jQvwFBa6p5VFw7G71VAHcUKL5wyZSU/ECtPM/9gacWxy2KFQKt1gMNA=="],
"pagefind": ["pagefind@1.3.0", "", { "optionalDependencies": { "@pagefind/darwin-arm64": "1.3.0", "@pagefind/darwin-x64": "1.3.0", "@pagefind/linux-arm64": "1.3.0", "@pagefind/linux-x64": "1.3.0", "@pagefind/windows-x64": "1.3.0" }, "bin": { "pagefind": "lib/runner/bin.cjs" } }, "sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw=="],
"pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="],
@ -927,11 +1229,13 @@
"parse-latin": ["parse-latin@7.0.0", "", { "dependencies": { "@types/nlcst": "^2.0.0", "@types/unist": "^3.0.0", "nlcst-to-string": "^4.0.0", "unist-util-modify-children": "^4.0.0", "unist-util-visit-children": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ=="],
"parse-ms": ["parse-ms@3.0.0", "", {}, "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw=="],
"parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
"path-data-parser": ["path-data-parser@0.1.0", "", {}, "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w=="],
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
@ -949,6 +1253,10 @@
"postcss-selector-parser": ["postcss-selector-parser@6.1.2", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg=="],
"pretty-bytes": ["pretty-bytes@6.1.1", "", {}, "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ=="],
"pretty-ms": ["pretty-ms@8.0.0", "", { "dependencies": { "parse-ms": "^3.0.0" } }, "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q=="],
"prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
"prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="],
@ -957,10 +1265,20 @@
"quansync": ["quansync@0.2.10", "", {}, "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A=="],
"radix-vue": ["radix-vue@1.9.17", "", { "dependencies": { "@floating-ui/dom": "^1.6.7", "@floating-ui/vue": "^1.1.0", "@internationalized/date": "^3.5.4", "@internationalized/number": "^3.5.3", "@tanstack/vue-virtual": "^3.8.1", "@vueuse/core": "^10.11.0", "@vueuse/shared": "^10.11.0", "aria-hidden": "^1.2.4", "defu": "^6.1.4", "fast-deep-equal": "^3.1.3", "nanoid": "^5.0.7" }, "peerDependencies": { "vue": ">= 3.2.0" } }, "sha512-mVCu7I2vXt1L2IUYHTt0sZMz7s1K2ZtqKeTIxG3yC5mMFfLBG4FtE1FDeRMpDd+Hhg/ybi9+iXmAP1ISREndoQ=="],
"radix3": ["radix3@1.1.2", "", {}, "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="],
"react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="],
"react-dom": ["react-dom@19.1.1", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.1" } }, "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw=="],
"react-refresh": ["react-refresh@0.17.0", "", {}, "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ=="],
"readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="],
"recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
"recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="],
"recma-jsx": ["recma-jsx@1.0.0", "", { "dependencies": { "acorn-jsx": "^5.0.0", "estree-util-to-js": "^2.0.0", "recma-parse": "^1.0.0", "recma-stringify": "^1.0.0", "unified": "^11.0.0" } }, "sha512-5vwkv65qWwYxg+Atz95acp8DMu1JDSqdGkA2Of1j6rCreyFUE/gp15fC8MnGEuG1W68UKjM6x6+YTWIh7hZM/Q=="],
@ -979,6 +1297,8 @@
"rehype-expressive-code": ["rehype-expressive-code@0.41.3", "", { "dependencies": { "expressive-code": "^0.41.3" } }, "sha512-8d9Py4c/V6I/Od2VIXFAdpiO2kc0SV2qTJsRAaqSIcM9aruW4ASLNe2kOEo1inXAAkIhpFzAHTc358HKbvpNUg=="],
"rehype-external-links": ["rehype-external-links@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "hast-util-is-element": "^3.0.0", "is-absolute-url": "^4.0.0", "space-separated-tokens": "^2.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw=="],
"rehype-format": ["rehype-format@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-format": "^1.0.0" } }, "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ=="],
"rehype-parse": ["rehype-parse@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-html": "^2.0.0", "unified": "^11.0.0" } }, "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag=="],
@ -987,6 +1307,8 @@
"rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="],
"rehype-sanitize": ["rehype-sanitize@6.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-sanitize": "^5.0.0" } }, "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg=="],
"rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="],
"remark-directive": ["remark-directive@3.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", "micromark-extension-directive": "^3.0.0", "unified": "^11.0.0" } }, "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A=="],
@ -1027,10 +1349,14 @@
"sax": ["sax@1.4.1", "", {}, "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="],
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"sharp": ["sharp@0.34.3", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.4", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.3", "@img/sharp-darwin-x64": "0.34.3", "@img/sharp-libvips-darwin-arm64": "1.2.0", "@img/sharp-libvips-darwin-x64": "1.2.0", "@img/sharp-libvips-linux-arm": "1.2.0", "@img/sharp-libvips-linux-arm64": "1.2.0", "@img/sharp-libvips-linux-ppc64": "1.2.0", "@img/sharp-libvips-linux-s390x": "1.2.0", "@img/sharp-libvips-linux-x64": "1.2.0", "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", "@img/sharp-libvips-linuxmusl-x64": "1.2.0", "@img/sharp-linux-arm": "0.34.3", "@img/sharp-linux-arm64": "0.34.3", "@img/sharp-linux-ppc64": "0.34.3", "@img/sharp-linux-s390x": "0.34.3", "@img/sharp-linux-x64": "0.34.3", "@img/sharp-linuxmusl-arm64": "0.34.3", "@img/sharp-linuxmusl-x64": "0.34.3", "@img/sharp-wasm32": "0.34.3", "@img/sharp-win32-arm64": "0.34.3", "@img/sharp-win32-ia32": "0.34.3", "@img/sharp-win32-x64": "0.34.3" } }, "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg=="],
"shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
"shiki": ["shiki@3.8.1", "", { "dependencies": { "@shikijs/core": "3.8.1", "@shikijs/engine-javascript": "3.8.1", "@shikijs/engine-oniguruma": "3.8.1", "@shikijs/langs": "3.8.1", "@shikijs/themes": "3.8.1", "@shikijs/types": "3.8.1", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-+MYIyjwGPCaegbpBeFN9+oOifI8CKiKG3awI/6h3JeT85c//H2wDW/xCJEGuQ5jPqtbboKNqNy+JyX9PYpGwNg=="],
"simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="],
@ -1059,16 +1385,28 @@
"stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="],
"stringify-object": ["stringify-object@5.0.0", "", { "dependencies": { "get-own-enumerable-keys": "^1.0.0", "is-obj": "^3.0.0", "is-regexp": "^3.1.0" } }, "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg=="],
"strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"style-mod": ["style-mod@4.1.2", "", {}, "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="],
"style-to-js": ["style-to-js@1.1.17", "", { "dependencies": { "style-to-object": "1.0.9" } }, "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA=="],
"style-to-object": ["style-to-object@1.0.9", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw=="],
"stylis": ["stylis@4.3.6", "", {}, "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ=="],
"tabbable": ["tabbable@6.2.0", "", {}, "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="],
"tailwind-merge": ["tailwind-merge@2.6.0", "", {}, "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA=="],
"tailwindcss": ["tailwindcss@4.1.12", "", {}, "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA=="],
"tiny-inflate": ["tiny-inflate@1.0.3", "", {}, "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw=="],
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
"tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
"tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
@ -1081,6 +1419,8 @@
"ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="],
"ts-deepmerge": ["ts-deepmerge@7.0.3", "", {}, "sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA=="],
"tsconfck": ["tsconfck@3.1.6", "", { "peerDependencies": { "typescript": "^5.0.0" }, "optionalPeers": ["typescript"], "bin": { "tsconfck": "bin/tsconfck.js" } }, "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
@ -1095,6 +1435,10 @@
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
"unhead": ["unhead@1.11.20", "", { "dependencies": { "@unhead/dom": "1.11.20", "@unhead/schema": "1.11.20", "@unhead/shared": "1.11.20", "hookable": "^5.5.3" } }, "sha512-3AsNQC0pjwlLqEYHLjtichGWankK8yqmocReITecmpB1H0aOabeESueyy+8X1gyJx4ftZVwo9hqQ4O3fPWffCA=="],
"unicode-properties": ["unicode-properties@1.4.1", "", { "dependencies": { "base64-js": "^1.3.0", "unicode-trie": "^2.0.0" } }, "sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg=="],
"unicode-trie": ["unicode-trie@2.0.0", "", { "dependencies": { "pako": "^0.2.5", "tiny-inflate": "^1.0.0" } }, "sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ=="],
@ -1125,6 +1469,8 @@
"unstorage": ["unstorage@1.16.1", "", { "dependencies": { "anymatch": "^3.1.3", "chokidar": "^4.0.3", "destr": "^2.0.5", "h3": "^1.15.3", "lru-cache": "^10.4.3", "node-fetch-native": "^1.6.6", "ofetch": "^1.4.1", "ufo": "^1.6.1" }, "peerDependencies": { "@azure/app-configuration": "^1.8.0", "@azure/cosmos": "^4.2.0", "@azure/data-tables": "^13.3.0", "@azure/identity": "^4.6.0", "@azure/keyvault-secrets": "^4.9.0", "@azure/storage-blob": "^12.26.0", "@capacitor/preferences": "^6.0.3 || ^7.0.0", "@deno/kv": ">=0.9.0", "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", "@planetscale/database": "^1.19.0", "@upstash/redis": "^1.34.3", "@vercel/blob": ">=0.27.1", "@vercel/kv": "^1.0.1", "aws4fetch": "^1.0.20", "db0": ">=0.2.1", "idb-keyval": "^6.2.1", "ioredis": "^5.4.2", "uploadthing": "^7.4.4" }, "optionalPeers": ["@azure/app-configuration", "@azure/cosmos", "@azure/data-tables", "@azure/identity", "@azure/keyvault-secrets", "@azure/storage-blob", "@capacitor/preferences", "@deno/kv", "@netlify/blobs", "@planetscale/database", "@upstash/redis", "@vercel/blob", "@vercel/kv", "aws4fetch", "db0", "idb-keyval", "ioredis", "uploadthing"] }, "sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ=="],
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
"url-template": ["url-template@3.1.1", "", {}, "sha512-4oszoaEKE/mQOtAmdMWqIRHmkxWkUZMnXFnjQ5i01CuRSK3uluxcH1MRVVVWmhlnzT1SCDfKxxficm2G37qzCA=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
@ -1153,10 +1499,24 @@
"vscode-uri": ["vscode-uri@3.0.8", "", {}, "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw=="],
"vue": ["vue@3.5.21", "", { "dependencies": { "@vue/compiler-dom": "3.5.21", "@vue/compiler-sfc": "3.5.21", "@vue/runtime-dom": "3.5.21", "@vue/server-renderer": "3.5.21", "@vue/shared": "3.5.21" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-xxf9rum9KtOdwdRkiApWL+9hZEMWE90FHh8yS1+KJAiWYh+iGWV1FquPjoO9VUHQ+VIhsCXNNyZ5Sf4++RVZBA=="],
"vue-component-type-helpers": ["vue-component-type-helpers@3.0.6", "", {}, "sha512-6CRM8X7EJqWCJOiKPvSLQG+hJPb/Oy2gyJx3pLjUEhY7PuaCthQu3e0zAGI1lqUBobrrk9IT0K8sG2GsCluxoQ=="],
"vue-demi": ["vue-demi@0.14.10", "", { "peerDependencies": { "@vue/composition-api": "^1.0.0-rc.1", "vue": "^3.0.0-0 || ^2.6.0" }, "optionalPeers": ["@vue/composition-api"], "bin": { "vue-demi-fix": "bin/vue-demi-fix.js", "vue-demi-switch": "bin/vue-demi-switch.js" } }, "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg=="],
"vue-router": ["vue-router@4.5.1", "", { "dependencies": { "@vue/devtools-api": "^6.6.4" }, "peerDependencies": { "vue": "^3.2.0" } }, "sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw=="],
"vue-sonner": ["vue-sonner@1.3.2", "", {}, "sha512-UbZ48E9VIya3ToiRHAZUbodKute/z/M1iT8/3fU8zEbwBRE11AKuHikssv18LMk2gTTr6eMQT4qf6JoLHWuj/A=="],
"w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="],
"web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="],
"whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
"which-pm-runs": ["which-pm-runs@1.1.0", "", {}, "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA=="],
@ -1167,6 +1527,10 @@
"xxhash-wasm": ["xxhash-wasm@1.1.0", "", {}, "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="],
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"yaml": ["yaml@2.8.0", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ=="],
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
"yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="],
@ -1175,6 +1539,8 @@
"yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="],
"zhead": ["zhead@2.2.4", "", {}, "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="],
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"zod-to-json-schema": ["zod-to-json-schema@3.24.6", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="],
@ -1185,8 +1551,78 @@
"@antfu/install-pkg/tinyexec": ["tinyexec@1.0.1", "", {}, "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw=="],
"@babel/core/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@babel/core/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@babel/generator/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@babel/generator/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@babel/helper-compilation-targets/lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
"@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@babel/helper-module-imports/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@babel/helpers/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@babel/template/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@babel/template/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@babel/traverse/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@babel/traverse/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@hyperjump/json-schema/uuid": ["uuid@9.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
"@readme/better-ajv-errors/leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
"@rollup/pluginutils/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"@scalar/api-client/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
"@scalar/api-reference/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
"@scalar/icons/@types/node": ["@types/node@22.18.0", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-m5ObIqwsUp6BZzyiy4RdZpzWGub9bqLJMvZDD0QMXhxjqMHMENlj+SqF5QxoUwaQNFe+8kz8XM8ZQhqkQPTgMQ=="],
"@scalar/oas-utils/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
"@scalar/openapi-types/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
"@scalar/types/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
"@scalar/use-hooks/@vueuse/core": ["@vueuse/core@10.11.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "10.11.1", "@vueuse/shared": "10.11.1", "vue-demi": ">=0.14.8" } }, "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww=="],
"@scalar/use-hooks/zod": ["zod@3.24.1", "", {}, "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A=="],
"@types/babel__core/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@types/babel__core/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@types/babel__generator/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@types/babel__template/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@types/babel__template/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@types/babel__traverse/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@vue/compiler-core/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@vue/compiler-core/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"@vue/compiler-core/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.28.3", "", { "dependencies": { "@babel/types": "^7.28.2" }, "bin": "./bin/babel-parser.js" }, "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA=="],
"@vue/compiler-sfc/estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="],
"@vue/compiler-sfc/magic-string": ["magic-string@0.30.18", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ=="],
"ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
@ -1203,12 +1639,34 @@
"hast-util-to-parse5/property-information": ["property-information@6.5.0", "", {}, "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig=="],
"mlly/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"mlly/pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
"pkg-types/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
"postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
"prompts/kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="],
"radix-vue/@vueuse/core": ["@vueuse/core@10.11.1", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "10.11.1", "@vueuse/shared": "10.11.1", "vue-demi": ">=0.14.8" } }, "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww=="],
"radix-vue/@vueuse/shared": ["@vueuse/shared@10.11.1", "", { "dependencies": { "vue-demi": ">=0.14.8" } }, "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA=="],
"recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"@scalar/use-hooks/@vueuse/core/@vueuse/metadata": ["@vueuse/metadata@10.11.1", "", {}, "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw=="],
"@scalar/use-hooks/@vueuse/core/@vueuse/shared": ["@vueuse/shared@10.11.1", "", { "dependencies": { "vue-demi": ">=0.14.8" } }, "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA=="],
"@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.28.2", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.27.1" } }, "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ=="],
"@vue/compiler-sfc/magic-string/@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
@ -1259,6 +1717,8 @@
"mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
"radix-vue/@vueuse/core/@vueuse/metadata": ["@vueuse/metadata@10.11.1", "", {}, "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw=="],
"ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
}
}

View File

@ -7,13 +7,26 @@
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
"astro": "astro",
"prebuild": "bun scripts/fix-local-spec-complete.js && bun scripts/conditional-cloud-spec.js",
"generate:local-spec": "bun scripts/fix-local-spec-complete.js",
"generate:cloud-spec": "bun scripts/generate-cloud-spec.js",
"generate:cloud-spec-force": "FORCE_UPDATE=true bun scripts/generate-cloud-spec.js",
"api:dev": "astro dev --open /api",
"api:local": "astro dev --open /api-reference/local",
"api:cloud": "astro dev --open /api-reference/cloud"
},
"dependencies": {
"@astrojs/react": "^4.3.0",
"@astrojs/starlight": "^0.35.1",
"@lorenzo_lewis/starlight-utils": "^0.3.2",
"@scalar/api-reference-react": "^0.7.42",
"@types/react": "^19.1.12",
"astro": "^5.6.1",
"astro-mermaid": "^1.0.4",
"mermaid": "^11.9.0",
"react": "^19.1.1",
"react-dom": "^19.1.1",
"sharp": "^0.34.3",
"starlight-openapi": "^0.19.1",
"starlight-sidebar-topics": "^0.6.0",

BIN
website/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path fill-rule="evenodd" d="M81 36 64 0 47 36l-1 2-9-10a6 6 0 0 0-9 9l10 10h-2L0 64l36 17h2L28 91a6 6 0 1 0 9 9l9-10 1 2 17 36 17-36v-2l9 10a6 6 0 1 0 9-9l-9-9 2-1 36-17-36-17-2-1 9-9a6 6 0 1 0-9-9l-9 10v-2Zm-17 2-2 5c-4 8-11 15-19 19l-5 2 5 2c8 4 15 11 19 19l2 5 2-5c4-8 11-15 19-19l5-2-5-2c-8-4-15-11-19-19l-2-5Z" clip-rule="evenodd"/><path d="M118 19a6 6 0 0 0-9-9l-3 3a6 6 0 1 0 9 9l3-3Zm-96 4c-2 2-6 2-9 0l-3-3a6 6 0 1 1 9-9l3 3c3 2 3 6 0 9Zm0 82c-2-2-6-2-9 0l-3 3a6 6 0 1 0 9 9l3-3c3-2 3-6 0-9Zm96 4a6 6 0 0 1-9 9l-3-3a6 6 0 1 1 9-9l3 3Z"/><style>path{fill:#000}@media (prefers-color-scheme:dark){path{fill:#fff}}</style></svg>

Before

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,119 @@
// Navigation injection script for Jan documentation
// This script adds navigation links to regular docs pages (not API reference pages)
;(function () {
// Navigation configuration for Jan docs
const JAN_NAV_CONFIG = {
// Product navigation links - easy to extend for multiple products
links: [
{
href: '/',
text: 'Docs',
isActive: (path) =>
path === '/' || (path.startsWith('/') && !path.startsWith('/api')),
},
{
href: '/api',
text: 'API Reference',
isActive: (path) => path.startsWith('/api'),
},
],
// Pages that have their own navigation (don't inject nav)
excludePaths: ['/api-reference/', '/api/'],
}
// Add navigation to docs pages with retry logic
function addNavigation(retries = 0) {
const currentPath = window.location.pathname
// Skip if page has its own navigation
const shouldSkipNav = JAN_NAV_CONFIG.excludePaths.some((path) =>
currentPath.startsWith(path)
)
if (shouldSkipNav) return
const header = document.querySelector('.header')
const siteTitle = document.querySelector('.site-title')
const existingNav = document.querySelector('.custom-nav-links')
if (header && siteTitle && !existingNav) {
// Find the right container for nav links
const searchElement = header.querySelector('[class*="search"]')
const flexContainer = header.querySelector('.sl-flex')
const targetContainer = flexContainer || header
if (targetContainer) {
// Create navigation container
const nav = document.createElement('nav')
nav.className = 'custom-nav-links'
nav.setAttribute('aria-label', 'Product Navigation')
// Create links from configuration
JAN_NAV_CONFIG.links.forEach((link) => {
const a = document.createElement('a')
a.href = link.href
a.textContent = link.text
a.className = 'nav-link'
// Set active state
if (link.isActive(currentPath)) {
a.setAttribute('aria-current', 'page')
}
nav.appendChild(a)
})
// Insert navigation safely
if (searchElement && targetContainer.contains(searchElement)) {
targetContainer.insertBefore(nav, searchElement)
} else {
// Find site title and insert after it
if (siteTitle && targetContainer.contains(siteTitle)) {
siteTitle.insertAdjacentElement('afterend', nav)
} else {
targetContainer.appendChild(nav)
}
}
} else if (retries < 5) {
setTimeout(() => addNavigation(retries + 1), 500)
}
} else if (retries < 5) {
setTimeout(() => addNavigation(retries + 1), 500)
}
}
// Initialize navigation injection
function initNavigation() {
// Update logo link to jan.ai
const logoLink = document.querySelector('a[href="/"]')
if (logoLink && logoLink.getAttribute('href') === '/') {
logoLink.href = 'https://jan.ai'
}
// Start navigation injection
if (document.readyState === 'loading') {
setTimeout(() => addNavigation(), 1000)
} else {
addNavigation()
}
}
// Run when DOM is ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initNavigation)
} else {
initNavigation()
}
// Handle page navigation in SPA-like environments
let lastUrl = location.href
new MutationObserver(() => {
const url = location.href
if (url !== lastUrl) {
lastUrl = url
// Re-run navigation injection after navigation
setTimeout(() => addNavigation(), 100)
}
}).observe(document, { subtree: true, childList: true })
})()

View File

@ -0,0 +1,48 @@
/* Navigation links for regular docs pages */
.custom-nav-links {
display: inline-flex;
align-items: center;
gap: 0.5rem;
margin: 0 1rem;
}
.custom-nav-links .nav-link {
display: inline-flex;
align-items: center;
padding: 0.5rem 0.875rem;
border-radius: 0.375rem;
color: var(--sl-color-gray-2);
text-decoration: none;
font-weight: 500;
font-size: 0.875rem;
transition: all 0.2s ease;
white-space: nowrap;
}
.custom-nav-links .nav-link:hover {
color: var(--sl-color-text);
background: var(--sl-color-gray-6);
}
.custom-nav-links .nav-link[aria-current="page"] {
color: var(--sl-color-text);
background: var(--sl-color-gray-6);
}
/* Responsive design */
@media (max-width: 768px) {
.custom-nav-links {
display: none;
}
}
@media (min-width: 768px) and (max-width: 1024px) {
.custom-nav-links {
margin: 0 0.5rem;
}
.custom-nav-links .nav-link {
padding: 0.375rem 0.625rem;
font-size: 0.8125rem;
}
}

View File

@ -0,0 +1,187 @@
#!/usr/bin/env node
/**
* Conditional Cloud Spec Generator
*
* This script conditionally runs the cloud spec generation based on environment variables.
* It's designed to be used in CI/CD pipelines to control when the spec should be updated.
*
* Environment variables:
* - SKIP_CLOUD_SPEC_UPDATE: Skip cloud spec generation entirely
* - FORCE_UPDATE: Force update even if skip is set
* - CI: Detect if running in CI environment
*/
import { spawn } from 'child_process'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
// Configuration
const CONFIG = {
CLOUD_SPEC_PATH: path.join(__dirname, '../public/openapi/cloud-openapi.json'),
GENERATOR_SCRIPT: path.join(__dirname, 'generate-cloud-spec.js'),
FALLBACK_SPEC_PATH: path.join(__dirname, '../public/openapi/openapi.json'),
}
// Color codes for console output
const colors = {
reset: '\x1b[0m',
green: '\x1b[32m',
yellow: '\x1b[33m',
cyan: '\x1b[36m',
gray: '\x1b[90m',
}
function log(message, type = 'info') {
const prefix = {
info: `${colors.cyan} `,
skip: `${colors.gray}⏭️ `,
run: `${colors.green}▶️ `,
warning: `${colors.yellow}⚠️ `,
}[type] || ''
console.log(`${prefix}${message}${colors.reset}`)
}
async function shouldRunGenerator() {
// Check environment variables
const skipUpdate = process.env.SKIP_CLOUD_SPEC_UPDATE === 'true'
const forceUpdate = process.env.FORCE_UPDATE === 'true'
const isCI = process.env.CI === 'true'
const isPR = process.env.GITHUB_EVENT_NAME === 'pull_request'
// Force update overrides all
if (forceUpdate) {
log('Force update requested', 'info')
return true
}
// Skip if explicitly requested
if (skipUpdate) {
log('Cloud spec update skipped (SKIP_CLOUD_SPEC_UPDATE=true)', 'skip')
return false
}
// Skip in PR builds to avoid unnecessary API calls
if (isPR) {
log('Cloud spec update skipped (Pull Request build)', 'skip')
return false
}
// Check if cloud spec already exists
const specExists = fs.existsSync(CONFIG.CLOUD_SPEC_PATH)
// In CI, only update if spec doesn't exist or if scheduled/manual trigger
if (isCI) {
const isScheduled = process.env.GITHUB_EVENT_NAME === 'schedule'
const isManualWithUpdate =
process.env.GITHUB_EVENT_NAME === 'workflow_dispatch' &&
process.env.UPDATE_CLOUD_SPEC === 'true'
if (isScheduled || isManualWithUpdate) {
log('Cloud spec update triggered (scheduled/manual)', 'info')
return true
}
if (!specExists) {
log('Cloud spec missing, will attempt to generate', 'warning')
return true
}
log('Cloud spec update skipped (CI build, spec exists)', 'skip')
return false
}
// For local development, update if spec is missing or older than 24 hours
if (!specExists) {
log('Cloud spec missing, generating...', 'info')
return true
}
// Check if spec is older than 24 hours
const stats = fs.statSync(CONFIG.CLOUD_SPEC_PATH)
const ageInHours = (Date.now() - stats.mtime.getTime()) / (1000 * 60 * 60)
if (ageInHours > 24) {
log(`Cloud spec is ${Math.round(ageInHours)} hours old, updating...`, 'info')
return true
}
log(`Cloud spec is recent (${Math.round(ageInHours)} hours old), skipping update`, 'skip')
return false
}
async function runGenerator() {
return new Promise((resolve, reject) => {
log('Running cloud spec generator...', 'run')
const child = spawn('bun', [CONFIG.GENERATOR_SCRIPT], {
stdio: 'inherit',
env: { ...process.env }
})
child.on('close', (code) => {
if (code === 0) {
resolve()
} else {
reject(new Error(`Generator exited with code ${code}`))
}
})
child.on('error', (err) => {
reject(err)
})
})
}
async function ensureFallback() {
// If cloud spec doesn't exist but fallback does, copy it
if (!fs.existsSync(CONFIG.CLOUD_SPEC_PATH) && fs.existsSync(CONFIG.FALLBACK_SPEC_PATH)) {
log('Using fallback spec as cloud spec', 'warning')
fs.copyFileSync(CONFIG.FALLBACK_SPEC_PATH, CONFIG.CLOUD_SPEC_PATH)
return true
}
return false
}
async function main() {
try {
// Determine if we should run the generator
const shouldRun = await shouldRunGenerator()
if (shouldRun) {
try {
await runGenerator()
log('Cloud spec generation completed', 'info')
} catch (error) {
log(`Cloud spec generation failed: ${error.message}`, 'warning')
// Try to use fallback
if (ensureFallback()) {
log('Fallback spec used successfully', 'info')
} else {
log('No fallback available, build may fail', 'warning')
// Don't exit with error - let the build continue
}
}
} else {
// Ensure we have at least a fallback spec
if (!fs.existsSync(CONFIG.CLOUD_SPEC_PATH)) {
ensureFallback()
}
}
// Always exit successfully to not break the build
process.exit(0)
} catch (error) {
console.error('Unexpected error:', error)
// Even on error, try to continue the build
process.exit(0)
}
}
// Run the script
main()

View File

@ -0,0 +1,746 @@
#!/usr/bin/env node
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const cloudSpecPath = path.join(
__dirname,
'../public/openapi/cloud-openapi.json'
)
const outputPath = path.join(__dirname, '../public/openapi/openapi.json')
console.log(
'🔧 Fixing Local OpenAPI Spec with Complete Examples and Schemas...'
)
// Read cloud spec as a reference
const cloudSpec = JSON.parse(fs.readFileSync(cloudSpecPath, 'utf8'))
// Convert Swagger 2.0 to OpenAPI 3.0 format for paths
function convertSwaggerPathToOpenAPI3(swaggerPath) {
const openApiPath = {}
Object.keys(swaggerPath || {}).forEach((method) => {
if (typeof swaggerPath[method] === 'object') {
openApiPath[method] = {
...swaggerPath[method],
// Convert parameters
parameters: swaggerPath[method].parameters?.filter(
(p) => p.in !== 'body'
),
// Convert body parameter to requestBody
requestBody: swaggerPath[method].parameters?.find(
(p) => p.in === 'body'
)
? {
required: true,
content: {
'application/json': {
schema: swaggerPath[method].parameters.find(
(p) => p.in === 'body'
).schema,
},
},
}
: undefined,
// Convert responses
responses: {},
}
// Convert responses
Object.keys(swaggerPath[method].responses || {}).forEach((statusCode) => {
const response = swaggerPath[method].responses[statusCode]
openApiPath[method].responses[statusCode] = {
description: response.description,
content: response.schema
? {
'application/json': {
schema: response.schema,
},
}
: undefined,
}
})
}
})
return openApiPath
}
// Create comprehensive local spec
const localSpec = {
openapi: '3.1.0',
info: {
title: 'Jan API',
description:
"OpenAI-compatible API for local inference with Jan. Run AI models locally with complete privacy using llama.cpp's high-performance inference engine. Supports GGUF models with CPU and GPU acceleration. No authentication required for local usage.",
version: '0.3.14',
contact: {
name: 'Jan Support',
url: 'https://jan.ai/support',
email: 'support@jan.ai',
},
license: {
name: 'Apache 2.0',
url: 'https://github.com/janhq/jan/blob/main/LICENSE',
},
},
servers: [
{
url: 'http://127.0.0.1:1337',
description: 'Local Jan Server (Default IP)',
},
{
url: 'http://localhost:1337',
description: 'Local Jan Server (localhost)',
},
{
url: 'http://localhost:8080',
description: 'Local Jan Server (Alternative Port)',
},
],
tags: [
{
name: 'Models',
description: 'List and describe available models',
},
{
name: 'Chat',
description: 'Chat completion endpoints for conversational AI',
},
{
name: 'Completions',
description: 'Text completion endpoints for generating text',
},
{
name: 'Extras',
description:
'Additional utility endpoints for tokenization and text processing',
},
],
paths: {},
components: {
schemas: {},
securitySchemes: {
bearerAuth: {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description:
'Optional: Enter your API key if authentication is enabled. The Bearer prefix will be added automatically.',
},
},
},
}
// Local model examples
const LOCAL_MODELS = [
'gemma-2-2b-it-Q8_0',
'llama-3.1-8b-instruct-Q4_K_M',
'mistral-7b-instruct-v0.3-Q4_K_M',
'phi-3-mini-4k-instruct-Q4_K_M',
]
// Add completions endpoint with rich examples
localSpec.paths['/v1/completions'] = {
post: {
tags: ['Completions'],
summary: 'Create completion',
description:
"Creates a completion for the provided prompt and parameters. This endpoint is compatible with OpenAI's completions API.",
operationId: 'create_completion',
requestBody: {
required: true,
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/CreateCompletionRequest',
},
examples: {
basic: {
summary: 'Basic Completion',
description: 'Simple text completion example',
value: {
model: LOCAL_MODELS[0],
prompt: 'Once upon a time',
max_tokens: 50,
temperature: 0.7,
},
},
creative: {
summary: 'Creative Writing',
description: 'Generate creative content with higher temperature',
value: {
model: LOCAL_MODELS[0],
prompt: 'Write a short poem about coding:',
max_tokens: 150,
temperature: 1.0,
top_p: 0.95,
},
},
code: {
summary: 'Code Generation',
description: 'Generate code with lower temperature for accuracy',
value: {
model: LOCAL_MODELS[0],
prompt:
'# Python function to calculate fibonacci\ndef fibonacci(n):',
max_tokens: 200,
temperature: 0.3,
stop: ['\n\n', 'def ', 'class '],
},
},
streaming: {
summary: 'Streaming Response',
description: 'Stream tokens as they are generated',
value: {
model: LOCAL_MODELS[0],
prompt: 'Explain quantum computing in simple terms:',
max_tokens: 300,
temperature: 0.7,
stream: true,
},
},
},
},
},
},
responses: {
200: {
description: 'Successful Response',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/CreateCompletionResponse',
},
},
},
},
202: {
description: 'Accepted - Request is being processed',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/CreateCompletionResponse',
},
},
'text/event-stream': {
schema: {
type: 'string',
format: 'binary',
description: 'Server-sent events stream for streaming responses',
},
},
},
},
422: {
description: 'Validation Error',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ValidationError',
},
},
},
},
},
},
}
// Add chat completions endpoint with rich examples
localSpec.paths['/v1/chat/completions'] = {
post: {
tags: ['Chat'],
summary: 'Create chat completion',
description:
"Creates a model response for the given chat conversation. This endpoint is compatible with OpenAI's chat completions API.",
operationId: 'create_chat_completion',
requestBody: {
required: true,
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/CreateChatCompletionRequest',
},
examples: {
simple: {
summary: 'Simple Chat',
description: 'Basic question and answer',
value: {
model: LOCAL_MODELS[0],
messages: [
{
role: 'user',
content: 'What is the capital of France?',
},
],
max_tokens: 100,
temperature: 0.7,
},
},
system: {
summary: 'With System Message',
description: 'Chat with system instructions',
value: {
model: LOCAL_MODELS[0],
messages: [
{
role: 'system',
content:
'You are a helpful assistant that speaks like a pirate.',
},
{
role: 'user',
content: 'Tell me about the weather today.',
},
],
max_tokens: 150,
temperature: 0.8,
},
},
conversation: {
summary: 'Multi-turn Conversation',
description: 'Extended conversation with context',
value: {
model: LOCAL_MODELS[0],
messages: [
{
role: 'system',
content: 'You are a knowledgeable AI assistant.',
},
{
role: 'user',
content: 'What is machine learning?',
},
{
role: 'assistant',
content:
'Machine learning is a subset of artificial intelligence that enables systems to learn and improve from experience without being explicitly programmed.',
},
{
role: 'user',
content: 'Can you give me a simple example?',
},
],
max_tokens: 200,
temperature: 0.7,
},
},
streaming: {
summary: 'Streaming Chat',
description: 'Stream the response token by token',
value: {
model: LOCAL_MODELS[0],
messages: [
{
role: 'user',
content: 'Write a haiku about programming',
},
],
stream: true,
temperature: 0.9,
},
},
json_mode: {
summary: 'JSON Response',
description: 'Request structured JSON output',
value: {
model: LOCAL_MODELS[0],
messages: [
{
role: 'user',
content:
'List 3 programming languages with their main use cases in JSON format',
},
],
max_tokens: 200,
temperature: 0.5,
response_format: {
type: 'json_object',
},
},
},
},
},
},
},
responses: {
200: {
description: 'Successful Response',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/CreateChatCompletionResponse',
},
},
'text/event-stream': {
schema: {
type: 'string',
format: 'binary',
description: 'Server-sent events stream for streaming responses',
},
},
},
},
202: {
description: 'Accepted - Request is being processed',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/CreateChatCompletionResponse',
},
},
'text/event-stream': {
schema: {
type: 'string',
format: 'binary',
description: 'Server-sent events stream for streaming responses',
},
},
},
},
422: {
description: 'Validation Error',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ValidationError',
},
},
},
},
},
},
}
// Add models endpoint
localSpec.paths['/v1/models'] = {
get: {
tags: ['Models'],
summary: 'List available models',
description:
'Lists the currently available models and provides basic information about each one such as the owner and availability.',
operationId: 'list_models',
responses: {
200: {
description: 'Successful Response',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/ModelList',
},
example: {
object: 'list',
data: LOCAL_MODELS.map((id) => ({
id: id,
object: 'model',
created: 1686935002,
owned_by: 'jan',
})),
},
},
},
},
},
},
}
// Add tokenization endpoints
localSpec.paths['/extras/tokenize'] = {
post: {
tags: ['Extras'],
summary: 'Tokenize text',
description: "Convert text input into tokens using the model's tokenizer.",
operationId: 'tokenize',
requestBody: {
required: true,
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/TokenizeRequest',
},
example: {
input: 'Hello, world!',
model: LOCAL_MODELS[0],
},
},
},
},
responses: {
200: {
description: 'Successful Response',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/TokenizeResponse',
},
example: {
tokens: [15339, 11, 1917, 0],
},
},
},
},
},
},
}
localSpec.paths['/extras/tokenize/count'] = {
post: {
tags: ['Extras'],
summary: 'Count tokens',
description: 'Count the number of tokens in the provided text.',
operationId: 'count_tokens',
requestBody: {
required: true,
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/TokenizeRequest',
},
example: {
input: 'How many tokens does this text have?',
model: LOCAL_MODELS[0],
},
},
},
},
responses: {
200: {
description: 'Successful Response',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/TokenCountResponse',
},
example: {
count: 8,
},
},
},
},
},
},
}
// Copy ALL necessary schemas from cloud spec
const schemasToInclude = [
// Request/Response schemas
'CreateChatCompletionRequest',
'CreateChatCompletionResponse',
'CreateCompletionRequest',
'CreateCompletionResponse',
'ChatCompletionRequestMessage',
'ChatCompletionRequestSystemMessage',
'ChatCompletionRequestUserMessage',
'ChatCompletionRequestAssistantMessage',
'ChatCompletionResponseMessage',
'ChatCompletionResponseChoice',
'CompletionChoice',
'CompletionUsage',
'ModelList',
'ModelData',
'ValidationError',
// Additional message types
'ChatCompletionRequestFunctionMessage',
'ChatCompletionRequestToolMessage',
'ChatCompletionRequestMessageContentPart',
'ChatCompletionRequestMessageContentPartText',
'ChatCompletionRequestMessageContentPartImage',
// Function calling
'ChatCompletionFunction',
'ChatCompletionFunctionCall',
'ChatCompletionTool',
'ChatCompletionToolCall',
'ChatCompletionNamedToolChoice',
// Response format
'ChatCompletionRequestResponseFormat',
// Logprobs
'ChatCompletionLogprobs',
'ChatCompletionLogprobToken',
'ChatCompletionTopLogprobToken',
]
// Copy schemas from cloud spec (handle both definitions and schemas)
if (cloudSpec.definitions || cloudSpec.components?.schemas) {
const sourceSchemas =
cloudSpec.definitions || cloudSpec.components?.schemas || {}
schemasToInclude.forEach((schemaName) => {
if (sourceSchemas[schemaName]) {
localSpec.components.schemas[schemaName] = JSON.parse(
JSON.stringify(sourceSchemas[schemaName])
)
}
})
// Also copy any schemas that are referenced by the included schemas
const processedSchemas = new Set(schemasToInclude)
const schemasToProcess = [...schemasToInclude]
while (schemasToProcess.length > 0) {
const currentSchema = schemasToProcess.pop()
const schema = localSpec.components.schemas[currentSchema]
if (!schema) continue
// Find all $ref references
const schemaString = JSON.stringify(schema)
const refPattern = /#\/(?:definitions|components\/schemas)\/([^"]+)/g
let match
while ((match = refPattern.exec(schemaString)) !== null) {
const referencedSchema = match[1]
if (
!processedSchemas.has(referencedSchema) &&
sourceSchemas[referencedSchema]
) {
localSpec.components.schemas[referencedSchema] = JSON.parse(
JSON.stringify(sourceSchemas[referencedSchema])
)
processedSchemas.add(referencedSchema)
schemasToProcess.push(referencedSchema)
}
}
}
}
// Add tokenization schemas manually
localSpec.components.schemas.TokenizeRequest = {
type: 'object',
properties: {
input: {
type: 'string',
description: 'The text to tokenize',
},
model: {
type: 'string',
description: 'The model to use for tokenization',
enum: LOCAL_MODELS,
},
},
required: ['input'],
}
localSpec.components.schemas.TokenizeResponse = {
type: 'object',
properties: {
tokens: {
type: 'array',
items: {
type: 'integer',
},
description: 'Array of token IDs',
},
},
required: ['tokens'],
}
localSpec.components.schemas.TokenCountResponse = {
type: 'object',
properties: {
count: {
type: 'integer',
description: 'Number of tokens',
},
},
required: ['count'],
}
// Update model references in schemas to use local models
if (
localSpec.components.schemas.CreateChatCompletionRequest?.properties?.model
) {
localSpec.components.schemas.CreateChatCompletionRequest.properties.model = {
...localSpec.components.schemas.CreateChatCompletionRequest.properties
.model,
enum: LOCAL_MODELS,
example: LOCAL_MODELS[0],
description: `ID of the model to use. Available models: ${LOCAL_MODELS.join(', ')}`,
}
}
if (localSpec.components.schemas.CreateCompletionRequest?.properties?.model) {
localSpec.components.schemas.CreateCompletionRequest.properties.model = {
...localSpec.components.schemas.CreateCompletionRequest.properties.model,
enum: LOCAL_MODELS,
example: LOCAL_MODELS[0],
description: `ID of the model to use. Available models: ${LOCAL_MODELS.join(', ')}`,
}
}
// Fix all $ref references to use components/schemas instead of definitions
function fixReferences(obj) {
if (typeof obj === 'string') {
return obj.replace(/#\/definitions\//g, '#/components/schemas/')
}
if (Array.isArray(obj)) {
return obj.map(fixReferences)
}
if (obj && typeof obj === 'object') {
const fixed = {}
for (const key in obj) {
fixed[key] = fixReferences(obj[key])
}
return fixed
}
return obj
}
// Apply reference fixes
localSpec.paths = fixReferences(localSpec.paths)
localSpec.components.schemas = fixReferences(localSpec.components.schemas)
// Add x-jan-local-features
localSpec['x-jan-local-features'] = {
engine: 'llama.cpp',
features: [
'GGUF model support',
'CPU and GPU acceleration',
'Quantized model support (Q4, Q5, Q8)',
'Metal acceleration on macOS',
'CUDA support on NVIDIA GPUs',
'ROCm support on AMD GPUs',
'AVX/AVX2/AVX512 optimizations',
'Memory-mapped model loading',
],
privacy: {
local_processing: true,
no_telemetry: true,
offline_capable: true,
},
model_formats: ['GGUF', 'GGML'],
default_settings: {
context_length: 4096,
batch_size: 512,
threads: 'auto',
},
}
// Write the fixed spec
fs.writeFileSync(outputPath, JSON.stringify(localSpec, null, 2), 'utf8')
console.log('✅ Local OpenAPI spec fixed successfully!')
console.log(`📁 Output: ${outputPath}`)
console.log(`📊 Endpoints: ${Object.keys(localSpec.paths).length}`)
console.log(`📊 Schemas: ${Object.keys(localSpec.components.schemas).length}`)
console.log(
`🎯 Examples: ${Object.keys(localSpec.paths).reduce((count, path) => {
return (
count +
Object.keys(localSpec.paths[path]).reduce((c, method) => {
const examples =
localSpec.paths[path][method]?.requestBody?.content?.[
'application/json'
]?.examples
return c + (examples ? Object.keys(examples).length : 0)
}, 0)
)
}, 0)}`
)

View File

@ -0,0 +1,421 @@
#!/usr/bin/env node
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
// Get current directory in ES modules
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
const CONFIG = {
// Jan Server API spec URL - change this for different environments
JAN_SERVER_SPEC_URL:
process.env.JAN_SERVER_SPEC_URL ||
'https://api.jan.ai/api/swagger/doc.json',
// Server URLs for different environments
SERVERS: {
production: {
url: process.env.JAN_SERVER_PROD_URL || 'https://api.jan.ai/v1',
description: 'Jan Server API (Production)',
},
staging: {
url:
process.env.JAN_SERVER_STAGING_URL || 'https://staging-api.jan.ai/v1',
description: 'Jan Server API (Staging)',
},
local: {
url: process.env.JAN_SERVER_LOCAL_URL || 'http://localhost:8000/v1',
description: 'Jan Server (Local Development)',
},
minikube: {
url:
process.env.JAN_SERVER_MINIKUBE_URL ||
'http://jan-server.local:8000/v1',
description: 'Jan Server (Minikube)',
},
},
// Output file path
OUTPUT_PATH: path.join(__dirname, '../public/openapi/cloud-openapi.json'),
// Fallback to local spec if fetch fails
FALLBACK_SPEC_PATH: path.join(__dirname, '../public/openapi/openapi.json'),
// Request timeout in milliseconds
FETCH_TIMEOUT: 10000,
}
// Model examples for Jan Server (vLLM deployment)
const MODEL_EXAMPLES = [
'llama-3.1-8b-instruct',
'mistral-7b-instruct-v0.3',
'gemma-2-9b-it',
'qwen2.5-7b-instruct',
]
// =============================================================================
// UTILITY FUNCTIONS
// =============================================================================
const colors = {
reset: '\x1b[0m',
green: '\x1b[32m',
yellow: '\x1b[33m',
red: '\x1b[31m',
cyan: '\x1b[36m',
bright: '\x1b[1m',
}
function log(message, type = 'info') {
const prefix =
{
success: `${colors.green}`,
warning: `${colors.yellow}⚠️ `,
error: `${colors.red}`,
info: `${colors.cyan} `,
}[type] || ''
console.log(`${prefix} ${message}${colors.reset}`)
}
async function fetchWithTimeout(url, options = {}) {
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), CONFIG.FETCH_TIMEOUT)
try {
const response = await fetch(url, {
...options,
signal: controller.signal,
})
clearTimeout(timeoutId)
return response
} catch (error) {
clearTimeout(timeoutId)
throw error
}
}
// =============================================================================
// SPEC ENHANCEMENT FUNCTIONS
// =============================================================================
function enhanceSpecWithBranding(spec) {
// Update info section with Jan Server branding
spec.info = {
...spec.info,
'title': '👋Jan Server API',
'description':
'OpenAI-compatible API for Jan Server powered by vLLM. High-performance, scalable inference service with automatic batching and optimized memory management.',
'version': spec.info?.version || '1.0.0',
'x-logo': {
url: 'https://jan.ai/logo.png',
altText: '👋Jan Server API',
},
'contact': {
name: 'Jan Server Support',
url: 'https://jan.ai/support',
email: 'support@jan.ai',
},
'license': {
name: 'Apache 2.0',
url: 'https://github.com/menloresearch/jan/blob/main/LICENSE',
},
}
// Update servers with our configured endpoints
spec.servers = Object.values(CONFIG.SERVERS)
// Add global security requirement
spec.security = [{ bearerAuth: [] }]
// Add tags for better organization
spec.tags = [
{ name: 'Models', description: 'List and describe available models' },
{
name: 'Chat',
description: 'Chat completion endpoints for conversational AI',
},
{ name: 'Completions', description: 'Text completion endpoints' },
{ name: 'Embeddings', description: 'Generate embeddings for text' },
{ name: 'Usage', description: 'Monitor API usage and quotas' },
]
return spec
}
function enhanceSecuritySchemes(spec) {
if (!spec.components) spec.components = {}
if (!spec.components.securitySchemes) spec.components.securitySchemes = {}
spec.components.securitySchemes.bearerAuth = {
type: 'http',
scheme: 'bearer',
bearerFormat: 'JWT',
description:
'Enter your Jan Server API key. Configure authentication in your server settings.',
}
return spec
}
function addModelExamples(spec) {
const primaryModel = MODEL_EXAMPLES[0]
// Helper function to update model fields in schemas
function updateModelField(modelField) {
if (!modelField) return
modelField.example = primaryModel
modelField.description = `ID of the model to use. Available models: ${MODEL_EXAMPLES.join(', ')}`
if (modelField.anyOf && modelField.anyOf[0]?.type === 'string') {
modelField.anyOf[0].example = primaryModel
modelField.anyOf[0].enum = MODEL_EXAMPLES
} else if (modelField.type === 'string') {
modelField.enum = MODEL_EXAMPLES
}
}
// Update model fields in common request schemas
const schemas = spec.components?.schemas || {}
if (schemas.CreateCompletionRequest?.properties?.model) {
updateModelField(schemas.CreateCompletionRequest.properties.model)
}
if (schemas.CreateChatCompletionRequest?.properties?.model) {
updateModelField(schemas.CreateChatCompletionRequest.properties.model)
}
if (schemas.CreateEmbeddingRequest?.properties?.model) {
updateModelField(schemas.CreateEmbeddingRequest.properties.model)
}
return spec
}
function addRequestExamples(spec) {
const primaryModel = MODEL_EXAMPLES[0]
// Example request bodies
const examples = {
completion: {
'text-completion': {
summary: 'Text Completion Example',
description: `Complete text using ${primaryModel}`,
value: {
model: primaryModel,
prompt: 'Once upon a time,',
max_tokens: 50,
temperature: 0.7,
top_p: 0.9,
stream: false,
},
},
},
chatCompletion: {
'simple-chat': {
summary: 'Simple Chat Example',
description: `Chat completion using ${primaryModel}`,
value: {
model: primaryModel,
messages: [
{ role: 'user', content: 'What is the capital of France?' },
],
max_tokens: 100,
temperature: 0.7,
stream: false,
},
},
},
embedding: {
'text-embedding': {
summary: 'Text Embedding Example',
description: `Generate embeddings using ${primaryModel}`,
value: {
model: primaryModel,
input: 'The quick brown fox jumps over the lazy dog',
},
},
},
}
// Add examples to path operations
Object.keys(spec.paths || {}).forEach((path) => {
Object.keys(spec.paths[path] || {}).forEach((method) => {
const operation = spec.paths[path][method]
if (!operation.requestBody?.content?.['application/json']) return
if (path.includes('/completions') && !path.includes('/chat')) {
operation.requestBody.content['application/json'].examples =
examples.completion
} else if (path.includes('/chat/completions')) {
operation.requestBody.content['application/json'].examples =
examples.chatCompletion
} else if (path.includes('/embeddings')) {
operation.requestBody.content['application/json'].examples =
examples.embedding
}
})
})
return spec
}
function addCloudFeatures(spec) {
// Add cloud-specific extension
spec['x-jan-server-features'] = {
vllm: {
version: '0.5.0',
features: [
'PagedAttention for efficient memory management',
'Continuous batching for high throughput',
'Tensor parallelism for multi-GPU serving',
'Quantization support (AWQ, GPTQ, SqueezeLLM)',
'Speculative decoding',
'LoRA adapter support',
],
},
scaling: {
auto_scaling: true,
min_replicas: 1,
max_replicas: 100,
target_qps: 100,
},
limits: {
max_tokens_per_request: 32768,
max_batch_size: 256,
timeout_seconds: 300,
},
}
return spec
}
// =============================================================================
// MAIN FUNCTIONS
// =============================================================================
async function fetchJanServerSpec() {
log(`Fetching Jan Server spec from: ${CONFIG.JAN_SERVER_SPEC_URL}`)
try {
const response = await fetchWithTimeout(CONFIG.JAN_SERVER_SPEC_URL)
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
}
const spec = await response.json()
log('Successfully fetched Jan Server specification', 'success')
return spec
} catch (error) {
log(`Failed to fetch Jan Server spec: ${error.message}`, 'warning')
// If FORCE_UPDATE is set, don't use fallback - fail instead
if (process.env.FORCE_UPDATE === 'true') {
log('Force update requested - not using fallback', 'error')
throw error
}
log(`Falling back to local spec: ${CONFIG.FALLBACK_SPEC_PATH}`, 'warning')
if (fs.existsSync(CONFIG.FALLBACK_SPEC_PATH)) {
const fallbackSpec = JSON.parse(
fs.readFileSync(CONFIG.FALLBACK_SPEC_PATH, 'utf8')
)
log('Using local fallback specification', 'warning')
return fallbackSpec
} else {
throw new Error('No fallback spec available')
}
}
}
async function generateCloudSpec() {
console.log(
`${colors.bright}${colors.cyan}🚀 Jan Server API Spec Generator${colors.reset}`
)
console.log(
`${colors.cyan}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${colors.reset}`
)
console.log(`📡 Source: ${CONFIG.JAN_SERVER_SPEC_URL}`)
console.log(`📁 Output: ${CONFIG.OUTPUT_PATH}`)
console.log(`🏗️ Servers: ${Object.keys(CONFIG.SERVERS).join(', ')}`)
console.log('')
try {
// Fetch the real Jan Server specification
let spec = await fetchJanServerSpec()
// Apply all enhancements
spec = enhanceSpecWithBranding(spec)
spec = enhanceSecuritySchemes(spec)
spec = addModelExamples(spec)
spec = addRequestExamples(spec)
spec = addCloudFeatures(spec)
// Ensure all paths have security requirements
Object.keys(spec.paths || {}).forEach((path) => {
Object.keys(spec.paths[path] || {}).forEach((method) => {
const operation = spec.paths[path][method]
if (!operation.security) {
operation.security = [{ bearerAuth: [] }]
}
})
})
// Write the enhanced specification
fs.writeFileSync(CONFIG.OUTPUT_PATH, JSON.stringify(spec, null, 2), 'utf8')
log('Jan Server specification generated successfully!', 'success')
console.log(`📁 Output: ${CONFIG.OUTPUT_PATH}`)
console.log('\n📊 Summary:')
console.log(` - Endpoints: ${Object.keys(spec.paths || {}).length}`)
console.log(` - Servers: ${spec.servers?.length || 0}`)
console.log(` - Models: ${MODEL_EXAMPLES.length}`)
console.log(` - Security: Bearer token authentication`)
console.log(
` - Engine: vLLM (${spec['x-jan-server-features']?.vllm?.version || 'unknown'})`
)
return true
} catch (error) {
log(
`Failed to generate Jan Server specification: ${error.message}`,
'error'
)
console.log('\n🔧 Troubleshooting:')
console.log(' 1. Check your internet connection')
console.log(
` 2. Verify Jan Server is accessible at: ${CONFIG.JAN_SERVER_SPEC_URL}`
)
console.log(' 3. Check if you need to set environment variables:')
console.log(' - JAN_SERVER_SPEC_URL')
console.log(' - JAN_SERVER_PROD_URL')
console.log(' - JAN_SERVER_LOCAL_URL')
return false
}
}
// =============================================================================
// EXECUTION
// =============================================================================
// Show configuration on startup
if (process.env.NODE_ENV !== 'test') {
console.log(`${colors.cyan}🔧 Configuration:${colors.reset}`)
console.log(` Spec URL: ${CONFIG.JAN_SERVER_SPEC_URL}`)
console.log(` Timeout: ${CONFIG.FETCH_TIMEOUT}ms`)
console.log(` Servers: ${Object.keys(CONFIG.SERVERS).length} configured`)
if (process.env.FORCE_UPDATE === 'true') {
console.log(` ${colors.yellow}Force Update: ENABLED${colors.reset}`)
}
console.log('')
}
// Run the generator
const success = await generateCloudSpec()
process.exit(success ? 0 : 1)

View File

@ -0,0 +1,396 @@
---
interface Props {
title: string;
description: string;
}
const { title, description } = Astro.props;
---
<!DOCTYPE html>
<html lang="en" dir="ltr" data-theme="dark">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>{title} | 👋 Jan</title>
<meta name="description" content={description} />
<meta name="generator" content="Astro + Starlight" />
<link rel="shortcut icon" href="/jan2.png" type="image/png" />
<!-- Starlight theme variables -->
<script>
window.StarlightThemeProvider = (() => {
const storedTheme =
typeof localStorage !== 'undefined' && localStorage.getItem('starlight-theme');
const theme =
storedTheme ||
(window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark');
document.documentElement.dataset.theme = theme === 'light' ? 'light' : 'dark';
return {
updatePickers(theme = storedTheme || 'auto') {
document.querySelectorAll('starlight-theme-select').forEach((picker) => {
const select = picker.querySelector('select');
if (select) select.value = theme;
const tmpl = document.querySelector(`#theme-icons`);
const newIcon = tmpl && tmpl.content.querySelector('.' + theme);
if (newIcon) {
const oldIcon = picker.querySelector('svg.label-icon');
if (oldIcon) {
oldIcon.replaceChildren(...newIcon.cloneNode(true).childNodes);
}
}
});
},
};
})();
</script>
<!-- Theme icons template -->
<template id="theme-icons">
<svg aria-hidden="true" class="light" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M5 12a1 1 0 0 0-1-1H3a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Zm.64 5-.71.71a1 1 0 0 0 0 1.41 1 1 0 0 0 1.41 0l.71-.71A1 1 0 0 0 5.64 17ZM12 5a1 1 0 0 0 1-1V3a1 1 0 0 0-2 0v1a1 1 0 0 0 1 1Zm5.66 2.34a1 1 0 0 0 .7-.29l.71-.71a1 1 0 1 0-1.41-1.41l-.66.71a1 1 0 0 0 0 1.41 1 1 0 0 0 .66.29Zm-12-.29a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.71-.71a1.004 1.004 0 1 0-1.43 1.41l.73.71ZM21 11h-1a1 1 0 0 0 0 2h1a1 1 0 0 0 0-2Zm-2.64 6A1 1 0 0 0 17 18.36l.71.71a1 1 0 0 0 1.41 0 1 1 0 0 0 0-1.41l-.76-.66ZM12 6.5a5.5 5.5 0 1 0 5.5 5.5A5.51 5.51 0 0 0 12 6.5Zm0 9a3.5 3.5 0 1 1 0-7 3.5 3.5 0 0 1 0 7Zm0 3.5a1 1 0 0 0-1 1v1a1 1 0 0 0 2 0v-1a1 1 0 0 0-1-1Z"/>
</svg>
<svg aria-hidden="true" class="dark" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M21.64 13a1 1 0 0 0-1.05-.14 8.049 8.049 0 0 1-3.37.73 8.15 8.15 0 0 1-8.14-8.1 8.59 8.59 0 0 1 .25-2A1 1 0 0 0 8 2.36a10.14 10.14 0 1 0 14 11.69 1 1 0 0 0-.36-1.05Zm-9.5 6.69A8.14 8.14 0 0 1 7.08 5.22v.27a10.15 10.15 0 0 0 10.14 10.14 9.784 9.784 0 0 0 2.1-.22 8.11 8.11 0 0 1-7.18 4.32v-.04Z"/>
</svg>
<svg aria-hidden="true" class="auto" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/>
</svg>
</template>
<style>
:root {
/* Import Starlight CSS custom properties */
--sl-font-system: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
--sl-color-bg: #18181b;
--sl-color-bg-nav: #27272a;
--sl-color-white: #ffffff;
--sl-color-text: #e4e4e7;
--sl-color-text-accent: #a855f7;
--sl-color-hairline: #3f3f46;
--sl-color-gray-1: #ffffff;
--sl-color-gray-2: #e4e4e7;
--sl-color-gray-3: #d4d4d8;
--sl-color-gray-4: #a1a1aa;
--sl-color-gray-5: #71717a;
--sl-color-gray-6: #52525b;
--sl-text-base: 1rem;
--sl-text-lg: 1.125rem;
--sl-line-height: 1.8;
--sl-outline-offset-inside: -0.125rem;
/* Enhanced Scalar-specific variables for dark mode */
--scalar-color-1: #ffffff;
--scalar-color-2: #e4e4e7;
--scalar-color-3: #a1a1aa;
--scalar-background-1: #18181b;
--scalar-background-2: #27272a;
--scalar-background-3: #3f3f46;
--scalar-border-color: #3f3f46;
--scalar-color-accent: #22c55e;
}
[data-theme="light"] {
--sl-color-bg: #ffffff;
--sl-color-bg-nav: #f8fafc;
--sl-color-white: #ffffff;
--sl-color-text: #1e293b;
--sl-color-text-accent: #7c3aed;
--sl-color-hairline: #e2e8f0;
--sl-color-gray-1: #0f172a;
--sl-color-gray-2: #334155;
--sl-color-gray-3: #475569;
--sl-color-gray-4: #64748b;
--sl-color-gray-5: #94a3b8;
--sl-color-gray-6: #cbd5e1;
/* Enhanced Scalar-specific variables for light mode */
--scalar-color-1: #0f172a;
--scalar-color-2: #334155;
--scalar-color-3: #64748b;
--scalar-background-1: #ffffff;
--scalar-background-2: #f8fafc;
--scalar-background-3: #f1f5f9;
--scalar-border-color: #e2e8f0;
--scalar-color-accent: #16a34a;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: var(--sl-font-system);
background: var(--sl-color-bg);
color: var(--sl-color-text);
line-height: var(--sl-line-height);
}
.api-layout {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.api-header {
position: sticky;
top: 0;
z-index: 1000;
background: var(--sl-color-bg-nav);
border-bottom: 1px solid var(--sl-color-hairline);
padding: 0 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
min-height: 4rem;
}
.site-title {
display: flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
color: var(--sl-color-text);
font-size: var(--sl-text-lg);
font-weight: 600;
}
.site-title:hover {
color: var(--sl-color-text-accent);
}
.header-actions {
display: flex;
align-items: center;
gap: 0.5rem;
margin-left: auto;
}
.theme-toggle {
background: none;
border: none;
color: var(--sl-color-text);
cursor: pointer;
padding: 0.5rem;
border-radius: 0.25rem;
display: flex;
align-items: center;
gap: 0.25rem;
}
.theme-toggle:hover {
background: var(--sl-color-hairline);
color: var(--sl-color-white);
}
.social-links {
display: flex;
gap: 0.5rem;
}
.social-link {
color: var(--sl-color-text);
padding: 0.5rem;
border-radius: 0.25rem;
text-decoration: none;
display: flex;
align-items: center;
}
.social-link:hover {
background: var(--sl-color-hairline);
color: var(--sl-color-white);
}
.api-content {
flex: 1;
width: 100%;
padding-top: 0;
margin-top: 0;
}
/* Match main nav link styles */
.custom-nav-links {
display: flex;
align-items: center;
gap: 0.5rem;
margin-left: 2rem;
margin-right: auto;
}
.nav-link {
display: inline-flex;
align-items: center;
gap: 0.375rem;
padding: 0.5rem 0.75rem;
border-radius: 0.375rem;
text-decoration: none;
color: var(--sl-color-gray-2);
font-weight: 500;
font-size: 0.9rem;
line-height: 1;
white-space: nowrap;
transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.nav-link:hover {
color: var(--sl-color-text);
background: var(--sl-color-hairline);
}
.nav-link[aria-current='page'] {
color: var(--sl-color-text);
background: var(--sl-color-gray-6);
}
@media (max-width: 1024px) {
.custom-nav-links {
margin-left: 1rem;
}
}
/* Hide scrollbars but maintain functionality */
.api-content {
scrollbar-width: thin;
scrollbar-color: var(--sl-color-hairline) transparent;
}
.api-content::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.api-content::-webkit-scrollbar-track {
background: transparent;
}
.api-content::-webkit-scrollbar-thumb {
background-color: var(--sl-color-hairline);
border-radius: 3px;
}
@media (max-width: 768px) {
.api-header {
padding: 0 0.5rem;
min-height: 3.5rem;
}
.social-links {
display: none;
}
}
</style>
</head>
<body>
<div class="api-layout">
<header class="api-header">
<a href="/" class="site-title">
👋 Jan
</a>
<nav class="custom-nav-links" aria-label="Primary">
<a href="/" class="nav-link">Docs</a>
<a href="/api" class="nav-link">API Reference</a>
</nav>
<div class="header-actions">
<div class="social-links">
<a href="https://github.com/janhq/jan" class="social-link" aria-label="GitHub">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.477 2 2 6.477 2 12c0 4.418 2.865 8.166 6.839 9.489.5.092.682-.217.682-.482 0-.237-.008-.866-.013-1.7-2.782.604-3.369-1.34-3.369-1.34-.454-1.156-1.11-1.464-1.11-1.464-.908-.62.069-.608.069-.608 1.003.07 1.531 1.03 1.531 1.03.892 1.529 2.341 1.087 2.91.831.092-.646.35-1.086.636-1.336-2.22-.253-4.555-1.11-4.555-4.943 0-1.091.39-1.984 1.029-2.683-.103-.253-.446-1.27.098-2.647 0 0 .84-.269 2.75 1.025A9.564 9.564 0 0 1 12 6.844c.85.004 1.705.115 2.504.337 1.909-1.294 2.747-1.025 2.747-1.025.546 1.377.203 2.394.1 2.647.64.699 1.028 1.592 1.028 2.683 0 3.842-2.339 4.687-4.566 4.935.359.309.678.919.678 1.852 0 1.336-.012 2.415-.012 2.743 0 .267.18.578.688.48C19.138 20.161 22 16.416 22 12c0-5.523-4.477-10-10-10Z"/>
</svg>
</a>
<a href="https://discord.com/invite/FTk2MvZwJH" class="social-link" aria-label="Discord">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z"/>
</svg>
</a>
<a href="https://twitter.com/jandotai" class="social-link" aria-label="Twitter">
<svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M18.901 1.153h3.68l-8.04 9.19L24 22.846h-7.406l-5.8-7.584-6.638 7.584H.474l8.6-9.83L0 1.154h7.594l5.243 6.932ZM17.61 20.644h2.039L6.486 3.24H4.298Z"/>
</svg>
</a>
</div>
<starlight-theme-select>
<label>
<select value="auto">
<option value="dark">Dark</option>
<option value="light">Light</option>
<option value="auto">Auto</option>
</select>
<svg aria-hidden="true" class="label-icon" width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
<path d="M21 14h-1V7a3 3 0 0 0-3-3H7a3 3 0 0 0-3 3v7H3a1 1 0 0 0-1 1v2a3 3 0 0 0 3 3h14a3 3 0 0 0 3-3v-2a1 1 0 0 0-1-1ZM6 7a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v7H6V7Zm14 10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-1h16v1Z"/>
</svg>
</label>
</starlight-theme-select>
</div>
</header>
<main class="api-content" id="_top" style="margin-top: 0;">
<slot />
</main>
</div>
<script>
// Theme toggle functionality
customElements.define('starlight-theme-select', class StarlightThemeSelect extends HTMLElement {
constructor() {
super();
this.select = this.querySelector('select');
this.select.addEventListener('change', (e) => {
const theme = e.target.value;
if (typeof localStorage !== 'undefined') {
localStorage.setItem('starlight-theme', theme);
}
document.documentElement.dataset.theme =
theme === 'auto'
? window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'
: theme;
});
}
});
// Initialize theme
if (typeof localStorage !== 'undefined') {
const storedTheme = localStorage.getItem('starlight-theme') || 'auto';
const themeSelect = document.querySelector('starlight-theme-select select');
if (themeSelect) themeSelect.value = storedTheme;
}
// Active state for custom nav
const setActiveNav = () => {
const path = window.location.pathname || '/';
const docs = document.querySelector('.custom-nav-links a[href="/"]');
const api = document.querySelector('.custom-nav-links a[href="/api"]');
if (docs) {
if (path === '/') docs.setAttribute('aria-current', 'page');
else docs.removeAttribute('aria-current');
}
if (api) {
if (path.startsWith('/api')) api.setAttribute('aria-current', 'page');
else api.removeAttribute('aria-current');
}
};
document.addEventListener('astro:page-load', setActiveNav);
document.addEventListener('DOMContentLoaded', setActiveNav);
// Update theme on system preference change
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => {
const storedTheme = typeof localStorage !== 'undefined' ? localStorage.getItem('starlight-theme') : 'auto';
if (storedTheme === 'auto') {
document.documentElement.dataset.theme = e.matches ? 'light' : 'dark';
}
});
// Logo link update
document.addEventListener('DOMContentLoaded', function() {
const logoLink = document.querySelector('.site-title');
if (logoLink && logoLink.getAttribute('href') === '/') {
logoLink.href = 'https://jan.ai';
}
});
</script>
</body>
</html>

View File

@ -0,0 +1,214 @@
import { ApiReferenceReact } from '@scalar/api-reference-react'
import '@scalar/api-reference-react/style.css'
import { useEffect, useState } from 'react'
const ScalarApiReferenceMulti = ({
specUrl,
title,
description,
deployment = 'local',
}) => {
const [isDarkMode, setIsDarkMode] = useState(true)
const [serverUrl, setServerUrl] = useState('')
useEffect(() => {
// Theme detection for Starlight
const getCurrentTheme = () => {
const htmlElement = document.documentElement
const theme = htmlElement.getAttribute('data-theme')
const isDark =
theme === 'dark' ||
(theme !== 'light' &&
window.matchMedia('(prefers-color-scheme: dark)').matches)
setIsDarkMode(isDark)
}
// Set initial theme
getCurrentTheme()
// Watch for theme changes
const observer = new MutationObserver(() => {
getCurrentTheme()
})
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme', 'class'],
})
// Watch for system theme changes
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)')
const handleSystemThemeChange = () => {
getCurrentTheme()
}
mediaQuery.addEventListener('change', handleSystemThemeChange)
// Check for custom server URL in localStorage or URL params
const params = new URLSearchParams(window.location.search)
const customServer =
params.get('server') || localStorage.getItem('jan-api-server')
if (customServer) {
setServerUrl(customServer)
}
return () => {
observer.disconnect()
mediaQuery.removeEventListener('change', handleSystemThemeChange)
}
}, [])
// Get deployment-specific servers
const getServers = () => {
const customServers = serverUrl
? [{ url: serverUrl, description: 'Custom Server' }]
: []
if (deployment === 'cloud') {
return [
...customServers,
{
url: 'https://api.jan.ai/v1',
description: 'Jan Server (Production)',
},
{
url: 'http://localhost:8000/v1',
description: 'Jan Server (Local Development)',
},
]
}
// Local deployment
return [
...customServers,
{
url: 'http://127.0.0.1:1337',
description: 'Local Jan Server (Default)',
},
{
url: 'http://localhost:1337',
description: 'Local Jan Server (localhost)',
},
{
url: 'http://localhost:8080',
description: 'Local Jan Server (Alternative Port)',
},
]
}
return (
<div className="scalar-wrapper">
{/* Optional server URL input */}
<div
className="server-config"
style={{
padding: '1rem',
background: 'var(--sl-color-bg-nav)',
borderBottom: '1px solid var(--sl-color-hairline)',
display: 'flex',
gap: '1rem',
alignItems: 'center',
fontSize: '0.9rem',
}}
>
<label
htmlFor="custom-server"
style={{ color: 'var(--sl-color-gray-3)' }}
>
Custom Server URL (optional):
</label>
<input
id="custom-server"
type="text"
placeholder="e.g., http://localhost:3000"
value={serverUrl}
onChange={(e) => {
setServerUrl(e.target.value)
localStorage.setItem('jan-api-server', e.target.value)
}}
style={{
padding: '0.25rem 0.5rem',
background: 'var(--sl-color-bg)',
border: '1px solid var(--sl-color-hairline)',
borderRadius: '4px',
color: 'var(--sl-color-text)',
fontFamily: 'monospace',
fontSize: '0.875rem',
flex: '1',
maxWidth: '300px',
}}
/>
<button
onClick={() => {
setServerUrl('')
localStorage.removeItem('jan-api-server')
}}
style={{
padding: '0.25rem 0.75rem',
background: 'var(--sl-color-gray-6)',
color: 'var(--sl-color-text)',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '0.875rem',
}}
>
Reset
</button>
</div>
<ApiReferenceReact
configuration={{
spec: {
url: specUrl,
},
theme: 'default',
darkMode: isDarkMode,
layout: 'modern',
hideModels: false,
hideDownloadButton: false,
hideTestRequestButton: false,
showSidebar: true,
authentication:
deployment === 'cloud'
? {
preferredSecurityScheme: 'bearerAuth',
apiKey: {
token: '',
},
}
: undefined,
servers: getServers(),
metaData: {
title: title || 'Jan API Reference',
description:
description || "Jan's OpenAI-compatible API documentation",
},
customCss: `
/* Minimal theme sync with Starlight */
:root {
--scalar-color-accent: ${isDarkMode ? '#22c55e' : '#16a34a'};
}
/* Fix logo visibility in light mode */
.scalar-api-reference .dark-mode-logo {
display: ${isDarkMode ? 'block' : 'none'};
}
.scalar-api-reference .light-mode-logo {
display: ${isDarkMode ? 'none' : 'block'};
}
/* Ensure logo contrast in header */
.scalar-api-reference header img[alt*="Jan"] {
filter: ${isDarkMode ? 'none' : 'invert(1)'};
}
`,
}}
/>
</div>
)
}
export default ScalarApiReferenceMulti

View File

@ -0,0 +1,101 @@
# Navigation Configuration
This directory contains configuration files for managing navigation across Jan's documentation sites.
## Overview
As Jan grows to include multiple products (Jan Desktop, Jan Server, Jan Mobile, etc.), we need a scalable way to manage navigation across different documentation sections. This configuration approach allows us to:
1. **Maintain consistency** across different products
2. **Avoid duplication** in navigation code
3. **Scale easily** as new products are added
4. **Separate concerns** between regular docs and API reference pages
## Structure
### `navigation.js`
Central navigation configuration file containing:
- Product-specific navigation links
- API deployment configurations
- Helper functions for navigation management
- Feature flags for navigation behavior
## Navigation Strategy
### Regular Documentation Pages
- Navigation is injected via `astro.config.mjs`
- Shows "Docs" and "API Reference" links
- Appears in the main header next to search
### API Reference Pages
- Have their own navigation via `ApiReferenceLayout.astro`
- Navigation is built into the layout (not injected)
- Prevents duplicate navigation elements
## Adding New Products
To add navigation for a new product:
1. Update `navigation.js`:
```javascript
products: {
janServer: {
name: 'Jan Server',
links: [
{ href: '/server', text: 'Server Docs', isActive: (path) => path.startsWith('/server') },
{ href: '/server/api', text: 'Server API', isActive: (path) => path.startsWith('/server/api') }
]
}
}
```
2. Update `astro.config.mjs` if needed to handle product-specific logic
3. Create corresponding layout components if the product needs custom API reference pages
## Configuration in astro.config.mjs
The navigation injection in `astro.config.mjs` is kept minimal and clean:
```javascript
const JAN_NAV_CONFIG = {
links: [/* navigation links */],
excludePaths: [/* paths that have their own navigation */]
};
```
This configuration:
- Is easy to read and modify
- Doesn't interfere with API reference pages
- Can be extended for multiple products
- Maintains clean separation of concerns
## Best Practices
1. **Keep it simple**: Navigation configuration should be declarative, not complex logic
2. **Avoid duplication**: Use the configuration to generate navigation, don't hardcode it multiple places
3. **Test changes**: Always verify navigation works on both regular docs and API reference pages
4. **Document changes**: Update this README when adding new products or changing navigation strategy
## Testing Navigation
After making changes, verify:
1. Navigation appears correctly on regular docs pages
2. Navigation doesn't duplicate on API reference pages
3. Active states work correctly
4. Mobile responsiveness is maintained
5. Theme switching doesn't break navigation
## Future Considerations
- **Product switcher**: Add a dropdown to switch between different product docs
- **Version selector**: Add version switching for API documentation
- **Search integration**: Integrate product-specific search scopes
- **Analytics**: Track navigation usage to improve UX
## Related Files
- `/astro.config.mjs` - Navigation injection for regular docs
- `/src/components/ApiReferenceLayout.astro` - API reference navigation
- `/src/pages/api.astro` - API documentation landing page
- `/src/pages/api-reference/*.astro` - API reference pages

View File

@ -0,0 +1,138 @@
/**
* Navigation Configuration
*
* Centralized navigation configuration for Jan documentation.
* This makes it easy to manage navigation across multiple products
* and maintain consistency across different documentation sections.
*/
export const NAVIGATION_CONFIG = {
// Main product navigation links
products: {
jan: {
name: 'Jan',
links: [
{
href: '/',
text: 'Docs',
isActive: (path) => path === '/' || (path.startsWith('/') && !path.startsWith('/api')),
description: 'Jan documentation and guides'
},
{
href: '/api',
text: 'API Reference',
isActive: (path) => path.startsWith('/api'),
description: 'OpenAI-compatible API documentation'
}
]
},
// Future products can be added here
// Example:
// janServer: {
// name: 'Jan Server',
// links: [
// { href: '/server', text: 'Server Docs', isActive: (path) => path.startsWith('/server') },
// { href: '/server/api', text: 'Server API', isActive: (path) => path.startsWith('/server/api') }
// ]
// }
},
// API deployment configurations
apiDeployments: {
local: {
name: 'Local API',
defaultServers: [
{ url: 'http://127.0.0.1:1337', description: 'Local Jan Server (Default)' },
{ url: 'http://localhost:1337', description: 'Local Jan Server (localhost)' },
{ url: 'http://localhost:8080', description: 'Local Jan Server (Alternative Port)' }
],
requiresAuth: false,
engine: 'llama.cpp'
},
cloud: {
name: 'Jan Server',
defaultServers: [
{ url: 'https://api.jan.ai/v1', description: 'Jan Server (Production)' },
{ url: 'http://localhost:8000/v1', description: 'Jan Server (Local Development)' }
],
requiresAuth: true,
engine: 'vLLM'
}
},
// Navigation styles configuration
styles: {
navLink: {
base: 'nav-link',
active: 'nav-link-active'
},
container: {
base: 'custom-nav-links',
mobile: 'custom-nav-links-mobile'
}
},
// Feature flags for navigation behavior
features: {
persistCustomServer: true,
allowUrlParams: true,
showProductSwitcher: false, // For future multi-product support
mobileMenuBreakpoint: 768
},
// Helper functions
helpers: {
/**
* Get navigation links for current product
* @param {string} productKey - The product identifier
* @returns {Array} Navigation links for the product
*/
getProductNav(productKey = 'jan') {
return this.products[productKey]?.links || [];
},
/**
* Determine if current path should show API reference navigation
* @param {string} path - Current pathname
* @returns {boolean} Whether to show API reference navigation
*/
isApiReferencePage(path) {
return path.startsWith('/api-reference/') || path.startsWith('/api/');
},
/**
* Get server configuration for deployment type
* @param {string} deployment - 'local' or 'cloud'
* @returns {Object} Server configuration
*/
getServerConfig(deployment) {
return this.apiDeployments[deployment] || this.apiDeployments.local;
},
/**
* Build navigation HTML for injection
* @param {string} currentPath - Current page path
* @param {string} productKey - Product identifier
* @returns {string} HTML string for navigation
*/
buildNavigationHTML(currentPath, productKey = 'jan') {
const links = this.getProductNav(productKey);
return links.map(link => `
<a href="${link.href}"
class="${this.styles.navLink.base} ${link.isActive(currentPath) ? this.styles.navLink.active : ''}"
${link.isActive(currentPath) ? 'aria-current="page"' : ''}
title="${link.description || link.text}">
${link.text}
</a>
`).join('');
}
}
};
// Export for use in browser context
if (typeof window !== 'undefined') {
window.JanNavigationConfig = NAVIGATION_CONFIG;
}
export default NAVIGATION_CONFIG;

View File

@ -22,7 +22,7 @@ banner:
We just launched something cool! 👋Jan now <a href="./jan/multi-modal">supports image 🖼️ attachments</a> 🎉
---
import { Aside } from '@astrojs/starlight/components';
import { Aside, LinkCard } from '@astrojs/starlight/components';
![Jan's Cover Image](../../assets/jan_loaded.png)
@ -121,11 +121,10 @@ The best AI is the one you control. Not the one that other control for you.
- Run powerful models locally on consumer hardware
- Connect to any cloud provider with your API keys
- Use MCP tools for real-world tasks
- Access transparent model evaluations
### What We're Building
- More specialized models that excel at specific tasks
- Expanded app ecosystem (mobile, web, extensions)
- Expanded app ecosystem (mobile, self-hosted server, web, extensions)
- Richer connector ecosystem
- An evaluation framework to build better models
@ -147,6 +146,13 @@ hardware, and better techniques, but we're honest that this is a journey, not a
2. Choose a model - download locally or add cloud API keys
3. Start chatting or connect tools via MCP
4. Build with our [local API](./api-server)
5. Explore the [API Reference](/api) for Local and Server endpoints
<LinkCard
title="API Reference"
description="Learn how to get started with the API Reference"
href="/api"
/>
## Acknowledgements

View File

@ -3,7 +3,7 @@ title: Local API Server
description: Build AI applications with Jan's OpenAI-compatible API server.
---
import { Aside } from '@astrojs/starlight/components';
import { Aside, LinkCard } from '@astrojs/starlight/components';
Jan provides an OpenAI-compatible API server that runs entirely on your computer. Use the same API patterns you know from OpenAI, but with complete control over your models and data.
@ -31,10 +31,17 @@ curl http://localhost:1337/v1/chat/completions \
## Documentation
- [**API Reference**](/api) - Interactive API documentation with Try It Out
- [**API Configuration**](./api-server) - Server settings, authentication, CORS
- [**Engine Settings**](./llama-cpp) - Configure llama.cpp for your hardware
- [**Server Settings**](./settings) - Advanced configuration options
<LinkCard
title="API Reference"
description="Learn how to get started with the API Reference"
href="/api"
/>
## Integration Examples
### Continue (VS Code)
@ -94,14 +101,14 @@ Jan implements the core OpenAI API endpoints. Some advanced features like functi
## Why Use Jan's API?
**Privacy** - Your data stays on your machine with local models
**Cost** - No API fees for local model usage
**Control** - Choose your models, parameters, and hardware
**Flexibility** - Mix local and cloud models as needed
**Privacy** - Your data stays on your machine with local models
**Cost** - No API fees for local model usage
**Control** - Choose your models, parameters, and hardware
**Flexibility** - Mix local and cloud models as needed
## Related Resources
- [Models Overview](/docs/jan/manage-models) - Available models
- [Data Storage](/docs/jan/data-folder) - Where Jan stores data
- [Troubleshooting](/docs/jan/troubleshooting) - Common issues
- [GitHub Repository](https://github.com/janhq/jan) - Source code
- [GitHub Repository](https://github.com/janhq/jan) - Source code

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Redirecting to API Documentation | Jan</title>
<meta http-equiv="refresh" content="0; url=/api" />
<link rel="canonical" href="/api" />
</head>
<body>
<div style="display: flex; align-items: center; justify-content: center; min-height: 100vh; font-family: system-ui, sans-serif;">
<div style="text-align: center;">
<h1>Redirecting...</h1>
<p>If you are not redirected automatically, <a href="/api">click here to go to the API Documentation</a>.</p>
</div>
</div>
<script>
// Fallback redirect in case meta refresh doesn't work
window.location.href = '/api';
</script>
</body>
</html>

View File

@ -0,0 +1,331 @@
---
import ApiReferenceLayout from '../../components/ApiReferenceLayout.astro'
import ScalarApiReferenceMulti from '../../components/react/ScalarApiReferenceMulti.jsx'
const title = 'Jan Server API Reference'
const description = 'OpenAI-compatible API documentation for Jan Server powered by vLLM'
---
<ApiReferenceLayout title={title} description={description}>
<div class="api-header-section">
<div class="api-header-content">
<div class="breadcrumb">
<a href="/api">API Documentation</a>
<span class="separator">/</span>
<span>Jan Server</span>
</div>
<h1>Jan Server API Reference</h1>
<p class="subtitle">
Self-hostable Jan Server powered by vLLM for high-throughput serving
</p>
<div class="quick-info">
<div class="info-item">
<span class="info-label">Base URL:</span>
<code>http://your-server:8000/v1</code>
</div>
<div class="info-item">
<span class="info-label">Engine:</span>
<span class="engine-badge">vLLM</span>
</div>
<div class="info-item">
<span class="info-label">Format:</span>
<span>OpenAI Compatible</span>
</div>
</div>
</div>
</div>
<div class="api-notice">
<div class="notice-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
<line x1="12" y1="9" x2="12" y2="13"></line>
<line x1="12" y1="17" x2="12.01" y2="17"></line>
</svg>
</div>
<div class="notice-content">
<strong>Authentication Required:</strong> All requests to Jan Server require authentication.
Include your API key in the <code>Authorization</code> header as <code>Bearer YOUR_API_KEY</code>.
Configure authentication in your server settings.
</div>
</div>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path>
</svg>
</div>
<h3>High Performance</h3>
<p>Powered by vLLM's PagedAttention for efficient memory usage and high throughput</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="3"></circle>
<circle cx="12" cy="12" r="10"></circle>
<circle cx="12" cy="12" r="6"></circle>
</svg>
</div>
<h3>Auto-Scaling</h3>
<p>Automatically scales to handle your workload with intelligent load balancing</p>
</div>
<div class="feature-card">
<div class="feature-icon">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M12 2L2 7l10 5 10-5-10-5z"></path>
<path d="M2 17l10 5 10-5"></path>
<path d="M2 12l10 5 10-5"></path>
</svg>
</div>
<h3>Multi-Model Support</h3>
<p>Support for various model formats and sizes with optimized serving configurations</p>
</div>
</div>
<div id="scalar-container">
<ScalarApiReferenceMulti
client:load
specUrl="/openapi/cloud-openapi.json"
title="Jan Server API"
description="OpenAI-compatible API for server inference with vLLM"
deployment="cloud"
/>
</div>
<style>
.api-header-section {
background: linear-gradient(180deg, var(--sl-color-bg-nav) 0%, transparent 100%);
padding: 2rem 2rem 3rem;
border-bottom: 1px solid var(--sl-color-hairline);
}
.api-header-content {
max-width: 1200px;
margin: 0 auto;
}
.breadcrumb {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
font-size: 0.9rem;
}
.breadcrumb a {
color: var(--sl-color-gray-3);
text-decoration: none;
transition: color 0.2s ease;
}
.breadcrumb a:hover {
color: #a855f7;
}
.separator {
color: var(--sl-color-gray-5);
}
.api-header-section h1 {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 0.5rem;
color: var(--sl-color-text);
}
.subtitle {
font-size: 1.1rem;
color: var(--sl-color-gray-2);
margin-bottom: 2rem;
max-width: 700px;
}
.quick-info {
display: flex;
flex-wrap: wrap;
gap: 2rem;
padding: 1.5rem;
background: var(--sl-color-bg);
border: 1px solid var(--sl-color-hairline);
border-radius: 8px;
}
.info-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
.info-label {
color: var(--sl-color-gray-4);
font-size: 0.9rem;
}
.info-item code {
padding: 0.25rem 0.5rem;
background: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 4px;
font-family: 'Fira Code', 'Monaco', monospace;
font-size: 0.9rem;
color: #a855f7;
}
.engine-badge {
padding: 0.25rem 0.75rem;
background: linear-gradient(135deg, #a855f7 0%, #9333ea 100%);
color: white;
border-radius: 100px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.api-notice {
max-width: 1200px;
margin: 2rem auto;
padding: 1.5rem;
background: linear-gradient(135deg, rgba(168, 85, 247, 0.1) 0%, rgba(147, 51, 234, 0.1) 100%);
border: 1px solid rgba(168, 85, 247, 0.3);
border-radius: 8px;
display: flex;
gap: 1rem;
align-items: flex-start;
}
.notice-icon {
flex-shrink: 0;
color: #a855f7;
}
.notice-content {
flex: 1;
color: var(--sl-color-gray-2);
line-height: 1.6;
}
.notice-content strong {
color: var(--sl-color-text);
}
.notice-content code {
padding: 0.2rem 0.4rem;
background: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 4px;
font-family: 'Fira Code', 'Monaco', monospace;
font-size: 0.85rem;
color: #a855f7;
}
.notice-content a {
color: #667eea;
text-decoration: none;
font-weight: 500;
transition: color 0.2s ease;
}
.notice-content a:hover {
color: #9333ea;
text-decoration: underline;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
max-width: 1200px;
margin: 2rem auto;
padding: 0 2rem;
}
.feature-card {
padding: 1.5rem;
background: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 8px;
transition: all 0.3s ease;
}
.feature-card:hover {
transform: translateY(-2px);
border-color: #a855f7;
box-shadow: 0 8px 16px rgba(168, 85, 247, 0.1);
}
.feature-icon {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, rgba(168, 85, 247, 0.2) 0%, rgba(147, 51, 234, 0.2) 100%);
border-radius: 12px;
margin-bottom: 1rem;
color: #a855f7;
}
.feature-card h3 {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: var(--sl-color-text);
}
.feature-card p {
color: var(--sl-color-gray-3);
line-height: 1.5;
font-size: 0.95rem;
}
#scalar-container {
width: 100%;
min-height: calc(100vh - 80px);
position: relative;
}
/* Minimal styling to preserve Scalar's native functionality */
#scalar-container :global(.scalar-api-reference) {
padding-top: 0;
position: relative;
z-index: 1;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.api-header-section {
padding: 1rem;
}
.api-header-section h1 {
font-size: 1.75rem;
}
.subtitle {
font-size: 1rem;
}
.quick-info {
flex-direction: column;
gap: 1rem;
}
.api-notice {
margin: 1rem;
padding: 1rem;
}
.features-grid {
grid-template-columns: 1fr;
padding: 0 1rem;
}
#scalar-container {
min-height: calc(100vh - 60px);
}
}
</style>
</ApiReferenceLayout>

View File

@ -0,0 +1,222 @@
---
import ApiReferenceLayout from '../../components/ApiReferenceLayout.astro'
import ScalarApiReferenceMulti from '../../components/react/ScalarApiReferenceMulti.jsx'
const title = 'Jan Local API Reference'
const description = 'OpenAI-compatible API documentation for Jan running locally with llama.cpp'
---
<ApiReferenceLayout title={title} description={description}>
<div class="api-header-section">
<div class="api-header-content">
<div class="breadcrumb">
<a href="/api">API Documentation</a>
<span class="separator">/</span>
<span>Local API</span>
</div>
<h1>Local API Reference</h1>
<p class="subtitle">
Run Jan locally on your machine with llama.cpp's high-performance inference engine
</p>
<div class="quick-info">
<div class="info-item">
<span class="info-label">Base URL:</span>
<code>http://localhost:1337</code>
</div>
<div class="info-item">
<span class="info-label">Engine:</span>
<span class="engine-badge">llama.cpp</span>
</div>
<div class="info-item">
<span class="info-label">Format:</span>
<span>OpenAI Compatible</span>
</div>
</div>
</div>
</div>
<div class="api-notice">
<div class="notice-icon">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="16" x2="12" y2="12"></line>
<line x1="12" y1="8" x2="12.01" y2="8"></line>
</svg>
</div>
<div class="notice-content">
<strong>Getting Started:</strong> Make sure Jan is running locally on your machine.
You can start the server by launching the Jan application or running the CLI command.
Default port is 1337, but you can configure it in your settings.
</div>
</div>
<div id="scalar-container">
<ScalarApiReferenceMulti
client:load
specUrl="/openapi/openapi.json"
title="Jan Local API"
description="OpenAI-compatible API for local inference with llama.cpp"
deployment="local"
/>
</div>
<style>
.api-header-section {
background: linear-gradient(180deg, var(--sl-color-bg-nav) 0%, transparent 100%);
padding: 2rem 2rem 3rem;
border-bottom: 1px solid var(--sl-color-hairline);
}
.api-header-content {
max-width: 1200px;
margin: 0 auto;
}
.breadcrumb {
display: flex;
align-items: center;
gap: 0.5rem;
margin-bottom: 1rem;
font-size: 0.9rem;
}
.breadcrumb a {
color: var(--sl-color-gray-3);
text-decoration: none;
transition: color 0.2s ease;
}
.breadcrumb a:hover {
color: var(--sl-color-accent, #22c55e);
}
.separator {
color: var(--sl-color-gray-5);
}
.api-header-section h1 {
font-size: 2.5rem;
font-weight: 700;
margin-bottom: 0.5rem;
color: var(--sl-color-text);
}
.subtitle {
font-size: 1.1rem;
color: var(--sl-color-gray-2);
margin-bottom: 2rem;
max-width: 700px;
}
.quick-info {
display: flex;
flex-wrap: wrap;
gap: 2rem;
padding: 1.5rem;
background: var(--sl-color-bg);
border: 1px solid var(--sl-color-hairline);
border-radius: 8px;
}
.info-item {
display: flex;
align-items: center;
gap: 0.5rem;
}
.info-label {
color: var(--sl-color-gray-4);
font-size: 0.9rem;
}
.info-item code {
padding: 0.25rem 0.5rem;
background: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 4px;
font-family: 'Fira Code', 'Monaco', monospace;
font-size: 0.9rem;
color: var(--sl-color-accent, #22c55e);
}
.engine-badge {
padding: 0.25rem 0.75rem;
background: linear-gradient(135deg, var(--sl-color-accent, #22c55e) 0%, #16a34a 100%);
color: white;
border-radius: 100px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.api-notice {
max-width: 1200px;
margin: 2rem auto;
padding: 1.5rem;
background: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 8px;
display: flex;
gap: 1rem;
align-items: flex-start;
}
.notice-icon {
flex-shrink: 0;
color: var(--sl-color-accent, #22c55e);
}
.notice-content {
flex: 1;
color: var(--sl-color-gray-2);
line-height: 1.6;
}
.notice-content strong {
color: var(--sl-color-text);
}
#scalar-container {
width: 100%;
min-height: calc(100vh - 80px);
position: relative;
}
/* Minimal styling to preserve Scalar's native functionality */
#scalar-container :global(.scalar-api-reference) {
padding-top: 0;
position: relative;
z-index: 1;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.api-header-section {
padding: 1rem;
}
.api-header-section h1 {
font-size: 1.75rem;
}
.subtitle {
font-size: 1rem;
}
.quick-info {
flex-direction: column;
gap: 1rem;
}
.api-notice {
margin: 1rem;
padding: 1rem;
}
#scalar-container {
min-height: calc(100vh - 60px);
}
}
</style>
</ApiReferenceLayout>

257
website/src/pages/api.astro Normal file
View File

@ -0,0 +1,257 @@
---
import ApiReferenceLayout from '../components/ApiReferenceLayout.astro'
const title = 'Jan API Documentation'
const description = 'OpenAI-compatible API for local and server deployments'
---
<ApiReferenceLayout title={title} description={description}>
<div class="api-docs">
<header class="docs-header">
<h1>👋Jan API Documentation</h1>
<p>OpenAI-compatible API for local and server deployments</p>
</header>
<div class="deployment-options">
<div class="option local">
<div class="option-header">
<h2>Local API</h2>
<span class="engine">llama.cpp</span>
</div>
<p>Run Jan locally with complete privacy.</p>
<div class="option-details">
<code>http://localhost:1337/v1</code>
<span class="features">Privacy-first • GGUF models • CPU/GPU</span>
</div>
<a href="/api-reference/local" class="docs-link">View Documentation →</a>
</div>
<div class="option server">
<div class="option-header">
<h2>Jan Server</h2>
<span class="engine">vLLM</span>
</div>
<p>Self-hostable server for high-throughput inference.</p>
<div class="option-details">
<code>http://your-server:8000/v1</code>
<span class="features">Open source • Auto-scaling • Multi-GPU</span>
</div>
<a href="/api-reference/cloud" class="docs-link">View Documentation →</a>
</div>
</div>
<section class="quick-start">
<h3>Quick Start</h3>
<div class="start-steps">
<div class="step">
<span class="step-num">1</span>
<span>Choose deployment type</span>
</div>
<div class="step">
<span class="step-num">2</span>
<span>Start your server</span>
</div>
<div class="step">
<span class="step-num">3</span>
<span>Make API requests</span>
</div>
</div>
</section>
</div>
<style>
.api-docs {
max-width: 800px;
margin: 0 auto;
padding: 2rem;
}
.docs-header {
text-align: center;
margin-bottom: 3rem;
}
.docs-header h1 {
font-size: 2.5rem;
font-weight: 600;
margin-bottom: 0.5rem;
color: var(--sl-color-text);
}
.docs-header p {
font-size: 1.1rem;
color: var(--sl-color-gray-2);
}
.deployment-options {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
margin-bottom: 3rem;
}
.option {
padding: 1.5rem;
background: var(--sl-color-bg-nav);
border: 1px solid var(--sl-color-hairline);
border-radius: 8px;
transition: border-color 0.2s;
}
.option:hover {
border-color: var(--sl-color-accent);
}
.option-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 0.75rem;
}
.option-header h2 {
font-size: 1.25rem;
font-weight: 600;
margin: 0;
color: var(--sl-color-text);
}
.engine {
padding: 0.2rem 0.5rem;
background: var(--sl-color-hairline);
color: var(--sl-color-gray-2);
border-radius: 4px;
font-size: 0.75rem;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.local .engine {
background: rgba(34, 197, 94, 0.2);
color: #22c55e;
}
.server .engine {
background: rgba(168, 85, 247, 0.2);
color: #a855f7;
}
.option p {
color: var(--sl-color-gray-3);
margin-bottom: 1rem;
line-height: 1.5;
}
.option-details {
margin-bottom: 1rem;
}
.option-details code {
display: block;
padding: 0.5rem;
background: var(--sl-color-bg);
border: 1px solid var(--sl-color-hairline);
border-radius: 4px;
font-family: 'Monaco', 'Courier New', monospace;
font-size: 0.85rem;
color: var(--sl-color-gray-2);
margin-bottom: 0.5rem;
}
.features {
font-size: 0.9rem;
color: var(--sl-color-gray-4);
}
.docs-link {
color: var(--sl-color-accent);
text-decoration: none;
font-weight: 500;
transition: color 0.2s;
}
.docs-link:hover {
color: var(--sl-color-text);
}
.local .docs-link {
color: #22c55e;
}
.local .docs-link:hover {
color: #16a34a;
}
.server .docs-link {
color: #a855f7;
}
.server .docs-link:hover {
color: #9333ea;
}
.quick-start {
padding: 1.5rem;
background: var(--sl-color-bg-nav);
border-radius: 8px;
}
.quick-start h3 {
font-size: 1.1rem;
font-weight: 600;
margin-bottom: 1rem;
color: var(--sl-color-text);
}
.start-steps {
display: flex;
gap: 2rem;
}
.step {
display: flex;
align-items: center;
gap: 0.5rem;
}
.step-num {
width: 1.5rem;
height: 1.5rem;
display: flex;
align-items: center;
justify-content: center;
background: var(--sl-color-accent);
color: white;
border-radius: 50%;
font-size: 0.8rem;
font-weight: 600;
flex-shrink: 0;
}
.step span:last-child {
color: var(--sl-color-gray-2);
font-size: 0.9rem;
}
@media (max-width: 768px) {
.api-docs {
padding: 1rem;
}
.docs-header h1 {
font-size: 2rem;
}
.deployment-options {
grid-template-columns: 1fr;
gap: 1rem;
}
.start-steps {
flex-direction: column;
gap: 0.75rem;
}
}
</style>
</ApiReferenceLayout>