mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-07-14 18:15:56 -04:00
refactor: replace Biome with oxlint + oxfmt
Migrate the entire monorepo from Biome 2.4.7 to oxlint 1.56.0 (linter) and oxfmt 0.41.0 (formatter) for faster lint/format and broader rule coverage. - Add `.oxlintrc.json` with React, TypeScript, unicorn, import plugins and correctness/suspicious categories - Add `.oxfmtrc.json` with 2-space indent, import sorting, and Tailwind class sorting (all 30+ custom className attributes migrated) - Add `docs/.oxlintrc.json` and `docs/.oxfmtrc.json` with Next.js plugin - Update all 12 workspace package.json scripts: `oxlint`, `oxfmt`, `oxfmt --check` - Add `format:check` turbo task and CI step - Update VS Code settings/extensions to use `oxc.oxc-vscode` - Update CI path triggers from `biome.json` to new config files - Remove all `biome-ignore` comments and fix shadowed variables - Delete `biome.json` and `docs/biome.json` - Reformat entire codebase with oxfmt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
||||
"proseWrap": "never",
|
||||
"sortImports": {
|
||||
"groups": ["builtin", "external", "internal", "parent", "sibling", "index"],
|
||||
"internalPattern": ["@/", "@sofa/", "collections/"],
|
||||
"newlinesBetween": true,
|
||||
"order": "asc"
|
||||
},
|
||||
"sortTailwindcss": {
|
||||
"attributes": ["classList"],
|
||||
"functions": ["cn", "clsx", "cva"]
|
||||
},
|
||||
"ignorePatterns": [
|
||||
"node_modules",
|
||||
".next",
|
||||
"dist",
|
||||
"build",
|
||||
".source",
|
||||
"public/openapi.json",
|
||||
"content/docs/api/**/*.mdx"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"extends": ["../.oxlintrc.json"],
|
||||
"plugins": ["eslint", "typescript", "unicorn", "oxc", "react", "nextjs", "import"],
|
||||
"categories": {
|
||||
"correctness": "error",
|
||||
"suspicious": "warn"
|
||||
},
|
||||
"rules": {
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"import/no-unassigned-import": "off"
|
||||
},
|
||||
"ignorePatterns": ["node_modules", ".next", "dist", "build", ".source", "public/openapi.json"]
|
||||
}
|
||||
+3
-6
@@ -1,7 +1,6 @@
|
||||
# sofa-docs
|
||||
|
||||
This is a Next.js application generated with
|
||||
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).
|
||||
This is a Next.js application generated with [Create Fumadocs](https://github.com/fuma-nama/fumadocs).
|
||||
|
||||
Run development server:
|
||||
|
||||
@@ -36,10 +35,8 @@ Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js and Fumadocs, take a look at the following
|
||||
resources:
|
||||
To learn more about Next.js and Fumadocs, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
|
||||
features and API.
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
- [Fumadocs](https://fumadocs.dev) - learn about Fumadocs
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
{
|
||||
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": true
|
||||
},
|
||||
"files": {
|
||||
"ignoreUnknown": true,
|
||||
"includes": [
|
||||
"**",
|
||||
"!node_modules",
|
||||
"!.next",
|
||||
"!dist",
|
||||
"!build",
|
||||
"!.source",
|
||||
"!public/openapi.json"
|
||||
]
|
||||
},
|
||||
"css": {
|
||||
"parser": {
|
||||
"cssModules": true,
|
||||
"tailwindDirectives": true
|
||||
}
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true
|
||||
},
|
||||
"domains": {
|
||||
"next": "recommended",
|
||||
"react": "recommended"
|
||||
}
|
||||
},
|
||||
"assist": {
|
||||
"actions": {
|
||||
"source": {
|
||||
"organizeImports": "on"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+142
-77
@@ -12,21 +12,22 @@
|
||||
"fumadocs-openapi": "^10.3.18",
|
||||
"fumadocs-ui": "^16.6.17",
|
||||
"lucide-react": "^0.577.0",
|
||||
"next": "16.1.6",
|
||||
"next": "16.1.7",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"shiki": "^4.0.2",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.7",
|
||||
"@tailwindcss/postcss": "^4.2.1",
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "^25.5.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"oxfmt": "0.41.0",
|
||||
"oxlint": "1.56.0",
|
||||
"postcss": "^8.5.8",
|
||||
"tailwindcss": "^4.2.1",
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^5.9.3",
|
||||
},
|
||||
},
|
||||
@@ -34,24 +35,6 @@
|
||||
"packages": {
|
||||
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
||||
|
||||
"@biomejs/biome": ["@biomejs/biome@2.4.7", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.7", "@biomejs/cli-darwin-x64": "2.4.7", "@biomejs/cli-linux-arm64": "2.4.7", "@biomejs/cli-linux-arm64-musl": "2.4.7", "@biomejs/cli-linux-x64": "2.4.7", "@biomejs/cli-linux-x64-musl": "2.4.7", "@biomejs/cli-win32-arm64": "2.4.7", "@biomejs/cli-win32-x64": "2.4.7" }, "bin": { "biome": "bin/biome" } }, "sha512-vXrgcmNGZ4lpdwZSpMf1hWw1aWS6B+SyeSYKTLrNsiUsAdSRN0J4d/7mF3ogJFbIwFFSOL3wT92Zzxia/d5/ng=="],
|
||||
|
||||
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Oo0cF5mHzmvDmTXw8XSjhCia8K6YrZnk7aCS54+/HxyMdZMruMO3nfpDsrlar/EQWe41r1qrwKiCa2QDYHDzWA=="],
|
||||
|
||||
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-I+cOG3sd/7HdFtvDSnF9QQPrWguUH7zrkIMMykM3PtfWU9soTcS2yRb9Myq6MHmzbeCT08D1UmY+BaiMl5CcoQ=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-om6FugwmibzfP/6ALj5WRDVSND4H2G9X0nkI1HZpp2ySf9lW2j0X68oQSaHEnls6666oy4KDsc5RFjT4m0kV0w=="],
|
||||
|
||||
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-I2NvM9KPb09jWml93O2/5WMfNR7Lee5Latag1JThDRMURVhPX74p9UDnyTw3Ae6cE1DgXfw7sqQgX7rkvpc0vw=="],
|
||||
|
||||
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.7", "", { "os": "linux", "cpu": "x64" }, "sha512-bV8/uo2Tj+gumnk4sUdkerWyCPRabaZdv88IpbmDWARQQoA/Q0YaqPz1a+LSEDIL7OfrnPi9Hq1Llz4ZIGyIQQ=="],
|
||||
|
||||
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.7", "", { "os": "linux", "cpu": "x64" }, "sha512-00kx4YrBMU8374zd2wHuRV5wseh0rom5HqRND+vDldJPrWwQw+mzd/d8byI9hPx926CG+vWzq6AeiT7Yi5y59g=="],
|
||||
|
||||
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-hOUHBMlFCvDhu3WCq6vaBoG0dp0LkWxSEnEEsxxXvOa9TfT6ZBnbh72A/xBM7CBYB7WgwqboetzFEVDnMxelyw=="],
|
||||
|
||||
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.7", "", { "os": "win32", "cpu": "x64" }, "sha512-qEpGjSkPC3qX4ycbMUthXvi9CkRq7kZpkqMY1OyhmYlYLnANnooDQ7hDerM8+0NJ+DZKVnsIc07h30XOpt7LtQ=="],
|
||||
|
||||
"@emnapi/runtime": ["@emnapi/runtime@1.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw=="],
|
||||
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.4", "", { "os": "aix", "cpu": "ppc64" }, "sha512-cQPwL2mp2nSmHHJlCyoXgHGhbEPMrEEU5xhkcy3Hs/O7nGZqEpZ2sUtLaL9MORLtDfRvVl2/3PAuEkYZH0Ty8Q=="],
|
||||
@@ -114,9 +97,9 @@
|
||||
|
||||
"@floating-ui/utils": ["@floating-ui/utils@0.2.11", "", {}, "sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg=="],
|
||||
|
||||
"@formatjs/fast-memoize": ["@formatjs/fast-memoize@3.1.0", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-b5mvSWCI+XVKiz5WhnBCY3RJ4ZwfjAidU0yVlKa3d3MSgKmH1hC3tBGEAtYyN5mqL7N0G5x0BOUYyO8CEupWgg=="],
|
||||
"@formatjs/fast-memoize": ["@formatjs/fast-memoize@3.1.1", "", {}, "sha512-CbNbf+tlJn1baRnPkNePnBqTLxGliG6DDgNa/UtV66abwIjwsliPMOt0172tzxABYzSuxZBZfcp//qI8AvBWPg=="],
|
||||
|
||||
"@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.8.1", "", { "dependencies": { "@formatjs/fast-memoize": "3.1.0", "tslib": "^2.8.1" } }, "sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA=="],
|
||||
"@formatjs/intl-localematcher": ["@formatjs/intl-localematcher@0.8.2", "", { "dependencies": { "@formatjs/fast-memoize": "3.1.1" } }, "sha512-q05KMYGJLyqFNFtIb8NhWLF5X3aK/k0wYt7dnRFuy6aLQL+vUwQ1cg5cO4qawEiINybeCPXAWlprY2mSBjSXAQ=="],
|
||||
|
||||
"@fumadocs/tailwind": ["@fumadocs/tailwind@0.0.3", "", { "dependencies": { "postcss-selector-parser": "^7.1.1" }, "peerDependencies": { "tailwindcss": "^4.0.0" }, "optionalPeers": ["tailwindcss"] }, "sha512-/FWcggMz9BhoX+13xBoZLX+XX9mYvJ50dkTqy3IfocJqua65ExcsKfxwKH8hgTO3vA5KnWv4+4jU7LaW2AjAmQ=="],
|
||||
|
||||
@@ -186,26 +169,102 @@
|
||||
|
||||
"@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.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-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="],
|
||||
|
||||
"@next/env": ["@next/env@16.1.6", "", {}, "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="],
|
||||
"@next/env": ["@next/env@16.1.7", "", {}, "sha512-rJJbIdJB/RQr2F1nylZr/PJzamvNNhfr3brdKP6s/GW850jbtR70QlSfFselvIBbcPUOlQwBakexjFzqLzF6pg=="],
|
||||
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw=="],
|
||||
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-b2wWIE8sABdyafc4IM8r5Y/dS6kD80JRtOGrUiKTsACFQfWWgUQ2NwoUX1yjFMXVsAwcQeNpnucF2ZrujsBBPg=="],
|
||||
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ=="],
|
||||
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-zcnVaaZulS1WL0Ss38R5Q6D2gz7MtBu8GZLPfK+73D/hp4GFMrC2sudLky1QibfV7h6RJBJs/gOFvYP0X7UVlQ=="],
|
||||
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw=="],
|
||||
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-2ant89Lux/Q3VyC8vNVg7uBaFVP9SwoK2jJOOR0L8TQnX8CAYnh4uctAScy2Hwj2dgjVHqHLORQZJ2wH6VxhSQ=="],
|
||||
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ=="],
|
||||
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-uufcze7LYv0FQg9GnNeZ3/whYfo+1Q3HnQpm16o6Uyi0OVzLlk2ZWoY7j07KADZFY8qwDbsmFnMQP3p3+Ftprw=="],
|
||||
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ=="],
|
||||
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.7", "", { "os": "linux", "cpu": "x64" }, "sha512-KWVf2gxYvHtvuT+c4MBOGxuse5TD7DsMFYSxVxRBnOzok/xryNeQSjXgxSv9QpIVlaGzEn/pIuI6Koosx8CGWA=="],
|
||||
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg=="],
|
||||
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.7", "", { "os": "linux", "cpu": "x64" }, "sha512-HguhaGwsGr1YAGs68uRKc4aGWxLET+NevJskOcCAwXbwj0fYX0RgZW2gsOCzr9S11CSQPIkxmoSbuVaBp4Z3dA=="],
|
||||
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw=="],
|
||||
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-S0n3KrDJokKTeFyM/vGGGR8+pCmXYrjNTk2ZozOL1C/JFdfUIL9O1ATaJOl5r2POe56iRChbsszrjMAdWSv7kQ=="],
|
||||
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.6", "", { "os": "win32", "cpu": "x64" }, "sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A=="],
|
||||
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.7", "", { "os": "win32", "cpu": "x64" }, "sha512-mwgtg8CNZGYm06LeEd+bNnOUfwOyNem/rOiP14Lsz+AnUY92Zq/LXwtebtUiaeVkhbroRCQ0c8GlR4UT1U+0yg=="],
|
||||
|
||||
"@orama/orama": ["@orama/orama@3.1.18", "", {}, "sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA=="],
|
||||
|
||||
"@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.41.0", "", { "os": "android", "cpu": "arm" }, "sha512-REfrqeMKGkfMP+m/ScX4f5jJBSmVNYcpoDF8vP8f8eYPDuPGZmzp56NIUsYmx3h7f6NzC6cE3gqh8GDWrJHCKw=="],
|
||||
|
||||
"@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.41.0", "", { "os": "android", "cpu": "arm64" }, "sha512-s0b1dxNgb2KomspFV2LfogC2XtSJB42POXF4bMCLJyvQmAGos4ZtjGPfQreToQEaY0FQFjz3030ggI36rF1q5g=="],
|
||||
|
||||
"@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.41.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EGXGualADbv/ZmamE7/2DbsrYmjoPlAmHEpTL4vapLF4EfVD6fr8/uQDFnPJkUBjiSWFJZtFNsGeN1B6V3owmA=="],
|
||||
|
||||
"@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.41.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-WxySJEvdQQYMmyvISH3qDpTvoS0ebnIP63IMxLLWowJyPp/AAH0hdWtlo+iGNK5y3eVfa5jZguwNaQkDKWpGSw=="],
|
||||
|
||||
"@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.41.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Y2kzMkv3U3oyuYaR4wTfGjOTYTXiFC/hXmG0yVASKkbh02BJkvD98Ij8bIevr45hNZ0DmZEgqiXF+9buD4yMYQ=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.41.0", "", { "os": "linux", "cpu": "arm" }, "sha512-ptazDjdUyhket01IjPTT6ULS1KFuBfTUU97osTP96X5y/0oso+AgAaJzuH81oP0+XXyrWIHbRzozSAuQm4p48g=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.41.0", "", { "os": "linux", "cpu": "arm" }, "sha512-UkoL2OKxFD+56bPEBcdGn+4juTW4HRv/T6w1dIDLnvKKWr6DbarB/mtHXlADKlFiJubJz8pRkttOR7qjYR6lTA=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.41.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-gofu0PuumSOHYczD8p62CPY4UF6ee+rSLZJdUXkpwxg6pILiwSDBIouPskjF/5nF3A7QZTz2O9KFNkNxxFN9tA=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.41.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-VfVZxL0+6RU86T8F8vKiDBa+iHsr8PAjQmKGBzSCAX70b6x+UOMFl+2dNihmKmUwqkCazCPfYjt6SuAPOeQJ3g=="],
|
||||
|
||||
"@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.41.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-bwzokz2eGvdfJbc0i+zXMJ4BBjQPqg13jyWpEEZDOrBCQ91r8KeY2Mi2kUeuMTZNFXju+jcAbAbpyJxRGla0eg=="],
|
||||
|
||||
"@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.41.0", "", { "os": "linux", "cpu": "none" }, "sha512-POLM//PCH9uqDeNDwWL3b3DkMmI3oI2cU6hwc2lnztD1o7dzrQs3R9nq555BZ6wI7t2lyhT9CS+CRaz5X0XqLA=="],
|
||||
|
||||
"@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.41.0", "", { "os": "linux", "cpu": "none" }, "sha512-NNK7PzhFqLUwx/G12Xtm6scGv7UITvyGdAR5Y+TlqsG+essnuRWR4jRNODWRjzLZod0T3SayRbnkSIWMBov33w=="],
|
||||
|
||||
"@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.41.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-qVf/zDC5cN9eKe4qI/O/m445er1IRl6swsSl7jHkqmOSVfknwCe5JXitYjZca+V/cNJSU/xPlC5EFMabMMFDpw=="],
|
||||
|
||||
"@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.41.0", "", { "os": "linux", "cpu": "x64" }, "sha512-ojxYWu7vUb6ysYqVCPHuAPVZHAI40gfZ0PDtZAMwVmh2f0V8ExpPIKoAKr7/8sNbAXJBBpZhs2coypIo2jJX4w=="],
|
||||
|
||||
"@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.41.0", "", { "os": "linux", "cpu": "x64" }, "sha512-O2exZLBxoCMIv2vlvcbkdedazJPTdG0VSup+0QUCfYQtx751zCZNboX2ZUOiQ/gDTdhtXvSiot0h6GEGkOyalA=="],
|
||||
|
||||
"@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.41.0", "", { "os": "none", "cpu": "arm64" }, "sha512-N+31/VoL+z+NNBt8viy3I4NaIdPbiYeOnB884LKqvXldaE2dRztdPv3q5ipfZYv0RwFp7JfqS4I27K/DSHCakg=="],
|
||||
|
||||
"@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.41.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z7NAtu/RN8kjCQ1y5oDD0nTAeRswh3GJ93qwcW51srmidP7XPBmZbLlwERu1W5veCevQJtPS9xmkpcDTYsGIwQ=="],
|
||||
|
||||
"@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.41.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-uNxxP3l4bJ6VyzIeRqCmBU2Q0SkCFgIhvx9/9dJ9V8t/v+jP1IBsuaLwCXGR8JPHtkj4tFp+RHtUmU2ZYAUpMA=="],
|
||||
|
||||
"@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.41.0", "", { "os": "win32", "cpu": "x64" }, "sha512-49ZSpbZ1noozyPapE8SUOSm3IN0Ze4b5nkO+4+7fq6oEYQQJFhE0saj5k/Gg4oewVPdjn0L3ZFeWk2Vehjcw7A=="],
|
||||
|
||||
"@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.56.0", "", { "os": "android", "cpu": "arm" }, "sha512-IyfYPthZyiSKwAv/dLjeO18SaK8MxLI9Yss2JrRDyweQAkuL3LhEy7pwIwI7uA3KQc1Vdn20kdmj3q0oUIQL6A=="],
|
||||
|
||||
"@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.56.0", "", { "os": "android", "cpu": "arm64" }, "sha512-Ga5zYrzH6vc/VFxhn6MmyUnYEfy9vRpwTIks99mY3j6Nz30yYpIkWryI0QKPCgvGUtDSXVLEaMum5nA+WrNOSg=="],
|
||||
|
||||
"@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.56.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ogmbdJysnw/D4bDcpf1sPLpFThZ48lYp4aKYm10Z/6Nh1SON6NtnNhTNOlhEY296tDFItsZUz+2tgcSYqh8Eyw=="],
|
||||
|
||||
"@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.56.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-x8QE1h+RAtQ2g+3KPsP6Fk/tdz6zJQUv5c7fTrJxXV3GHOo+Ry5p/PsogU4U+iUZg0rj6hS+E4xi+mnwwlDCWQ=="],
|
||||
|
||||
"@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.56.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-6G+WMZvwJpMvY7my+/SHEjb7BTk/PFbePqLpmVmUJRIsJMy/UlyYqjpuh0RCgYYkPLcnXm1rUM04kbTk8yS1Yg=="],
|
||||
|
||||
"@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-YYHBsk/sl7fYwQOok+6W5lBPeUEvisznV/HZD2IfZmF3Bns6cPC3Z0vCtSEOaAWTjYWN3jVsdu55jMxKlsdlhg=="],
|
||||
|
||||
"@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.56.0", "", { "os": "linux", "cpu": "arm" }, "sha512-+AZK8rOUr78y8WT6XkDb04IbMRqauNV+vgT6f8ZLOH8wnpQ9i7Nol0XLxAu+Cq7Sb+J9wC0j6Km5hG8rj47/yQ=="],
|
||||
|
||||
"@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-urse2SnugwJRojUkGSSeH2LPMaje5Q50yQtvtL9HFckiyeqXzoFwOAZqD5TR29R2lq7UHidfFDM9EGcchcbb8A=="],
|
||||
|
||||
"@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.56.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-rkTZkBfJ4TYLjansjSzL6mgZOdN5IvUnSq3oNJSLwBcNvy3dlgQtpHPrRxrCEbbcp7oQ6If0tkNaqfOsphYZ9g=="],
|
||||
|
||||
"@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.56.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-uqL1kMH3u69/e1CH2EJhP3CP28jw2ExLsku4o8RVAZ7fySo9zOyI2fy9pVlTAp4voBLVgzndXi3SgtdyCTa2aA=="],
|
||||
|
||||
"@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-j0CcMBOgV6KsRaBdsebIeiy7hCjEvq2KdEsiULf2LZqAq0v1M1lWjelhCV57LxsqaIGChXFuFJ0RiFrSRHPhSg=="],
|
||||
|
||||
"@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.56.0", "", { "os": "linux", "cpu": "none" }, "sha512-7VDOiL8cDG3DQ/CY3yKjbV1c4YPvc4vH8qW09Vv+5ukq3l/Kcyr6XGCd5NvxUmxqDb2vjMpM+eW/4JrEEsUetA=="],
|
||||
|
||||
"@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.56.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-JGRpX0M+ikD3WpwJ7vKcHKV6Kg0dT52BW2Eu2BupXotYeqGXBrbY+QPkAyKO6MNgKozyTNaRh3r7g+VWgyAQYQ=="],
|
||||
|
||||
"@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-dNaICPvtmuxFP/VbqdofrLqdS3bM/AKJN3LMJD52si44ea7Be1cBk6NpfIahaysG9Uo+L98QKddU9CD5L8UHnQ=="],
|
||||
|
||||
"@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.56.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pF1vOtM+GuXmbklM1hV8WMsn6tCNPvkUzklj/Ej98JhlanbmA2RB1BILgOpwSuCTRTIYx2MXssmEyQQ90QF5aA=="],
|
||||
|
||||
"@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.56.0", "", { "os": "none", "cpu": "arm64" }, "sha512-bp8NQ4RE6fDIFLa4bdBiOA+TAvkNkg+rslR+AvvjlLTYXLy9/uKAYLQudaQouWihLD/hgkrXIKKzXi5IXOewwg=="],
|
||||
|
||||
"@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.56.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-PxT4OJDfMOQBzo3OlzFb9gkoSD+n8qSBxyVq2wQSZIHFQYGEqIRTo9M0ZStvZm5fdhMqaVYpOnJvH2hUMEDk/g=="],
|
||||
|
||||
"@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.56.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-PTRy6sIEPqy2x8PTP1baBNReN/BNEFmde0L+mYeHmjXE1Vlcc9+I5nsqENsB2yAm5wLkzPoTNCMY/7AnabT4/A=="],
|
||||
|
||||
"@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.56.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ZHa0clocjLmIDr+1LwoWtxRcoYniAvERotvwKUYKhH41NVfl0Y4LNbyQkwMZzwDvKklKGvGZ5+DAG58/Ik47tQ=="],
|
||||
|
||||
"@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
|
||||
|
||||
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
|
||||
@@ -276,13 +335,13 @@
|
||||
|
||||
"@radix-ui/rect": ["@radix-ui/rect@1.1.1", "", {}, "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw=="],
|
||||
|
||||
"@scalar/helpers": ["@scalar/helpers@0.4.1", "", {}, "sha512-XfyYqSUA597wfzS8lmMY1xvYv4si2WytuoBWj7JDpx3E/lVq7YEsticXF/Q30ttFVRBfgQErg8MQI6b6IkZr2Q=="],
|
||||
"@scalar/helpers": ["@scalar/helpers@0.4.2", "", {}, "sha512-IrgrGVSahCfYDNWITazz4Q1BOndp5eEzlimRkfxiYn++KqeWyLfALyym1omqcdKGYtiSx1KIbKaUJL9vkjaN7w=="],
|
||||
|
||||
"@scalar/json-magic": ["@scalar/json-magic@0.12.3", "", { "dependencies": { "@scalar/helpers": "0.4.1", "pathe": "^2.0.3", "yaml": "^2.8.0" } }, "sha512-SX4LbdCk/0JLP4t4oz1nzqfMzHsG9gY1jSgKB7Q2BsQHJ4V1zapQ+aFrMmbjaCrz8hueGG/3UCtgyWBNuGmT9g=="],
|
||||
"@scalar/json-magic": ["@scalar/json-magic@0.12.4", "", { "dependencies": { "@scalar/helpers": "0.4.2", "pathe": "^2.0.3", "yaml": "^2.8.0" } }, "sha512-ZsJM+y9SOVjRL+g9Tr/jFEodcYPfHSt5ZRrpbeGDK71yTvSZw41A3UJ7Bg+RXM8JJWRYcJkYVkzrmbb/ig7qlA=="],
|
||||
|
||||
"@scalar/openapi-types": ["@scalar/openapi-types@0.6.0", "", { "dependencies": { "zod": "^4.3.5" } }, "sha512-OeaCrQmXGqO+ZRGgo/mAA8X1nTsdNWW2BxQjyDWTCSD1Qv5Cm58QvKzINKvJPFWrS0LXebRF6OXN+2H2hu9xpA=="],
|
||||
"@scalar/openapi-types": ["@scalar/openapi-types@0.6.1", "", { "dependencies": { "zod": "^4.3.5" } }, "sha512-P1RvyTFN0vRSL136OqWjlZfSFjY9JoJfuD6LM1mIjoocfwmqX3WuzsFEFX6hAeeDlTh6gjbiy+OdhSee8GFfSA=="],
|
||||
|
||||
"@scalar/openapi-upgrader": ["@scalar/openapi-upgrader@0.2.0", "", { "dependencies": { "@scalar/openapi-types": "0.6.0" } }, "sha512-T8XKPaYBrxn+8THq8HgXjqpnqp71YZsPCamNYIYJrIM5pXSbBLyLoAh6uie7YfhcNvdQWc/KqahHQebEIcmeqA=="],
|
||||
"@scalar/openapi-upgrader": ["@scalar/openapi-upgrader@0.2.1", "", { "dependencies": { "@scalar/openapi-types": "0.6.1" } }, "sha512-7KO1HZ5Uau7FVznu7lLRmoD9UwJIt73rAXVCgNx4hPe3dzdiCwxq+nnc5Z7xFY2BVlAklGuacgZhoZFJt8kbJw=="],
|
||||
|
||||
"@shikijs/core": ["@shikijs/core@4.0.2", "", { "dependencies": { "@shikijs/primitive": "4.0.2", "@shikijs/types": "4.0.2", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw=="],
|
||||
|
||||
@@ -308,35 +367,35 @@
|
||||
|
||||
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||
|
||||
"@tailwindcss/node": ["@tailwindcss/node@4.2.1", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.1" } }, "sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg=="],
|
||||
"@tailwindcss/node": ["@tailwindcss/node@4.2.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.32.0", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.2" } }, "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA=="],
|
||||
|
||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.1", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.1", "@tailwindcss/oxide-darwin-arm64": "4.2.1", "@tailwindcss/oxide-darwin-x64": "4.2.1", "@tailwindcss/oxide-freebsd-x64": "4.2.1", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.1", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.1", "@tailwindcss/oxide-linux-arm64-musl": "4.2.1", "@tailwindcss/oxide-linux-x64-gnu": "4.2.1", "@tailwindcss/oxide-linux-x64-musl": "4.2.1", "@tailwindcss/oxide-wasm32-wasi": "4.2.1", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.1", "@tailwindcss/oxide-win32-x64-msvc": "4.2.1" } }, "sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw=="],
|
||||
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.2", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.2", "@tailwindcss/oxide-darwin-arm64": "4.2.2", "@tailwindcss/oxide-darwin-x64": "4.2.2", "@tailwindcss/oxide-freebsd-x64": "4.2.2", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", "@tailwindcss/oxide-linux-x64-musl": "4.2.2", "@tailwindcss/oxide-wasm32-wasi": "4.2.2", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" } }, "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg=="],
|
||||
|
||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.1", "", { "os": "android", "cpu": "arm64" }, "sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg=="],
|
||||
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.2", "", { "os": "android", "cpu": "arm64" }, "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw=="],
|
||||
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg=="],
|
||||
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw=="],
|
||||
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw=="],
|
||||
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA=="],
|
||||
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.1", "", { "os": "linux", "cpu": "arm" }, "sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw=="],
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.2", "", { "os": "linux", "cpu": "arm" }, "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ=="],
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ=="],
|
||||
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g=="],
|
||||
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg=="],
|
||||
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.1", "", { "os": "linux", "cpu": "x64" }, "sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g=="],
|
||||
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.1", "", { "dependencies": { "@emnapi/core": "^1.8.1", "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q=="],
|
||||
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.2", "", { "dependencies": { "@emnapi/core": "^1.8.1", "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA=="],
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ=="],
|
||||
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.1", "", { "os": "win32", "cpu": "x64" }, "sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ=="],
|
||||
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.2", "", { "os": "win32", "cpu": "x64" }, "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA=="],
|
||||
|
||||
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.1", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.1", "@tailwindcss/oxide": "4.2.1", "postcss": "^8.5.6", "tailwindcss": "4.2.1" } }, "sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw=="],
|
||||
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.2", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.2", "@tailwindcss/oxide": "4.2.2", "postcss": "^8.5.6", "tailwindcss": "4.2.2" } }, "sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ=="],
|
||||
|
||||
"@takumi-rs/core": ["@takumi-rs/core@0.73.1", "", { "dependencies": { "@takumi-rs/helpers": "0.73.1" }, "optionalDependencies": { "@takumi-rs/core-darwin-arm64": "0.73.1", "@takumi-rs/core-darwin-x64": "0.73.1", "@takumi-rs/core-linux-arm64-gnu": "0.73.1", "@takumi-rs/core-linux-arm64-musl": "0.73.1", "@takumi-rs/core-linux-x64-gnu": "0.73.1", "@takumi-rs/core-linux-x64-musl": "0.73.1", "@takumi-rs/core-win32-arm64-msvc": "0.73.1", "@takumi-rs/core-win32-x64-msvc": "0.73.1" } }, "sha512-+8GNu0O9lDNBjXx2uM3/15zIyTCt+vI3Ltmkudacybnvl6Kx2TMokRWD9/bymg19ZVcGbfOC1FsFIGQdVePCvQ=="],
|
||||
|
||||
@@ -386,7 +445,7 @@
|
||||
|
||||
"@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
|
||||
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.57.0", "", {}, "sha512-dTLI8PEXhjUC7B9Kre+u0XznO696BhXcTlOn0/6kf1fHaQW8+VjJAVHJ3eTI14ZapTxdkOmc80HblPQLaEeJdg=="],
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.57.1", "", {}, "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ=="],
|
||||
|
||||
"@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
|
||||
|
||||
@@ -406,9 +465,9 @@
|
||||
|
||||
"bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="],
|
||||
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.7", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-1ghYO3HnxGec0TCGBXiDLVns4eCSx4zJpxnHrlqFQajmhfKMQBzUGDdkMK7fUW7PTHTeLf+j87aTuKuuwWzMGw=="],
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.10.8", "", { "bin": { "baseline-browser-mapping": "dist/cli.cjs" } }, "sha512-PCLz/LXGBsNTErbtB6i5u4eLpHeMfi93aUv5duMmj6caNu6IphS4q6UevDnL36sZQv9lrP11dbPKGMaXPwMKfQ=="],
|
||||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001778", "", {}, "sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg=="],
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001780", "", {}, "sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ=="],
|
||||
|
||||
"ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="],
|
||||
|
||||
@@ -452,7 +511,7 @@
|
||||
|
||||
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
|
||||
|
||||
"enhanced-resolve": ["enhanced-resolve@5.20.0", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-/ce7+jQ1PQ6rVXwe+jKEg5hW5ciicHwIQUagZkp6IufBoY3YDgdTTY1azVs0qoRgVmvsNB+rbjLJxDAeHHtwsQ=="],
|
||||
"enhanced-resolve": ["enhanced-resolve@5.20.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.0" } }, "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA=="],
|
||||
|
||||
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
@@ -488,15 +547,15 @@
|
||||
|
||||
"fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
|
||||
|
||||
"fast-xml-builder": ["fast-xml-builder@1.1.3", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-1o60KoFw2+LWKQu3IdcfcFlGTW4dpqEWmjhYec6H82AYZU2TVBXep6tMl8Z1Y+wM+ZrzCwe3BZ9Vyd9N2rIvmg=="],
|
||||
"fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="],
|
||||
|
||||
"fast-xml-parser": ["fast-xml-parser@5.5.5", "", { "dependencies": { "fast-xml-builder": "^1.1.3", "path-expression-matcher": "^1.1.3", "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-NLY+V5NNbdmiEszx9n14mZBseJTC50bRq1VHsaxOmR72JDuZt+5J1Co+dC/4JPnyq+WrIHNM69r0sqf7BMb3Mg=="],
|
||||
"fast-xml-parser": ["fast-xml-parser@5.5.6", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.1.3", "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-3+fdZyBRVg29n4rXP0joHthhcHdPUHaIC16cuyyd1iLsuaO6Vea36MPrxgAzbZna8lhvZeRL8Bc9GP56/J9xEw=="],
|
||||
|
||||
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||
|
||||
"foreach": ["foreach@2.0.6", "", {}, "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg=="],
|
||||
|
||||
"framer-motion": ["framer-motion@12.36.0", "", { "dependencies": { "motion-dom": "^12.36.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-4PqYHAT7gev0ke0wos+PyrcFxI0HScjm3asgU8nSYa8YzJFuwgIvdj3/s3ZaxLq0bUSboIn19A2WS/MHwLCvfw=="],
|
||||
"framer-motion": ["framer-motion@12.38.0", "", { "dependencies": { "motion-dom": "^12.38.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g=="],
|
||||
|
||||
"fumadocs-core": ["fumadocs-core@16.6.17", "", { "dependencies": { "@formatjs/intl-localematcher": "^0.8.1", "@orama/orama": "^3.1.18", "@shikijs/rehype": "^4.0.2", "@shikijs/transformers": "^4.0.2", "estree-util-value-to-estree": "^3.5.0", "github-slugger": "^2.0.0", "hast-util-to-estree": "^3.1.3", "hast-util-to-jsx-runtime": "^2.3.6", "image-size": "^2.0.2", "mdast-util-mdx": "^3.0.0", "mdast-util-to-markdown": "^2.1.2", "negotiator": "^1.0.0", "npm-to-yarn": "^3.0.1", "path-to-regexp": "^8.3.0", "remark": "^15.0.1", "remark-gfm": "^4.0.1", "remark-rehype": "^11.1.2", "scroll-into-view-if-needed": "^3.1.0", "shiki": "^4.0.2", "tinyglobby": "^0.2.15", "unified": "^11.0.5", "unist-util-visit": "^5.1.0", "vfile": "^6.0.3" }, "peerDependencies": { "@mdx-js/mdx": "*", "@mixedbread/sdk": "^0.46.0", "@orama/core": "1.x.x", "@oramacloud/client": "2.x.x", "@tanstack/react-router": "1.x.x", "@types/estree-jsx": "*", "@types/hast": "*", "@types/mdast": "*", "@types/react": "*", "algoliasearch": "5.x.x", "flexsearch": "*", "lucide-react": "*", "next": "16.x.x", "react": "^19.2.0", "react-dom": "^19.2.0", "react-router": "7.x.x", "waku": "^0.26.0 || ^0.27.0 || ^1.0.0", "zod": "4.x.x" }, "optionalPeers": ["@mdx-js/mdx", "@mixedbread/sdk", "@orama/core", "@oramacloud/client", "@tanstack/react-router", "@types/estree-jsx", "@types/hast", "@types/mdast", "@types/react", "algoliasearch", "flexsearch", "lucide-react", "next", "react", "react-dom", "react-router", "waku", "zod"] }, "sha512-ssHz9a7+ZZSkHjB4/sfHq9rO2fPW8jtw2fPeDVzkPJd34DqOPbxuaP0TQ6CEs1Pei99Fky9CzE8ENS3H8WFxnQ=="],
|
||||
|
||||
@@ -556,29 +615,29 @@
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
||||
|
||||
"lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
|
||||
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
||||
|
||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
|
||||
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||
|
||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
|
||||
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
|
||||
|
||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
|
||||
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
|
||||
|
||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
|
||||
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
|
||||
|
||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
|
||||
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
|
||||
|
||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
|
||||
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
|
||||
|
||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
|
||||
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
|
||||
|
||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
|
||||
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
|
||||
|
||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
|
||||
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
|
||||
|
||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
|
||||
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
|
||||
|
||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
|
||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
||||
|
||||
"longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="],
|
||||
|
||||
@@ -692,9 +751,9 @@
|
||||
|
||||
"micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="],
|
||||
|
||||
"motion": ["motion@12.36.0", "", { "dependencies": { "framer-motion": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-5BMQuktYUX8aEByKWYx5tR4X3G08H2OMgp46wTxZ4o7CDDstyy4A0fe9RLNMjZiwvntCWGDvs16sC87/emz4Yw=="],
|
||||
"motion": ["motion@12.38.0", "", { "dependencies": { "framer-motion": "^12.38.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w=="],
|
||||
|
||||
"motion-dom": ["motion-dom@12.36.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-Ep1pq8P88rGJ75om8lTCA13zqd7ywPGwCqwuWwin6BKc0hMLkVfcS6qKlRqEo2+t0DwoUcgGJfXwaiFn4AOcQA=="],
|
||||
"motion-dom": ["motion-dom@12.38.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA=="],
|
||||
|
||||
"motion-utils": ["motion-utils@12.36.0", "", {}, "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg=="],
|
||||
|
||||
@@ -704,7 +763,7 @@
|
||||
|
||||
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
|
||||
|
||||
"next": ["next@16.1.6", "", { "dependencies": { "@next/env": "16.1.6", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.6", "@next/swc-darwin-x64": "16.1.6", "@next/swc-linux-arm64-gnu": "16.1.6", "@next/swc-linux-arm64-musl": "16.1.6", "@next/swc-linux-x64-gnu": "16.1.6", "@next/swc-linux-x64-musl": "16.1.6", "@next/swc-win32-arm64-msvc": "16.1.6", "@next/swc-win32-x64-msvc": "16.1.6", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw=="],
|
||||
"next": ["next@16.1.7", "", { "dependencies": { "@next/env": "16.1.7", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.9.19", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.7", "@next/swc-darwin-x64": "16.1.7", "@next/swc-linux-arm64-gnu": "16.1.7", "@next/swc-linux-arm64-musl": "16.1.7", "@next/swc-linux-x64-gnu": "16.1.7", "@next/swc-linux-x64-musl": "16.1.7", "@next/swc-win32-arm64-msvc": "16.1.7", "@next/swc-win32-x64-msvc": "16.1.7", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-WM0L7WrSvKwoLegLYr6V+mz+RIofqQgVAfHhMp9a88ms0cFX8iX9ew+snpWlSBwpkURJOUdvCEt3uLl3NNzvWg=="],
|
||||
|
||||
"next-themes": ["next-themes@0.4.6", "", { "peerDependencies": { "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc", "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA=="],
|
||||
|
||||
@@ -712,10 +771,14 @@
|
||||
|
||||
"oniguruma-parser": ["oniguruma-parser@0.12.1", "", {}, "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w=="],
|
||||
|
||||
"oniguruma-to-es": ["oniguruma-to-es@4.3.4", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA=="],
|
||||
"oniguruma-to-es": ["oniguruma-to-es@4.3.5", "", { "dependencies": { "oniguruma-parser": "^0.12.1", "regex": "^6.1.0", "regex-recursion": "^6.0.2" } }, "sha512-Zjygswjpsewa0NLTsiizVuMQZbp0MDyM6lIt66OxsF21npUDlzpHi1Mgb/qhQdkb+dWFTzJmFbEWdvZgRho8eQ=="],
|
||||
|
||||
"openapi-sampler": ["openapi-sampler@1.7.2", "", { "dependencies": { "@types/json-schema": "^7.0.7", "fast-xml-parser": "^5.5.1", "json-pointer": "0.6.2" } }, "sha512-OKytvqB5XIaTgA9xtw8W8UTar+uymW2xPVpFN0NihMtuHPdPTGxBEhGnfFnJW5g/gOSIvkP+H0Xh3XhVI9/n7g=="],
|
||||
|
||||
"oxfmt": ["oxfmt@0.41.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.41.0", "@oxfmt/binding-android-arm64": "0.41.0", "@oxfmt/binding-darwin-arm64": "0.41.0", "@oxfmt/binding-darwin-x64": "0.41.0", "@oxfmt/binding-freebsd-x64": "0.41.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.41.0", "@oxfmt/binding-linux-arm-musleabihf": "0.41.0", "@oxfmt/binding-linux-arm64-gnu": "0.41.0", "@oxfmt/binding-linux-arm64-musl": "0.41.0", "@oxfmt/binding-linux-ppc64-gnu": "0.41.0", "@oxfmt/binding-linux-riscv64-gnu": "0.41.0", "@oxfmt/binding-linux-riscv64-musl": "0.41.0", "@oxfmt/binding-linux-s390x-gnu": "0.41.0", "@oxfmt/binding-linux-x64-gnu": "0.41.0", "@oxfmt/binding-linux-x64-musl": "0.41.0", "@oxfmt/binding-openharmony-arm64": "0.41.0", "@oxfmt/binding-win32-arm64-msvc": "0.41.0", "@oxfmt/binding-win32-ia32-msvc": "0.41.0", "@oxfmt/binding-win32-x64-msvc": "0.41.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-sKLdJZdQ3bw6x9qKiT7+eID4MNEXlDHf5ZacfIircrq6Qwjk0L6t2/JQlZZrVHTXJawK3KaMuBoJnEJPcqCEdg=="],
|
||||
|
||||
"oxlint": ["oxlint@1.56.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.56.0", "@oxlint/binding-android-arm64": "1.56.0", "@oxlint/binding-darwin-arm64": "1.56.0", "@oxlint/binding-darwin-x64": "1.56.0", "@oxlint/binding-freebsd-x64": "1.56.0", "@oxlint/binding-linux-arm-gnueabihf": "1.56.0", "@oxlint/binding-linux-arm-musleabihf": "1.56.0", "@oxlint/binding-linux-arm64-gnu": "1.56.0", "@oxlint/binding-linux-arm64-musl": "1.56.0", "@oxlint/binding-linux-ppc64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-gnu": "1.56.0", "@oxlint/binding-linux-riscv64-musl": "1.56.0", "@oxlint/binding-linux-s390x-gnu": "1.56.0", "@oxlint/binding-linux-x64-gnu": "1.56.0", "@oxlint/binding-linux-x64-musl": "1.56.0", "@oxlint/binding-openharmony-arm64": "1.56.0", "@oxlint/binding-win32-arm64-msvc": "1.56.0", "@oxlint/binding-win32-ia32-msvc": "1.56.0", "@oxlint/binding-win32-x64-msvc": "1.56.0" }, "peerDependencies": { "oxlint-tsgolint": ">=0.15.0" }, "optionalPeers": ["oxlint-tsgolint"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-Q+5Mj5PVaH/R6/fhMMFzw4dT+KPB+kQW4kaL8FOIq7tfhlnEVp6+3lcWqFruuTNlUo9srZUW3qH7Id4pskeR6g=="],
|
||||
|
||||
"parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="],
|
||||
|
||||
"parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
|
||||
@@ -784,7 +847,7 @@
|
||||
|
||||
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
||||
|
||||
"sax": ["sax@1.5.0", "", {}, "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA=="],
|
||||
"sax": ["sax@1.6.0", "", {}, "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA=="],
|
||||
|
||||
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||
|
||||
@@ -814,7 +877,7 @@
|
||||
|
||||
"tailwind-merge": ["tailwind-merge@3.5.0", "", {}, "sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A=="],
|
||||
|
||||
"tailwindcss": ["tailwindcss@4.2.1", "", {}, "sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw=="],
|
||||
"tailwindcss": ["tailwindcss@4.2.2", "", {}, "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q=="],
|
||||
|
||||
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
|
||||
|
||||
@@ -822,6 +885,8 @@
|
||||
|
||||
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
|
||||
|
||||
"tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="],
|
||||
|
||||
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
||||
|
||||
"trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
|
||||
|
||||
@@ -17,7 +17,8 @@ There is currently no way to transfer the admin role to another user.
|
||||
Toggle user registration open or closed in **Settings → Security → Open Registration**.
|
||||
|
||||
<Callout type="info">
|
||||
Registration is always open when no users exist — this is how the initial admin account is created. After the first account is registered, it closes automatically.
|
||||
Registration is always open when no users exist — this is how the initial admin account is
|
||||
created. After the first account is registered, it closes automatically.
|
||||
</Callout>
|
||||
|
||||
When registration is closed, new users cannot create accounts unless they authenticate via [OIDC/SSO](/docs/configuration#oidc--sso) with `OIDC_AUTO_REGISTER` enabled.
|
||||
@@ -58,12 +59,12 @@ Click **Create backup** to generate an immediate database backup. Each backup is
|
||||
|
||||
Enable scheduled backups with the toggle and configure:
|
||||
|
||||
| Setting | Default | Options |
|
||||
|---|---|---|
|
||||
| Frequency | Every day | `6h`, `12h`, `1d`, `7d` |
|
||||
| Time | 02:00 | Any `HH:MM` (UTC) |
|
||||
| Day of week | Sunday | For weekly backups only |
|
||||
| Retention | 7 | Max number of scheduled backups to keep |
|
||||
| Setting | Default | Options |
|
||||
| ----------- | --------- | --------------------------------------- |
|
||||
| Frequency | Every day | `6h`, `12h`, `1d`, `7d` |
|
||||
| Time | 02:00 | Any `HH:MM` (UTC) |
|
||||
| Day of week | Sunday | For weekly backups only |
|
||||
| Retention | 7 | Max number of scheduled backups to keep |
|
||||
|
||||
Old backups beyond the retention count are automatically pruned. Scheduled backups are named `sofa-scheduled-*.db`.
|
||||
|
||||
@@ -76,7 +77,8 @@ Upload a backup file or select one from the existing backup list to restore. Bef
|
||||
3. After the database is replaced, **migrations run automatically** to bring older backups up to the current schema.
|
||||
|
||||
<Callout type="warn">
|
||||
Restoring a backup replaces the entire database. All data since the backup was created will be lost. The pre-restore snapshot lets you undo the restore if something goes wrong.
|
||||
Restoring a backup replaces the entire database. All data since the backup was created will be
|
||||
lost. The pre-restore snapshot lets you undo the restore if something goes wrong.
|
||||
</Callout>
|
||||
|
||||
## Background Jobs
|
||||
|
||||
@@ -9,7 +9,7 @@ icon: Settings
|
||||
These three environment variables must be set for Sofa to start:
|
||||
|
||||
| Variable | Description | Example |
|
||||
|---|---|---|
|
||||
| --- | --- | --- |
|
||||
| `TMDB_API_READ_ACCESS_TOKEN` | TMDB API authentication token | [Get one here](https://www.themoviedb.org/settings/api) |
|
||||
| `BETTER_AUTH_SECRET` | Session encryption secret (min 32 chars) | `openssl rand -base64 32` |
|
||||
| `BETTER_AUTH_URL` | Public URL of your instance | `https://sofa.example.com` |
|
||||
@@ -18,11 +18,11 @@ These three environment variables must be set for Sofa to start:
|
||||
|
||||
## Data & Storage
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `DATA_DIR` | `/data` (Docker) or `./data` (dev) | Root directory for all persistent data |
|
||||
| `DATABASE_URL` | `${DATA_DIR}/sqlite.db` | SQLite database file path |
|
||||
| `CACHE_DIR` | `${DATA_DIR}/images` | Image cache directory |
|
||||
| Variable | Default | Description |
|
||||
| -------------- | ---------------------------------- | -------------------------------------- |
|
||||
| `DATA_DIR` | `/data` (Docker) or `./data` (dev) | Root directory for all persistent data |
|
||||
| `DATABASE_URL` | `${DATA_DIR}/sqlite.db` | SQLite database file path |
|
||||
| `CACHE_DIR` | `${DATA_DIR}/images` | Image cache directory |
|
||||
|
||||
`DATABASE_URL` and `CACHE_DIR` are derived from `DATA_DIR` by default but can be overridden independently.
|
||||
|
||||
@@ -30,9 +30,9 @@ The database uses SQLite with WAL (Write-Ahead Logging) mode for concurrent read
|
||||
|
||||
## Image Caching
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `IMAGE_CACHE_ENABLED` | `true` | Cache TMDB images locally |
|
||||
| Variable | Default | Description |
|
||||
| --------------------- | ------- | ------------------------- |
|
||||
| `IMAGE_CACHE_ENABLED` | `true` | Cache TMDB images locally |
|
||||
|
||||
When enabled, Sofa downloads poster, backdrop, and other images from TMDB and serves them from disk. This improves load times and reduces external requests but uses disk space.
|
||||
|
||||
@@ -51,9 +51,9 @@ Set `IMAGE_CACHE_ENABLED=false` to serve images directly from TMDB's CDN instead
|
||||
|
||||
## Logging
|
||||
|
||||
| Variable | Default | Options |
|
||||
|---|---|---|
|
||||
| `LOG_LEVEL` | `info` | `error`, `warn`, `info`, `debug`, `trace` |
|
||||
| Variable | Default | Options |
|
||||
| ----------- | ------- | ----------------------------------------- |
|
||||
| `LOG_LEVEL` | `info` | `error`, `warn`, `info`, `debug`, `trace` |
|
||||
|
||||
Sofa uses structured JSON logging via [Pino](https://getpino.io/). Set to `debug` for troubleshooting.
|
||||
|
||||
@@ -61,13 +61,13 @@ Sofa uses structured JSON logging via [Pino](https://getpino.io/). Set to `debug
|
||||
|
||||
Sofa supports any OpenID Connect provider (Authentik, Keycloak, Authelia, Google Workspace, etc.). OIDC is enabled when all three of `OIDC_CLIENT_ID`, `OIDC_CLIENT_SECRET`, and `OIDC_ISSUER_URL` are set.
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `OIDC_CLIENT_ID` | — | Client ID from your identity provider |
|
||||
| `OIDC_CLIENT_SECRET` | — | Client secret from your identity provider |
|
||||
| `OIDC_ISSUER_URL` | — | Issuer discovery URL |
|
||||
| `OIDC_PROVIDER_NAME` | `SSO` | Label shown on the login button |
|
||||
| `OIDC_AUTO_REGISTER` | `true` | Auto-create accounts on first OIDC login |
|
||||
| Variable | Default | Description |
|
||||
| ------------------------ | ------- | -------------------------------------------- |
|
||||
| `OIDC_CLIENT_ID` | — | Client ID from your identity provider |
|
||||
| `OIDC_CLIENT_SECRET` | — | Client secret from your identity provider |
|
||||
| `OIDC_ISSUER_URL` | — | Issuer discovery URL |
|
||||
| `OIDC_PROVIDER_NAME` | `SSO` | Label shown on the login button |
|
||||
| `OIDC_AUTO_REGISTER` | `true` | Auto-create accounts on first OIDC login |
|
||||
| `DISABLE_PASSWORD_LOGIN` | `false` | Hide the email/password form (requires OIDC) |
|
||||
|
||||
### Callback URL
|
||||
@@ -120,7 +120,7 @@ When OIDC is enabled, account linking is active by default. If a user logs in vi
|
||||
`OIDC_AUTO_REGISTER` and `DISABLE_PASSWORD_LOGIN` interact to control how users can access your instance:
|
||||
|
||||
| `OIDC_AUTO_REGISTER` | `DISABLE_PASSWORD_LOGIN` | Behavior |
|
||||
|---|---|---|
|
||||
| --- | --- | --- |
|
||||
| `true` (default) | `false` (default) | Both login methods available. New OIDC users get accounts created automatically. |
|
||||
| `true` | `true` | OIDC only. Accounts are auto-created on first login. Password form is hidden. |
|
||||
| `false` | `false` | Both login methods available. OIDC users must have a pre-existing account with a matching email. |
|
||||
@@ -128,19 +128,19 @@ When OIDC is enabled, account linking is active by default. If a user logs in vi
|
||||
|
||||
## TMDB Overrides
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `TMDB_API_BASE_URL` | `https://api.themoviedb.org/3` | Override TMDB API endpoint |
|
||||
| `TMDB_IMAGE_BASE_URL` | `https://image.tmdb.org/t/p` | Override TMDB image CDN |
|
||||
| Variable | Default | Description |
|
||||
| --------------------- | ------------------------------ | -------------------------- |
|
||||
| `TMDB_API_BASE_URL` | `https://api.themoviedb.org/3` | Override TMDB API endpoint |
|
||||
| `TMDB_IMAGE_BASE_URL` | `https://image.tmdb.org/t/p` | Override TMDB image CDN |
|
||||
|
||||
These are only needed if you're proxying TMDB requests or using an alternative endpoint.
|
||||
|
||||
## Network
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `CORS_ORIGIN` | `http://localhost:3000` | Allowed CORS origin |
|
||||
| `PORT` | `3000` | Server listening port |
|
||||
| Variable | Default | Description |
|
||||
| ------------- | ----------------------- | --------------------- |
|
||||
| `CORS_ORIGIN` | `http://localhost:3000` | Allowed CORS origin |
|
||||
| `PORT` | `3000` | Server listening port |
|
||||
|
||||
Set `CORS_ORIGIN` to your public URL when using a reverse proxy.
|
||||
|
||||
@@ -148,8 +148,8 @@ Set `CORS_ORIGIN` to your public URL when using a reverse proxy.
|
||||
|
||||
Sofa checks for new versions every 6 hours by contacting the public API.
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| Variable | Default | Description |
|
||||
| ---------------- | ------------------------------- | --------------------------- |
|
||||
| `PUBLIC_API_URL` | `https://public-api.sofa.watch` | Endpoint for version checks |
|
||||
|
||||
Update checks can be disabled in **Settings → Admin → Update Checks**. When a new version is available, a notification appears in the admin settings.
|
||||
@@ -162,12 +162,12 @@ Sofa includes opt-in anonymous telemetry. It is **disabled by default**. See the
|
||||
|
||||
Automatic backups can be enabled in **Settings → Admin → Backups**. Configuration options:
|
||||
|
||||
| Setting | Default | Options |
|
||||
|---|---|---|
|
||||
| Frequency | Every day | `6h`, `12h`, `1d`, `7d` |
|
||||
| Time | 02:00 | Any `HH:MM` |
|
||||
| Day of week | Sunday | (for weekly backups) |
|
||||
| Retention | 7 | Number of scheduled backups to keep |
|
||||
| Setting | Default | Options |
|
||||
| ----------- | --------- | ----------------------------------- |
|
||||
| Frequency | Every day | `6h`, `12h`, `1d`, `7d` |
|
||||
| Time | 02:00 | Any `HH:MM` |
|
||||
| Day of week | Sunday | (for weekly backups) |
|
||||
| Retention | 7 | Number of scheduled backups to keep |
|
||||
|
||||
Backups are SQLite database dumps stored in the `backups/` directory inside `DATA_DIR`. Old backups beyond the retention count are automatically deleted.
|
||||
|
||||
@@ -175,15 +175,15 @@ Backups are SQLite database dumps stored in the `backups/` directory inside `DAT
|
||||
|
||||
Sofa runs several background jobs automatically:
|
||||
|
||||
| Job | Schedule | Description |
|
||||
|---|---|---|
|
||||
| Library refresh | Daily at 3:00 AM | Refreshes metadata for tracked titles |
|
||||
| Streaming availability | Every 6 hours | Updates where titles are available to stream |
|
||||
| Recommendations | Every 12 hours | Refreshes personalized recommendations |
|
||||
| New episodes | Every 12 hours | Checks for new episodes of tracked TV shows |
|
||||
| Image caching | Twice daily | Caches images for tracked titles |
|
||||
| Credits refresh | Daily at 2:00 AM | Updates cast and crew information |
|
||||
| Update check | Every 6 hours | Checks for new Sofa versions |
|
||||
| Telemetry | Daily at 12:30 AM | Sends anonymized usage data (if enabled) |
|
||||
| Job | Schedule | Description |
|
||||
| ---------------------- | ----------------- | -------------------------------------------- |
|
||||
| Library refresh | Daily at 3:00 AM | Refreshes metadata for tracked titles |
|
||||
| Streaming availability | Every 6 hours | Updates where titles are available to stream |
|
||||
| Recommendations | Every 12 hours | Refreshes personalized recommendations |
|
||||
| New episodes | Every 12 hours | Checks for new episodes of tracked TV shows |
|
||||
| Image caching | Twice daily | Caches images for tracked titles |
|
||||
| Credits refresh | Daily at 2:00 AM | Updates cast and crew information |
|
||||
| Update check | Every 6 hours | Checks for new Sofa versions |
|
||||
| Telemetry | Daily at 12:30 AM | Sends anonymized usage data (if enabled) |
|
||||
|
||||
All schedules are in UTC. TMDB API calls are rate-limited with a 300ms delay between requests per title to stay within API limits.
|
||||
|
||||
@@ -7,11 +7,11 @@ Sofa can import your existing watch history, watchlist, and ratings from other t
|
||||
|
||||
## Supported Services
|
||||
|
||||
| Service | OAuth Connect | File Upload | Data Imported |
|
||||
|---|---|---|---|
|
||||
| **Trakt** | Yes | JSON export | Watches, watchlist, ratings |
|
||||
| **Simkl** | Yes | JSON export | Watches, watchlist, ratings, anime (as TV) |
|
||||
| **Letterboxd** | No | ZIP export | Watches, watchlist, ratings (movies only) |
|
||||
| Service | OAuth Connect | File Upload | Data Imported |
|
||||
| -------------- | ------------- | ----------- | ------------------------------------------ |
|
||||
| **Trakt** | Yes | JSON export | Watches, watchlist, ratings |
|
||||
| **Simkl** | Yes | JSON export | Watches, watchlist, ratings, anime (as TV) |
|
||||
| **Letterboxd** | No | ZIP export | Watches, watchlist, ratings (movies only) |
|
||||
|
||||
## Importing via OAuth (Trakt & Simkl)
|
||||
|
||||
@@ -71,11 +71,11 @@ Imports are safe to re-run. Sofa checks for existing data before writing:
|
||||
|
||||
Different services use different rating scales. Sofa converts to its 1–5 star scale:
|
||||
|
||||
| Source | Scale | Conversion |
|
||||
|---|---|---|
|
||||
| Trakt | 1–10 | `round(rating / 2)`, clamped to 1–5 |
|
||||
| Simkl | 1–10 | `round(rating / 2)`, clamped to 1–5 |
|
||||
| Letterboxd | 0.5–5 (half-stars) | `round(rating)`, clamped to 1–5 |
|
||||
| Source | Scale | Conversion |
|
||||
| ---------- | ------------------ | ----------------------------------- |
|
||||
| Trakt | 1–10 | `round(rating / 2)`, clamped to 1–5 |
|
||||
| Simkl | 1–10 | `round(rating / 2)`, clamped to 1–5 |
|
||||
| Letterboxd | 0.5–5 (half-stars) | `round(rating)`, clamped to 1–5 |
|
||||
|
||||
### Timestamps
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description: Connect Sofa to your media stack.
|
||||
icon: Puzzle
|
||||
---
|
||||
|
||||
Sofa integrates with popular media servers and the *arr stack to automate your tracking workflow.
|
||||
Sofa integrates with popular media servers and the \*arr stack to automate your tracking workflow.
|
||||
|
||||
## Webhook Integrations
|
||||
|
||||
|
||||
@@ -7,7 +7,8 @@ icon: Smartphone
|
||||
Sofa has a native mobile app for iOS and Android built with [Expo](https://expo.dev/) and React Native. It connects to your self-hosted Sofa server and provides the same core features as the web app.
|
||||
|
||||
<Callout type="info">
|
||||
The mobile app is not currently available on the App Store or Google Play. You'll need to build it from source.
|
||||
The mobile app is not currently available on the App Store or Google Play. You'll need to build it
|
||||
from source.
|
||||
</Callout>
|
||||
|
||||
## Features
|
||||
|
||||
@@ -10,11 +10,11 @@ Sofa includes optional, privacy-focused telemetry to help understand how the pro
|
||||
|
||||
Sofa has two separate telemetry systems depending on the platform:
|
||||
|
||||
| | Server | Mobile App | Web App |
|
||||
|---|---|---|---|
|
||||
| **System** | Custom reporting | PostHog | None |
|
||||
| **Default** | Disabled | Disabled | N/A |
|
||||
| **Opt-in** | Admin toggle | User toggle + ATT | N/A |
|
||||
| | Server | Mobile App | Web App |
|
||||
| ----------- | ---------------- | ----------------- | ------- |
|
||||
| **System** | Custom reporting | PostHog | None |
|
||||
| **Default** | Disabled | Disabled | N/A |
|
||||
| **Opt-in** | Admin toggle | User toggle + ATT | N/A |
|
||||
|
||||
The web app has **zero analytics** — no tracking scripts, no third-party services.
|
||||
|
||||
@@ -48,7 +48,7 @@ A single JSON payload is sent to `https://public-api.sofa.watch/v1/telemetry`:
|
||||
```
|
||||
|
||||
| Field | Description |
|
||||
|---|---|
|
||||
| --- | --- |
|
||||
| `instanceId` | A random UUID generated once per server instance. Not tied to any user or IP. |
|
||||
| `version` | The Sofa version running on your server. |
|
||||
| `arch` | OS and CPU architecture (e.g. `linux-x64`, `darwin-arm64`). |
|
||||
|
||||
@@ -21,11 +21,11 @@ If your library is empty, the dashboard shows an invitation to start exploring.
|
||||
|
||||
Every title in your library has one of three statuses:
|
||||
|
||||
| Status | Meaning |
|
||||
|---|---|
|
||||
| **Watchlist** | You plan to watch this |
|
||||
| Status | Meaning |
|
||||
| --------------- | ------------------------------ |
|
||||
| **Watchlist** | You plan to watch this |
|
||||
| **In Progress** | You're currently watching this |
|
||||
| **Completed** | You've finished watching this |
|
||||
| **Completed** | You've finished watching this |
|
||||
|
||||
Set a status from any title's detail page by clicking the status button, or press <kbd>W</kbd> to cycle through statuses.
|
||||
|
||||
@@ -51,7 +51,8 @@ These same transitions apply when watches are logged automatically via [webhook
|
||||
- **Catch up** — When you mark an episode as watched while earlier episodes are unwatched, a toast notification offers a "Catch up" button to batch-mark all prior episodes.
|
||||
|
||||
<Callout type="info">
|
||||
Duplicate watches within 5 minutes are automatically ignored. This prevents double-counting when webhook integrations send the same event multiple times.
|
||||
Duplicate watches within 5 minutes are automatically ignored. This prevents double-counting when
|
||||
webhook integrations send the same event multiple times.
|
||||
</Callout>
|
||||
|
||||
## Rating Titles
|
||||
@@ -95,7 +96,8 @@ Title detail pages include a **Where to Watch** section showing which streaming
|
||||
Click a provider's logo to open their page for that title in a new tab.
|
||||
|
||||
<Callout type="info">
|
||||
Streaming availability data is currently limited to the **United States**. Provider information is refreshed automatically every 6 hours for titles in your library.
|
||||
Streaming availability data is currently limited to the **United States**. Provider information is
|
||||
refreshed automatically every 6 hours for titles in your library.
|
||||
</Callout>
|
||||
|
||||
## Account Management
|
||||
@@ -110,13 +112,13 @@ Manage your profile in **Settings**:
|
||||
|
||||
Press <kbd>?</kbd> anywhere in the app to see the full shortcut reference. Here's a summary:
|
||||
|
||||
| Scope | Keys | Action |
|
||||
|---|---|---|
|
||||
| Global | `/` | Open search |
|
||||
| Global | `?` | Show keyboard shortcuts |
|
||||
| Navigation | `g` then `h` | Go to dashboard |
|
||||
| Navigation | `g` then `e` | Go to explore |
|
||||
| Title page | `w` | Cycle watch status |
|
||||
| Title page | `m` | Mark movie as watched |
|
||||
| Title page | `Escape` | Go back |
|
||||
| Title page | `1`–`5` | Rate 1–5 stars |
|
||||
| Scope | Keys | Action |
|
||||
| ---------- | ------------ | ----------------------- |
|
||||
| Global | `/` | Open search |
|
||||
| Global | `?` | Show keyboard shortcuts |
|
||||
| Navigation | `g` then `h` | Go to dashboard |
|
||||
| Navigation | `g` then `e` | Go to explore |
|
||||
| Title page | `w` | Cycle watch status |
|
||||
| Title page | `m` | Mark movie as watched |
|
||||
| Title page | `Escape` | Go back |
|
||||
| Title page | `1`–`5` | Rate 1–5 stars |
|
||||
|
||||
+10
-7
@@ -6,8 +6,9 @@
|
||||
"build": "next build",
|
||||
"dev": "next dev",
|
||||
"start": "next start",
|
||||
"lint": "biome check",
|
||||
"format": "biome format --write",
|
||||
"lint": "oxlint",
|
||||
"format": "oxfmt",
|
||||
"format:check": "oxfmt --check",
|
||||
"check-types": "fumadocs-mdx && next typegen && tsc --noEmit",
|
||||
"generate:api-docs": "bun scripts/generate-api-docs.ts",
|
||||
"postinstall": "fumadocs-mdx"
|
||||
@@ -20,21 +21,23 @@
|
||||
"fumadocs-openapi": "^10.3.18",
|
||||
"fumadocs-ui": "^16.6.17",
|
||||
"lucide-react": "^0.577.0",
|
||||
"next": "16.1.6",
|
||||
"next": "16.1.7",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"shiki": "^4.0.2",
|
||||
"tailwind-merge": "^3.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^2.4.7",
|
||||
"@tailwindcss/postcss": "^4.2.1",
|
||||
"@tailwindcss/postcss": "^4.2.2",
|
||||
"@types/mdx": "^2.0.13",
|
||||
"@types/node": "^25.5.0",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"oxfmt": "0.41.0",
|
||||
"oxlint": "1.56.0",
|
||||
"postcss": "^8.5.8",
|
||||
"tailwindcss": "^4.2.1",
|
||||
"tailwindcss": "^4.2.2",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
},
|
||||
"packageManager": "bun@1.3.10"
|
||||
}
|
||||
|
||||
@@ -4190,13 +4190,24 @@
|
||||
"type": "string",
|
||||
"default": "TMDB API key is not configured"
|
||||
},
|
||||
"data": {}
|
||||
"data": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"const": "TMDB_NOT_CONFIGURED"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"defined",
|
||||
"code",
|
||||
"status",
|
||||
"message"
|
||||
"message",
|
||||
"data"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { generateFiles } from "fumadocs-openapi";
|
||||
|
||||
import { openapi } from "../src/lib/openapi";
|
||||
|
||||
void generateFiles({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { HomeLayout } from "fumadocs-ui/layouts/home";
|
||||
import Link from "next/link";
|
||||
|
||||
import { TmdbLogo } from "@/components/tmdb-logo";
|
||||
import { baseOptions } from "@/lib/layout.shared";
|
||||
|
||||
@@ -7,8 +8,8 @@ export default function Layout({ children }: LayoutProps<"/">) {
|
||||
return (
|
||||
<HomeLayout {...baseOptions()}>
|
||||
{children}
|
||||
<footer className="border-t border-fd-border px-6 py-8">
|
||||
<div className="mx-auto flex max-w-5xl flex-col items-center gap-4 text-center text-xs text-fd-muted-foreground">
|
||||
<footer className="border-fd-border border-t px-6 py-8">
|
||||
<div className="text-fd-muted-foreground mx-auto flex max-w-5xl flex-col items-center gap-4 text-center text-xs">
|
||||
<div className="flex flex-wrap items-center justify-center gap-x-2 gap-y-1">
|
||||
<a
|
||||
href="https://github.com/jakejarvis/sofa"
|
||||
@@ -36,9 +37,8 @@ export default function Layout({ children }: LayoutProps<"/">) {
|
||||
>
|
||||
<TmdbLogo className="h-3" />
|
||||
</a>
|
||||
<p className="max-w-md text-fd-muted-foreground/80">
|
||||
This product uses the TMDB API but is not endorsed or certified by
|
||||
TMDB.
|
||||
<p className="text-fd-muted-foreground/80 max-w-md">
|
||||
This product uses the TMDB API but is not endorsed or certified by TMDB.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Smartphone,
|
||||
} from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
import { ScrollIndicator } from "@/components/scroll-indicator";
|
||||
import { SofaLogo } from "@/components/sofa-logo";
|
||||
|
||||
@@ -21,8 +22,7 @@ const features = [
|
||||
},
|
||||
{
|
||||
title: "Media Server Sync",
|
||||
description:
|
||||
"Automatically log watches from Plex, Jellyfin, or Emby via webhooks.",
|
||||
description: "Automatically log watches from Plex, Jellyfin, or Emby via webhooks.",
|
||||
icon: MonitorPlay,
|
||||
},
|
||||
{
|
||||
@@ -44,8 +44,7 @@ const features = [
|
||||
},
|
||||
{
|
||||
title: "One Container",
|
||||
description:
|
||||
"Deploy with a single Docker image. No external database, no sidecar services.",
|
||||
description: "Deploy with a single Docker image. No external database, no sidecar services.",
|
||||
icon: Container,
|
||||
},
|
||||
];
|
||||
@@ -55,16 +54,16 @@ const steps = [
|
||||
step: "1",
|
||||
title: "Get a TMDB API token",
|
||||
content: (
|
||||
<p className="text-sm text-fd-muted-foreground">
|
||||
<p className="text-fd-muted-foreground text-sm">
|
||||
Create a free account at{" "}
|
||||
<a
|
||||
href="https://www.themoviedb.org/settings/api"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-fd-primary underline underline-offset-4 hover:text-fd-primary/80"
|
||||
className="text-fd-primary hover:text-fd-primary/80 underline underline-offset-4"
|
||||
>
|
||||
themoviedb.org
|
||||
<ExternalLinkIcon className="size-3 inline-block translate-y-[-2px] text-fd-muted-foreground ml-1" />
|
||||
<ExternalLinkIcon className="text-fd-muted-foreground ml-1 inline-block size-3 translate-y-[-2px]" />
|
||||
</a>
|
||||
</p>
|
||||
),
|
||||
@@ -73,7 +72,7 @@ const steps = [
|
||||
step: "2",
|
||||
title: "Set three environment variables",
|
||||
content: (
|
||||
<pre className="overflow-x-auto mt-2 rounded-lg bg-fd-background/80 p-3 text-xs text-fd-muted-foreground ring-1 ring-white/[0.06]">
|
||||
<pre className="bg-fd-background/80 text-fd-muted-foreground mt-2 overflow-x-auto rounded-lg p-3 text-xs ring-1 ring-white/[0.06]">
|
||||
<code>{`TMDB_API_READ_ACCESS_TOKEN=...
|
||||
BETTER_AUTH_SECRET=...
|
||||
BETTER_AUTH_URL=https://sofa.example.com`}</code>
|
||||
@@ -84,7 +83,7 @@ BETTER_AUTH_URL=https://sofa.example.com`}</code>
|
||||
step: "3",
|
||||
title: "Start the container",
|
||||
content: (
|
||||
<pre className="overflow-x-auto mt-2 rounded-lg bg-fd-background/80 p-3 text-xs text-fd-muted-foreground ring-1 ring-white/[0.06]">
|
||||
<pre className="bg-fd-background/80 text-fd-muted-foreground mt-2 overflow-x-auto rounded-lg p-3 text-xs ring-1 ring-white/[0.06]">
|
||||
<code>docker compose up -d</code>
|
||||
</pre>
|
||||
),
|
||||
@@ -99,10 +98,10 @@ export default function HomePage() {
|
||||
<div className="pointer-events-none absolute top-[60vh] -right-24 h-[400px] w-[400px] rounded-full bg-[oklch(0.8_0.14_65)] opacity-[0.04] blur-[100px]" />
|
||||
|
||||
{/* ── Hero ── */}
|
||||
<section className="relative flex min-h-[calc(100vh-3.5rem)] flex-col items-center justify-center px-6 pb-16 pt-8 text-center">
|
||||
<section className="relative flex min-h-[calc(100vh-3.5rem)] flex-col items-center justify-center px-6 pt-8 pb-16 text-center">
|
||||
<div className="relative flex max-w-2xl flex-col items-center gap-8">
|
||||
<p
|
||||
className="animate-stagger-item text-xs font-medium tracking-[0.3em] text-fd-primary uppercase"
|
||||
className="animate-stagger-item text-fd-primary text-xs font-medium tracking-[0.3em] uppercase"
|
||||
style={{ "--stagger-index": 0 } as React.CSSProperties}
|
||||
>
|
||||
Self-hosted movie & TV tracker
|
||||
@@ -112,7 +111,7 @@ export default function HomePage() {
|
||||
className="animate-stagger-item"
|
||||
style={{ "--stagger-index": 1 } as React.CSSProperties}
|
||||
>
|
||||
<SofaLogo className="size-20 text-fd-primary md:size-28" />
|
||||
<SofaLogo className="text-fd-primary size-20 md:size-28" />
|
||||
</div>
|
||||
|
||||
<h1
|
||||
@@ -123,11 +122,10 @@ export default function HomePage() {
|
||||
</h1>
|
||||
|
||||
<p
|
||||
className="animate-stagger-item max-w-md text-base leading-relaxed text-fd-muted-foreground md:text-lg"
|
||||
className="animate-stagger-item text-fd-muted-foreground max-w-md text-base leading-relaxed md:text-lg"
|
||||
style={{ "--stagger-index": 3 } as React.CSSProperties}
|
||||
>
|
||||
Sofa lives on your own server and seamlessly plugs into your
|
||||
existing home media stack.
|
||||
Sofa lives on your own server and seamlessly plugs into your existing home media stack.
|
||||
</p>
|
||||
|
||||
<div
|
||||
@@ -136,7 +134,7 @@ export default function HomePage() {
|
||||
>
|
||||
<Link
|
||||
href="/docs"
|
||||
className="inline-flex h-11 items-center rounded-lg bg-fd-primary px-7 text-sm font-medium text-fd-primary-foreground transition-shadow hover:shadow-lg hover:shadow-fd-primary/20"
|
||||
className="bg-fd-primary text-fd-primary-foreground hover:shadow-fd-primary/20 inline-flex h-11 items-center rounded-lg px-7 text-sm font-medium transition-shadow hover:shadow-lg"
|
||||
>
|
||||
Get Started
|
||||
</Link>
|
||||
@@ -144,7 +142,7 @@ export default function HomePage() {
|
||||
href="https://github.com/jakejarvis/sofa"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex h-11 items-center rounded-lg px-7 text-sm font-medium ring-1 ring-fd-border transition-colors hover:bg-fd-accent hover:ring-fd-primary/30"
|
||||
className="ring-fd-border hover:bg-fd-accent hover:ring-fd-primary/30 inline-flex h-11 items-center rounded-lg px-7 text-sm font-medium ring-1 transition-colors"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
@@ -160,12 +158,12 @@ export default function HomePage() {
|
||||
{features.map((feature, i) => (
|
||||
<div
|
||||
key={feature.title}
|
||||
className="animate-stagger-item rounded-xl bg-fd-card/50 p-6 ring-1 ring-white/[0.06]"
|
||||
className="animate-stagger-item bg-fd-card/50 rounded-xl p-6 ring-1 ring-white/[0.06]"
|
||||
style={{ "--stagger-index": i } as React.CSSProperties}
|
||||
>
|
||||
<feature.icon className="mb-3 size-5 text-fd-primary" />
|
||||
<h3 className="mb-1.5 font-display text-lg">{feature.title}</h3>
|
||||
<p className="text-sm leading-relaxed text-fd-muted-foreground">
|
||||
<feature.icon className="text-fd-primary mb-3 size-5" />
|
||||
<h3 className="font-display mb-1.5 text-lg">{feature.title}</h3>
|
||||
<p className="text-fd-muted-foreground text-sm leading-relaxed">
|
||||
{feature.description}
|
||||
</p>
|
||||
</div>
|
||||
@@ -176,7 +174,7 @@ export default function HomePage() {
|
||||
{/* ── Quick Start ── */}
|
||||
<section className="mx-auto w-full max-w-3xl px-6 pb-24">
|
||||
<h2
|
||||
className="animate-stagger-item mb-8 text-center font-display text-2xl md:text-3xl"
|
||||
className="animate-stagger-item font-display mb-8 text-center text-2xl md:text-3xl"
|
||||
style={{ "--stagger-index": 0 } as React.CSSProperties}
|
||||
>
|
||||
Deploy in minutes
|
||||
@@ -186,13 +184,11 @@ export default function HomePage() {
|
||||
{steps.map((s) => (
|
||||
<div
|
||||
key={s.step}
|
||||
className="animate-stagger-item rounded-xl bg-fd-card/50 p-5 ring-1 ring-white/[0.06]"
|
||||
style={
|
||||
{ "--stagger-index": Number(s.step) } as React.CSSProperties
|
||||
}
|
||||
className="animate-stagger-item bg-fd-card/50 rounded-xl p-5 ring-1 ring-white/[0.06]"
|
||||
style={{ "--stagger-index": Number(s.step) } as React.CSSProperties}
|
||||
>
|
||||
<div className="flex items-baseline gap-3">
|
||||
<span className="flex size-6 shrink-0 items-center justify-center rounded-full bg-fd-primary text-xs font-semibold text-fd-primary-foreground">
|
||||
<span className="bg-fd-primary text-fd-primary-foreground flex size-6 shrink-0 items-center justify-center rounded-full text-xs font-semibold">
|
||||
{s.step}
|
||||
</span>
|
||||
<h3 className="font-display text-base">{s.title}</h3>
|
||||
@@ -202,15 +198,15 @@ export default function HomePage() {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="mt-4 text-xs text-fd-muted-foreground flex items-center gap-1 mx-auto w-fit">
|
||||
<InfoIcon className="size-3 inline-block" />
|
||||
<p className="text-fd-muted-foreground mx-auto mt-4 flex w-fit items-center gap-1 text-xs">
|
||||
<InfoIcon className="inline-block size-3" />
|
||||
The first registered account becomes admin.
|
||||
</p>
|
||||
|
||||
<div className="mt-6 text-center">
|
||||
<Link
|
||||
href="/docs"
|
||||
className="text-sm text-fd-primary underline underline-offset-4 hover:text-fd-primary/80"
|
||||
className="text-fd-primary hover:text-fd-primary/80 text-sm underline underline-offset-4"
|
||||
>
|
||||
Read the full setup guide →
|
||||
</Link>
|
||||
|
||||
@@ -8,95 +8,75 @@ export const metadata: Metadata = {
|
||||
|
||||
export default function PrivacyPolicyPage() {
|
||||
return (
|
||||
<article className="prose prose-sm prose-invert mx-auto max-w-3xl px-6 py-16 [&_a]:text-fd-primary [&_a]:underline [&_a]:underline-offset-4 hover:[&_a]:text-fd-primary/80 [&_h2]:font-display [&_h2]:text-2xl [&_h2]:mt-10 [&_h2]:mb-4 [&_h2]:border-b [&_h2]:pb-2 [&_h3]:font-display [&_h3]:text-xl [&_h3]:mt-8 [&_h3]:mb-3 [&_p]:text-fd-muted-foreground [&_p]:text-[15px] [&_p]:leading-relaxed [&_li]:text-fd-muted-foreground [&_li]:text-[15px] [&_li]:leading-relaxed [&_ul]:space-y-1 [&_strong]:text-fd-foreground [&_strong]:font-medium">
|
||||
<h1 className="font-display text-3xl tracking-tight mb-2">
|
||||
Privacy Policy
|
||||
</h1>
|
||||
<p className="text-sm text-fd-muted-foreground/60 !mt-0 mb-8">
|
||||
Last updated: March 16, 2026
|
||||
</p>
|
||||
<article className="prose prose-sm prose-invert [&_a]:text-fd-primary hover:[&_a]:text-fd-primary/80 [&_h2]:font-display [&_h3]:font-display [&_p]:text-fd-muted-foreground [&_li]:text-fd-muted-foreground [&_strong]:text-fd-foreground mx-auto max-w-3xl px-6 py-16 [&_a]:underline [&_a]:underline-offset-4 [&_h2]:mt-10 [&_h2]:mb-4 [&_h2]:border-b [&_h2]:pb-2 [&_h2]:text-2xl [&_h3]:mt-8 [&_h3]:mb-3 [&_h3]:text-xl [&_li]:text-[15px] [&_li]:leading-relaxed [&_p]:text-[15px] [&_p]:leading-relaxed [&_strong]:font-medium [&_ul]:space-y-1">
|
||||
<h1 className="font-display mb-2 text-3xl tracking-tight">Privacy Policy</h1>
|
||||
<p className="text-fd-muted-foreground/60 !mt-0 mb-8 text-sm">Last updated: March 16, 2026</p>
|
||||
|
||||
<p>
|
||||
Sofa is a self-hosted application. When you run Sofa, your data lives on
|
||||
your own server and is under your control. This policy describes what
|
||||
data Sofa stores, what it sends externally, and how you can control it.
|
||||
Sofa is a self-hosted application. When you run Sofa, your data lives on your own server and
|
||||
is under your control. This policy describes what data Sofa stores, what it sends
|
||||
externally, and how you can control it.
|
||||
</p>
|
||||
|
||||
<h2>Data Stored on Your Server</h2>
|
||||
|
||||
<p>
|
||||
All of the following data is stored locally in a single SQLite database
|
||||
file on the machine running Sofa.
|
||||
All of the following data is stored locally in a single SQLite database file on the machine
|
||||
running Sofa.
|
||||
</p>
|
||||
|
||||
<h3>Account Information</h3>
|
||||
<ul>
|
||||
<li>Email address, display name, and hashed password</li>
|
||||
<li>Session tokens, IP address, and user agent string of active sessions</li>
|
||||
<li>
|
||||
Session tokens, IP address, and user agent string of active sessions
|
||||
</li>
|
||||
<li>
|
||||
If using OIDC/SSO: provider account IDs and OAuth tokens from your
|
||||
identity provider
|
||||
If using OIDC/SSO: provider account IDs and OAuth tokens from your identity provider
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Viewing Activity</h3>
|
||||
<ul>
|
||||
<li>
|
||||
Watchlist status (e.g. “watching”,
|
||||
“completed”) for movies and TV shows
|
||||
Watchlist status (e.g. “watching”, “completed”) for movies and TV
|
||||
shows
|
||||
</li>
|
||||
<li>Individual movie and episode watch timestamps</li>
|
||||
<li>Personal ratings</li>
|
||||
<li>
|
||||
Source of each watch event (manual entry, or imported from Plex,
|
||||
Jellyfin, or Emby)
|
||||
</li>
|
||||
<li>Source of each watch event (manual entry, or imported from Plex, Jellyfin, or Emby)</li>
|
||||
</ul>
|
||||
|
||||
<h3>Media Metadata</h3>
|
||||
<p>
|
||||
Movie, TV show, season, episode, and cast/crew metadata is fetched from{" "}
|
||||
<a
|
||||
href="https://www.themoviedb.org/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<a href="https://www.themoviedb.org/" target="_blank" rel="noopener noreferrer">
|
||||
The Movie Database (TMDB)
|
||||
</a>{" "}
|
||||
and cached locally. This includes titles, descriptions, images, genres,
|
||||
streaming availability, and related recommendations. No personal data is
|
||||
included in this metadata.
|
||||
and cached locally. This includes titles, descriptions, images, genres, streaming
|
||||
availability, and related recommendations. No personal data is included in this metadata.
|
||||
</p>
|
||||
|
||||
<h3>Backups</h3>
|
||||
<p>
|
||||
Manual and scheduled backups are full copies of the database stored on
|
||||
your server. They contain all of the data described above. Backup
|
||||
management (creation, download, deletion) requires admin authentication.
|
||||
Manual and scheduled backups are full copies of the database stored on your server. They
|
||||
contain all of the data described above. Backup management (creation, download, deletion)
|
||||
requires admin authentication.
|
||||
</p>
|
||||
|
||||
<h2>External Services</h2>
|
||||
|
||||
<p>
|
||||
Sofa communicates with the following external services during normal
|
||||
operation.
|
||||
</p>
|
||||
<p>Sofa communicates with the following external services during normal operation.</p>
|
||||
|
||||
<h3>The Movie Database (TMDB)</h3>
|
||||
<p>
|
||||
Your server makes API requests to TMDB to fetch and refresh movie and TV
|
||||
metadata. These requests include your TMDB API key and the IDs or search
|
||||
queries for titles being looked up. A single API key is used for the
|
||||
entire instance — TMDB cannot identify individual users. No
|
||||
personal data (watch history, ratings, etc.) is ever sent to TMDB.
|
||||
Your server makes API requests to TMDB to fetch and refresh movie and TV metadata. These
|
||||
requests include your TMDB API key and the IDs or search queries for titles being looked up.
|
||||
A single API key is used for the entire instance — TMDB cannot identify individual
|
||||
users. No personal data (watch history, ratings, etc.) is ever sent to TMDB.
|
||||
</p>
|
||||
<p>
|
||||
When the local image cache is enabled (the default), poster and backdrop
|
||||
images are downloaded from the TMDB CDN and served from your server.
|
||||
When disabled, images are loaded directly from TMDB’s CDN by the
|
||||
client.
|
||||
When the local image cache is enabled (the default), poster and backdrop images are
|
||||
downloaded from the TMDB CDN and served from your server. When disabled, images are loaded
|
||||
directly from TMDB’s CDN by the client.
|
||||
</p>
|
||||
|
||||
<h3>Sofa Public API</h3>
|
||||
@@ -104,78 +84,67 @@ export default function PrivacyPolicyPage() {
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Update checks</strong> — a periodic request to{" "}
|
||||
<code>public-api.sofa.watch</code> to check for new releases. Only a
|
||||
user agent string is sent; no instance or user data is included. Can
|
||||
be disabled in admin settings.
|
||||
<code>public-api.sofa.watch</code> to check for new releases. Only a user agent string is
|
||||
sent; no instance or user data is included. Can be disabled in admin settings.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Telemetry</strong> — an optional, anonymous report sent
|
||||
at most once every 24 hours. It includes a random instance ID, the
|
||||
Sofa version, CPU architecture, bucketed user and title counts (e.g.
|
||||
“2-5”), and which optional features are enabled. No
|
||||
personal data, watch history, or exact counts are included. Telemetry
|
||||
is <strong>disabled by default</strong> and must be explicitly enabled
|
||||
by an admin. See the{" "}
|
||||
<Link href="/docs/telemetry">telemetry documentation</Link> for full
|
||||
details.
|
||||
<strong>Telemetry</strong> — an optional, anonymous report sent at most once every
|
||||
24 hours. It includes a random instance ID, the Sofa version, CPU architecture, bucketed
|
||||
user and title counts (e.g. “2-5”), and which optional features are enabled.
|
||||
No personal data, watch history, or exact counts are included. Telemetry is{" "}
|
||||
<strong>disabled by default</strong> and must be explicitly enabled by an admin. See the{" "}
|
||||
<Link href="/docs/telemetry">telemetry documentation</Link> for full details.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>PostHog (Mobile App Only)</h3>
|
||||
<p>
|
||||
The native iOS and Android app includes optional, anonymous analytics
|
||||
powered by PostHog. This tracks screen views and app lifecycle events
|
||||
— no personal data, search queries, or watch history is collected.
|
||||
Analytics is <strong>disabled by default</strong> and requires explicit
|
||||
opt-in. On iOS, Apple’s App Tracking Transparency prompt is shown
|
||||
first. You can change your preference at any time in the app’s
|
||||
settings.
|
||||
The native iOS and Android app includes optional, anonymous analytics powered by PostHog.
|
||||
This tracks screen views and app lifecycle events — no personal data, search queries,
|
||||
or watch history is collected. Analytics is <strong>disabled by default</strong> and
|
||||
requires explicit opt-in. On iOS, Apple’s App Tracking Transparency prompt is shown
|
||||
first. You can change your preference at any time in the app’s settings.
|
||||
</p>
|
||||
|
||||
<h3>Media Server Integrations</h3>
|
||||
<p>
|
||||
If you connect Plex, Jellyfin, or Emby, those services send webhook
|
||||
events <em>to</em> your Sofa server when you finish watching something.
|
||||
This data is processed and stored locally. Sofa does not send data back
|
||||
to your media servers.
|
||||
If you connect Plex, Jellyfin, or Emby, those services send webhook events <em>to</em> your
|
||||
Sofa server when you finish watching something. This data is processed and stored locally.
|
||||
Sofa does not send data back to your media servers.
|
||||
</p>
|
||||
|
||||
<h3>Sonarr & Radarr</h3>
|
||||
<p>
|
||||
If you use Sonarr or Radarr integration, those services pull your
|
||||
watchlist from Sofa via authenticated API requests. Sofa does not push
|
||||
data to them.
|
||||
If you use Sonarr or Radarr integration, those services pull your watchlist from Sofa via
|
||||
authenticated API requests. Sofa does not push data to them.
|
||||
</p>
|
||||
|
||||
<h2>Cookies</h2>
|
||||
<p>
|
||||
Sofa uses a session cookie to keep you logged in. This cookie is
|
||||
HTTP-only, same-site, and contains only a session token. No third-party
|
||||
cookies are set by the web app.
|
||||
Sofa uses a session cookie to keep you logged in. This cookie is HTTP-only, same-site, and
|
||||
contains only a session token. No third-party cookies are set by the web app.
|
||||
</p>
|
||||
|
||||
<h2>Data Sharing</h2>
|
||||
<p>
|
||||
Because Sofa is self-hosted, there is no central service that has access
|
||||
to your data. The project maintainers have no access to your database,
|
||||
your watch history, or your account information. The only data that
|
||||
leaves your server is described in the{" "}
|
||||
Because Sofa is self-hosted, there is no central service that has access to your data. The
|
||||
project maintainers have no access to your database, your watch history, or your account
|
||||
information. The only data that leaves your server is described in the{" "}
|
||||
<a href="#external-services">External Services</a> section above.
|
||||
</p>
|
||||
|
||||
<h2>Data Retention & Deletion</h2>
|
||||
<p>
|
||||
All data is stored in a single SQLite file on your server. You have full
|
||||
control over it:
|
||||
All data is stored in a single SQLite file on your server. You have full control over it:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
Admin users can delete other user accounts, which cascades to all
|
||||
associated viewing history and ratings
|
||||
Admin users can delete other user accounts, which cascades to all associated viewing
|
||||
history and ratings
|
||||
</li>
|
||||
<li>
|
||||
Scheduled backups are automatically pruned after a configurable
|
||||
retention limit (default: 7)
|
||||
Scheduled backups are automatically pruned after a configurable retention limit (default:
|
||||
7)
|
||||
</li>
|
||||
<li>Sessions and verification tokens expire automatically</li>
|
||||
<li>Deleting the database file removes all data entirely</li>
|
||||
@@ -183,20 +152,15 @@ export default function PrivacyPolicyPage() {
|
||||
|
||||
<h2>Children</h2>
|
||||
<p>
|
||||
Sofa is not directed at children under 13. Since the application is
|
||||
self-hosted, account creation is controlled entirely by the server
|
||||
administrator.
|
||||
Sofa is not directed at children under 13. Since the application is self-hosted, account
|
||||
creation is controlled entirely by the server administrator.
|
||||
</p>
|
||||
|
||||
<h2>Open Source</h2>
|
||||
<p>
|
||||
Sofa is open source under the MIT License. You can audit exactly what
|
||||
data is collected and how it is handled by reviewing the{" "}
|
||||
<a
|
||||
href="https://github.com/jakejarvis/sofa"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Sofa is open source under the MIT License. You can audit exactly what data is collected and
|
||||
how it is handled by reviewing the{" "}
|
||||
<a href="https://github.com/jakejarvis/sofa" target="_blank" rel="noopener noreferrer">
|
||||
source code
|
||||
</a>
|
||||
.
|
||||
@@ -204,9 +168,8 @@ export default function PrivacyPolicyPage() {
|
||||
|
||||
<h2>Changes</h2>
|
||||
<p>
|
||||
This policy may be updated as new features are added. Changes will be
|
||||
reflected in the “Last updated” date above and committed to
|
||||
the repository.
|
||||
This policy may be updated as new features are added. Changes will be reflected in the
|
||||
“Last updated” date above and committed to the repository.
|
||||
</p>
|
||||
|
||||
<h2>Contact</h2>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createFromSource } from "fumadocs-core/search/server";
|
||||
|
||||
import { source } from "@/lib/source";
|
||||
|
||||
export const { GET } = createFromSource(source, {
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
import { createRelativeLink } from "fumadocs-ui/mdx";
|
||||
import type { Metadata } from "next";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import { getMDXComponents } from "@/components/mdx";
|
||||
import { gitConfig } from "@/lib/layout.shared";
|
||||
import { getPageImage, source } from "@/lib/source";
|
||||
@@ -23,10 +24,8 @@ export default async function Page(props: PageProps<"/docs/[[...slug]]">) {
|
||||
return (
|
||||
<DocsPage toc={page.data.toc} full={page.data.full}>
|
||||
<DocsTitle>{page.data.title}</DocsTitle>
|
||||
<DocsDescription className="mb-0">
|
||||
{page.data.description}
|
||||
</DocsDescription>
|
||||
<div className="flex flex-row gap-2 items-center border-b pb-6">
|
||||
<DocsDescription className="mb-0">{page.data.description}</DocsDescription>
|
||||
<div className="flex flex-row items-center gap-2 border-b pb-6">
|
||||
<MarkdownCopyButton markdownUrl={`${page.url}.mdx`} />
|
||||
<ViewOptionsPopover
|
||||
markdownUrl={`${page.url}.mdx`}
|
||||
@@ -49,9 +48,7 @@ export async function generateStaticParams() {
|
||||
return source.generateParams();
|
||||
}
|
||||
|
||||
export async function generateMetadata(
|
||||
props: PageProps<"/docs/[[...slug]]">,
|
||||
): Promise<Metadata> {
|
||||
export async function generateMetadata(props: PageProps<"/docs/[[...slug]]">): Promise<Metadata> {
|
||||
const params = await props.params;
|
||||
const page = source.getPage(params.slug);
|
||||
if (!page) notFound();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { DocsLayout } from "fumadocs-ui/layouts/docs";
|
||||
|
||||
import { baseOptions } from "@/lib/layout.shared";
|
||||
import { source } from "@/lib/source";
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import { getLLMText, source } from "@/lib/source";
|
||||
|
||||
export const revalidate = false;
|
||||
|
||||
export async function GET(
|
||||
_req: Request,
|
||||
{ params }: RouteContext<"/llms.mdx/docs/[[...slug]]">,
|
||||
) {
|
||||
export async function GET(_req: Request, { params }: RouteContext<"/llms.mdx/docs/[[...slug]]">) {
|
||||
const { slug } = await params;
|
||||
const page = source.getPage(slug);
|
||||
if (!page) notFound();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { llms } from "fumadocs-core/source";
|
||||
|
||||
import { source } from "@/lib/source";
|
||||
|
||||
export const revalidate = false;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ImageResponse } from "@takumi-rs/image-response";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import { getPageImage, source } from "@/lib/source";
|
||||
|
||||
export const revalidate = false;
|
||||
@@ -37,10 +38,7 @@ const PRIMARY = "#fba952";
|
||||
// oklch(0.63 0.02 80) → muted foreground
|
||||
const MUTED = "#90887c";
|
||||
|
||||
export async function GET(
|
||||
_req: Request,
|
||||
{ params }: RouteContext<"/og/docs/[...slug]">,
|
||||
) {
|
||||
export async function GET(_req: Request, { params }: RouteContext<"/og/docs/[...slug]">) {
|
||||
const { slug } = await params;
|
||||
const page = source.getPage(slug.slice(0, -1));
|
||||
if (!page) notFound();
|
||||
@@ -110,9 +108,7 @@ export async function GET(
|
||||
{title}
|
||||
</div>
|
||||
{description ? (
|
||||
<div style={{ fontSize: "24px", lineHeight: 1.5, color: MUTED }}>
|
||||
{description}
|
||||
</div>
|
||||
<div style={{ fontSize: "24px", lineHeight: 1.5, color: MUTED }}>{description}</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { createAPIPage } from "fumadocs-openapi/ui";
|
||||
|
||||
import { openapi } from "@/lib/openapi";
|
||||
|
||||
import client from "./api-page.client";
|
||||
|
||||
export const APIPage = createAPIPage(openapi, { client });
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
||||
import type { MDXComponents } from "mdx/types";
|
||||
|
||||
import { APIPage } from "@/components/api-page";
|
||||
|
||||
export function getMDXComponents(components?: MDXComponents) {
|
||||
|
||||
@@ -43,13 +43,10 @@ export function ScrollIndicator() {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className="absolute bottom-9 flex flex-col items-center gap-1.5 text-fd-muted-foreground transition-opacity duration-500"
|
||||
className="text-fd-muted-foreground absolute bottom-9 flex flex-col items-center gap-1.5 transition-opacity duration-500"
|
||||
style={{ opacity: shown && !scrolled && fits ? 1 : 0 }}
|
||||
>
|
||||
<ArrowDown
|
||||
className="size-7 animate-scroll-bounce stroke-2"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<ArrowDown className="animate-scroll-bounce size-7 stroke-2" aria-hidden="true" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
|
||||
|
||||
import { SofaLogo } from "@/components/sofa-logo";
|
||||
|
||||
export const gitConfig = {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { docs } from "collections/server";
|
||||
import { type InferPageType, loader } from "fumadocs-core/source";
|
||||
import { lucideIconsPlugin } from "fumadocs-core/source/lucide-icons";
|
||||
import { openapiPlugin } from "fumadocs-openapi/server";
|
||||
|
||||
import { docs } from "collections/server";
|
||||
|
||||
// See https://fumadocs.dev/docs/headless/source-api for more info
|
||||
export const source = loader({
|
||||
baseUrl: "/docs",
|
||||
|
||||
+1
-4
@@ -1,10 +1,7 @@
|
||||
import { isMarkdownPreferred, rewritePath } from "fumadocs-core/negotiation";
|
||||
import { type NextRequest, NextResponse } from "next/server";
|
||||
|
||||
const { rewrite: rewriteLLM } = rewritePath(
|
||||
"/docs{/*path}",
|
||||
"/llms.mdx/docs{/*path}",
|
||||
);
|
||||
const { rewrite: rewriteLLM } = rewritePath("/docs{/*path}", "/llms.mdx/docs{/*path}");
|
||||
|
||||
export default function proxy(request: NextRequest) {
|
||||
if (isMarkdownPreferred(request)) {
|
||||
|
||||
Reference in New Issue
Block a user