diff --git a/.github/workflows/ci-docs.yaml b/.github/workflows/ci-docs.yaml new file mode 100644 index 00000000..08f8f4fd --- /dev/null +++ b/.github/workflows/ci-docs.yaml @@ -0,0 +1,30 @@ +name: CI - Docs + +on: + pull_request: + push: + branches: + - main + +jobs: + ci-docs: + runs-on: ubuntu-latest + defaults: + run: + working-directory: packages/docs + + steps: + - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 + - run: corepack enable + - uses: actions/setup-node@v4 + with: + node-version: 22 + corepack: true + cache: 'pnpm' + + - name: Install dependencies + run: pnpm i + working-directory: ./ + + - name: Build the lib + run: pnpm build diff --git a/.gitignore b/.gitignore index 64b285d8..afdd4882 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,5 @@ logs !.env.example .wrangler -coverage \ No newline at end of file +coverage +cache \ No newline at end of file diff --git a/packages/app-client/.env.example b/packages/app-client/.env.example index 484dafa4..576f314e 100644 --- a/packages/app-client/.env.example +++ b/packages/app-client/.env.example @@ -1 +1,2 @@ -VITE_BASE_API_URL=http://localhost:8787 \ No newline at end of file +VITE_BASE_API_URL=http://localhost:8787 +VITE_FALLBACK_DOCUMENTATION_URL=http://localhost:3001 \ No newline at end of file diff --git a/packages/app-client/.gitignore b/packages/app-client/.gitignore index ff044969..ba6e890d 100644 --- a/packages/app-client/.gitignore +++ b/packages/app-client/.gitignore @@ -26,3 +26,5 @@ gitignore # System Files .DS_Store Thumbs.db + +cache \ No newline at end of file diff --git a/packages/app-client/public/robots.txt b/packages/app-client/public/robots.txt index a0c0cac9..e2f49e2c 100644 --- a/packages/app-client/public/robots.txt +++ b/packages/app-client/public/robots.txt @@ -1,4 +1,5 @@ User-agent: * Disallow: / Allow: /$ -Allow: /og-image.png \ No newline at end of file +Allow: /og-image.png +Allow: /docs/ \ No newline at end of file diff --git a/packages/app-client/src/modules/config/config.ts b/packages/app-client/src/modules/config/config.ts index de7675b3..2ad8baf6 100644 --- a/packages/app-client/src/modules/config/config.ts +++ b/packages/app-client/src/modules/config/config.ts @@ -1,3 +1,4 @@ export const config = { baseApiUrl: import.meta.env.VITE_BASE_API_URL ?? window.location.origin, + documentationBaseUrl: import.meta.env.VITE_DOCUMENTATION_BASE_URL ?? 'https://docs.enclosed.cc', }; diff --git a/packages/app-client/src/modules/docs/docs.models.test.ts b/packages/app-client/src/modules/docs/docs.models.test.ts new file mode 100644 index 00000000..4ff1f6c2 --- /dev/null +++ b/packages/app-client/src/modules/docs/docs.models.test.ts @@ -0,0 +1,41 @@ +import { describe, expect, test } from 'vitest'; +import { buildDocUrl, joinUrlParts } from './docs.models'; + +describe('docs models', () => { + describe('buildDocUrl', () => { + test('it creates a url to the documentation', () => { + expect( + buildDocUrl({ + path: '/test', + + baseUrl: 'https://docs.enclosed.cc', + }), + ).to.eql('https://docs.enclosed.cc/test'); + }); + + test('it uses the default base url', () => { + expect(buildDocUrl({ path: '/test' })).to.eql('https://docs.enclosed.cc/test'); + }); + + test('it handles clashing slashes', () => { + expect( + buildDocUrl({ + path: '/test', + baseUrl: 'https://docs.enclosed.cc/', + }), + ).to.eql('https://docs.enclosed.cc/test'); + }); + }); + + describe('joinUrlParts', () => { + test('it merges url parts and trim slashes', () => { + expect(joinUrlParts('/part1/', '/part2/', 'part3', 'part4/')).to.eql('part1/part2/part3/part4'); + expect(joinUrlParts('/part1/part2/', 'part3', 'part4/')).to.eql('part1/part2/part3/part4'); + expect(joinUrlParts('')).to.eql(''); + }); + + test('multiple slashes inside a part are preserved', () => { + expect(joinUrlParts('/part1//part2/', '/part3/')).to.eql('part1//part2/part3'); + }); + }); +}); diff --git a/packages/app-client/src/modules/docs/docs.models.ts b/packages/app-client/src/modules/docs/docs.models.ts new file mode 100644 index 00000000..6e99ca14 --- /dev/null +++ b/packages/app-client/src/modules/docs/docs.models.ts @@ -0,0 +1,19 @@ +import { config } from '../config/config'; + +export { buildDocUrl, joinUrlParts }; + +function joinUrlParts(...parts: string[]): string { + return parts.map(part => part.replace(/(^\/|\/$)/g, '')).join('/'); +} + +function buildDocUrl({ + path, + baseUrl = config.documentationBaseUrl, +}: { + path: string; + baseUrl?: string; +}): string { + const url = joinUrlParts(baseUrl, path); + + return url; +} diff --git a/packages/app-client/src/modules/ui/layouts/app.layout.tsx b/packages/app-client/src/modules/ui/layouts/app.layout.tsx index abe8e322..f3cced67 100644 --- a/packages/app-client/src/modules/ui/layouts/app.layout.tsx +++ b/packages/app-client/src/modules/ui/layouts/app.layout.tsx @@ -1,10 +1,11 @@ import { A, useNavigate } from '@solidjs/router'; import type { Component, ParentComponent } from 'solid-js'; import { DropdownMenu } from '@kobalte/core/dropdown-menu'; -import { DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '../components/dropdown-menu'; +import { DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from '../components/dropdown-menu'; import { Button } from '@/modules/ui/components/button'; import { useThemeStore } from '@/modules/theme/theme.store'; import { useNoteContext } from '@/modules/notes/notes.context'; +import { buildDocUrl } from '@/modules/docs/docs.models'; export const Navbar: Component = () => { const themeStore = useThemeStore(); @@ -43,21 +44,48 @@ export const Navbar: Component = () => {
- - themeStore.setColorMode({ mode: 'light' })} class="flex items-center gap-2"> + + themeStore.setColorMode({ mode: 'light' })} class="flex items-center gap-2 cursor-pointer">
Light mode
- themeStore.setColorMode({ mode: 'dark' })} class="flex items-center gap-2"> + themeStore.setColorMode({ mode: 'dark' })} class="flex items-center gap-2 cursor-pointer">
Dark mode
- themeStore.setColorMode({ mode: 'system' })} class="flex items-center gap-2"> + themeStore.setColorMode({ mode: 'system' })} class="flex items-center gap-2 cursor-pointer">
System
+ + + +
+
+ + + +
+ Documentation +
+ + +
+ Enclosed CLI +
+ + + + +
+ Support Enclosed +
+ +
+ +
diff --git a/packages/docs/.vitepress/config.ts b/packages/docs/.vitepress/config.ts new file mode 100644 index 00000000..d8055538 --- /dev/null +++ b/packages/docs/.vitepress/config.ts @@ -0,0 +1,135 @@ +import { defineConfig } from 'vitepress'; +import { getPlausibleScripts } from './plausible'; + +const basePath = process.env.DOCS_BASE_PATH; // undefined for root / + +const createAbsoluteUrl = (path: string) => 'https://enclosed.cc/' + path.replace(/(^\/$)/g, ''); + +// https://vitepress.dev/reference/site-config +export default defineConfig({ + title: 'Enclosed', + description: 'Send private and secure notes', + base: basePath, + lang: 'en-US', + lastUpdated: true, + srcDir: './src', + outDir: './dist', + + markdown: { + theme: { + dark: 'github-dark', + light: 'github-light', + }, + }, + + head: [ + ['meta', { name: 'author', content: 'Corentin Thomasset' }], + ['meta', { name: 'keywords', content: 'Enclosed, notes, secure, private, encrypted, self-hosted' }], + ['link', { rel: 'icon', href: '/favicon.ico' }], + ['link', { rel: 'apple-touch-icon', href: '/apple-touch-icon.png' }], + ['link', {rel: 'icon', type: 'image/png', sizes: '32x32', href: '/favicon-32x32.png'}], + ['link', {rel: 'icon', type: 'image/png', sizes: '16x16', href: '/favicon-16x16.png'}], + + ['meta', {name: 'theme-color', content: '#ffffff'}], + + + + ['meta', {name: 'og:title', content: 'Enclosed documentation'}], + ['meta', {name: 'og:description', content: 'Send private and secure notes'}], + ['meta', {name: 'og:image', content: createAbsoluteUrl('og-image.png')}], + ['meta', {name: 'og:url', content: 'https://enclosed.cc'}], + ['meta', {name: 'og:type', content: 'website'}], + ['meta', {name: 'og:site_name', content: 'Enclosed'}], + ['meta', {name: 'og:locale', content: 'en_US'}], + + ['meta', {name: 'twitter:card', content: 'summary'}], + ['meta', {name: 'twitter:site', content: '@cthmsst'}], + ['meta', {name: 'twitter:creator', content: '@cthmsst'}], + ['meta', {name: 'twitter:title', content: 'Enclosed documentation'}], + ['meta', {name: 'twitter:description', content: 'Send private and secure notes'}], + ['meta', {name: 'twitter:image', content: createAbsoluteUrl('og-image.png')}], + + ...getPlausibleScripts(), + ], + + themeConfig: { + + logo: { + light: '/logo-light.svg', + dark: '/logo-dark.svg', + alt: 'Logo', + }, + + siteTitle: 'Enclosed - DOCS', + + // https://vitepress.dev/reference/default-theme-config + nav: [ + { text: 'Enclosed App', link: 'https://enclosed.cc' }, + ], + + sidebar: [ + { + text: 'Enclosed', + items: [ + { text: 'Introduction', link: '/' }, + { text: 'How it works?', link: '/how-it-works' }, + ], + }, + { + text: 'Self hosting', + items: [ + { text: 'Using Docker', link: '/self-hosting/docker' }, + { text: 'Using Docker Compose', link: '/self-hosting/docker-compose' }, + { text: 'Configuration', link: '/self-hosting/configuration' }, + ], + }, + { + text: 'Integrations', + items: [ + { text: 'CLI', link: '/integrations/cli' }, + { text: 'NPM package', link: '/integrations/npm-package' }, + ] + }, + ], + + + footer: { + copyright: 'Copyright © 2024-present Corentin Thomasset', + }, + + editLink: { + pattern: 'https://github.com/CorentinTh/enclosed/edit/main/packages/docs/src/:path', + text: 'Edit this page on GitHub', + }, + + socialLinks: [ + { icon: 'github', link: 'https://github.com/CorentinTh/enclosed', ariaLabel: 'GitHub' }, + { icon: 'twitter', link: 'https://twitter.com/cthmsst', ariaLabel: 'Twitter' }, + ], + + search: { + provider: 'local', + + options: { + detailedView: true, + + miniSearch: { + /** + * @type {Pick} + */ + options: { + }, + /** + * @type {import('minisearch').SearchOptions} + */ + searchOptions: { + fuzzy: 0.3, + prefix: true, + boost: { title: 4, text: 2, titles: 1 }, + }, + }, + }, + }, + }, +}); + \ No newline at end of file diff --git a/packages/docs/.vitepress/plausible.ts b/packages/docs/.vitepress/plausible.ts new file mode 100644 index 00000000..49ca2be8 --- /dev/null +++ b/packages/docs/.vitepress/plausible.ts @@ -0,0 +1,17 @@ +import { HeadConfig } from "vitepress"; + +const isPlausibleEnabled = process.env.VITE_IS_PLAUSIBLE_ENABLED === 'true'; +const plausibleDomain = String(process.env.VITE_PLAUSIBLE_DOMAIN); +const plausibleScriptSrc = String(process.env.VITE_PLAUSIBLE_SCRIPT_SRC); + +export { getPlausibleScripts }; + +function getPlausibleScripts(): HeadConfig[] { + if (!isPlausibleEnabled || !plausibleDomain) { + return []; + } + + return [ + ['script', { async: '', defer: '', 'data-domain': plausibleDomain, src: plausibleScriptSrc }], + ]; +} \ No newline at end of file diff --git a/packages/docs/.vitepress/theme/custom.css b/packages/docs/.vitepress/theme/custom.css new file mode 100644 index 00000000..7fa5205c --- /dev/null +++ b/packages/docs/.vitepress/theme/custom.css @@ -0,0 +1,19 @@ +:root { + --vp-c-brand-1: #000000; + --vp-c-brand-2: #000000; +} + +.dark { + --vp-c-brand-1: #ffffff; + --vp-c-brand-2: #ffffff; + + --vp-c-text-1: rgba(255, 255, 245, 0.92); + --vp-c-text-2: rgba(235, 235, 245, 0.6); + --vp-c-text-3: rgba(235, 235, 245, 0.38); +} + + +.VPSocialLink span{ + height: 18px !important; + width: 18px !important; +} \ No newline at end of file diff --git a/packages/docs/.vitepress/theme/index.js b/packages/docs/.vitepress/theme/index.js new file mode 100644 index 00000000..508d8b4a --- /dev/null +++ b/packages/docs/.vitepress/theme/index.js @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme \ No newline at end of file diff --git a/packages/docs/package.json b/packages/docs/package.json new file mode 100644 index 00000000..6fb6b83f --- /dev/null +++ b/packages/docs/package.json @@ -0,0 +1,23 @@ +{ + "name": "@enclosed/docs", + "version": "0.0.0", + "type": "module", + "packageManager": "pnpm@9.9.0", + "description": "Documentation website for Enclosed.", + "author": "Corentin Thomasset (https://corentin.tech)", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/CorentinTh/enclosed" + }, + "main": "index.js", + "scripts": { + "dev": "vitepress dev --port 3001", + "build": "vitepress build", + "preview": "vitepress preview" + }, + "keywords": [], + "devDependencies": { + "vitepress": "^1.3.4" + } +} \ No newline at end of file diff --git a/packages/docs/src/how-it-works.md b/packages/docs/src/how-it-works.md new file mode 100644 index 00000000..b7c18faf --- /dev/null +++ b/packages/docs/src/how-it-works.md @@ -0,0 +1,59 @@ +--- +outline: deep +--- + +# How It Works + +Enclosed is designed with a focus on security and privacy, ensuring that your notes remain confidential from creation to retrieval. This section explains the entire process, from creating a note to decrypting it, highlighting the end-to-end encryption that makes Enclosed a secure platform. + +## 1. Note Creation + +When you create a note, you enter your content and, optionally, set a password. This step is performed entirely on the client side, meaning your data never leaves your device in an unencrypted form. + +## 2. Key Generation + +A **base key** is generated on your device. This key is crucial for the encryption process and ensures that even if no password is set, your note remains secure. The base key is unique and is not known to the server. + +## 3. Master Key Derivation + +If you set a password, a **master key** is derived from the combination of the base key and your password using **PBKDF2 with SHA-256**. This process adds an additional layer of security, ensuring that only someone with the correct password can decrypt the note. + +## 4. Note Encryption + +Your note is encrypted using the master key with **AES-GCM** encryption. AES-GCM (Advanced Encryption Standard in Galois/Counter Mode) is a highly secure encryption method that provides both confidentiality and integrity for your data. + +## 5. Sending to Server + +The encrypted note, along with some metadata (such as the expiration time and whether the note should self-destruct after reading), is sent to the server. Importantly, the server only stores the encrypted note and metadata; it never has access to the content of the note or the keys used to encrypt it. + +## 6. Storage and ID Assignment + +The server stores the encrypted note and assigns it a unique **ID**. This ID is used to retrieve the note later. Because the note is encrypted before it reaches the server, even if the server is compromised, your note remains secure. + +## 7. Link Generation + +A **link** is generated that contains the note ID and the base key as a URL hash fragment. The URL hash fragment (everything after the `#`) is never sent to the server, making it a secure way to transmit the key needed for decryption. + +## 8. Link Sharing + +You share this link with the intended recipient. The security of the note relies on the secrecy of the link, as it contains the necessary information to decrypt the note. + +## 9. Note Retrieval + +When the recipient opens the link, the application fetches the encrypted note and its metadata from the server using the note ID. The base key, which was included in the URL hash fragment, remains on the client side. + +## 10. Key Extraction + +The base key is extracted from the URL hash fragment. Since this fragment was never sent to the server, the key remains secure and is only available to the recipient. + +## 11. Password Prompt (If Applicable) + +If the note is password-protected, the recipient is prompted to enter the password. This step ensures that only authorized users can decrypt the note. + +## 12. Master Key Derivation + +If a password was set, the master key is derived from the base key and the entered password using PBKDF2 with SHA-256. This process ensures that the recipient has the correct key to decrypt the note. + +## 13. Note Decryption + +The note is decrypted using the master key with AES-GCM encryption. Once decrypted, the recipient can read the note. diff --git a/packages/docs/src/index.md b/packages/docs/src/index.md new file mode 100644 index 00000000..9760c932 --- /dev/null +++ b/packages/docs/src/index.md @@ -0,0 +1,31 @@ +--- +outline: deep +--- + +# Enclosed + +**Enclosed** is a minimalistic web application designed for sending private and secure notes. Whether you need to share sensitive information or just want a simple way to send encrypted messages, Enclosed provides a user-friendly interface with strong security features to ensure your data remains confidential. + +The name **Enclosed** is inspired by the idea of keeping your notes safe and secure, like a sealed envelope. + +## Key Features + +- **End-to-End Encryption**: All notes are encrypted on the client side using AES-GCM with a 256-bit key, ensuring that only the intended recipient can read them. +- **Zero Knowledge**: The server does not have access to the content of your notes, making it impossible for anyone else to decrypt them. +- **Configurable Security**: Users can set a password, define an expiration period (TTL), and choose to have the note self-destruct after being read. +- **Minimalistic UI**: Enclosed's interface is simple and intuitive, allowing for quick and easy note sharing. +- **Dark Mode**: Enjoy a dark theme for comfortable usage, especially in low-light environments. +- **Responsive Design**: The application works seamlessly on all devices, from desktops to mobile phones. +- **Open Source**: The source code is available under the Apache 2.0 License, allowing for community contributions and self-hosting. +- **Self-Hostable**: Run your instance of Enclosed to maintain complete control over your note-sharing environment. +- **CLI**: A command-line interface is available for creating and managing notes directly from your terminal. + +## Why Enclosed? + +In a world where privacy is increasingly hard to maintain, Enclosed offers a secure way to share notes that prioritize your privacy and security. Whether you are communicating sensitive information or simply value the confidentiality of your messages, Enclosed ensures that your data stays between you and the intended recipient. + +By leveraging client-side encryption and a zero-knowledge server, Enclosed guarantees that your notes are safe from prying eyes. Even if the server is compromised, your data remains secure and unreadable by anyone without the correct decryption key. + +## Get Started + +Ready to start using Enclosed? You can [try it out online](https://enclosed.cc) or [self-host](./self-hosting/docker) your instance for maximum control. Dive into our documentation to learn more about how Enclosed works and how you can take full advantage of its features. diff --git a/packages/docs/src/integrations/cli.md b/packages/docs/src/integrations/cli.md new file mode 100644 index 00000000..1879c87c --- /dev/null +++ b/packages/docs/src/integrations/cli.md @@ -0,0 +1,160 @@ +# CLI Guide + +The Enclosed Command-Line Interface (CLI) allows you to create and manage secure notes directly from your terminal. This guide will walk you through installing the CLI, creating and viewing notes, and configuring the CLI for different use cases. + +## Installation + +You can install the Enclosed CLI globally using npm, yarn, or pnpm. + +### Using npm + +```bash +npm install -g @enclosed/cli +``` + +### Using yarn + +```bash +yarn global add @enclosed/cli +``` + +### Using pnpm + +```bash +pnpm add -g @enclosed/cli +``` + +Once installed, you can use the `enclosed` command in your terminal. + +## Creating a Note + +The primary function of the Enclosed CLI is to create secure notes. You can create a note with a simple command. + +### Basic Usage + +To create a note with the content "Hello, World!", run: + +```bash +enclosed create "Hello, World!" +``` + +This command will return a URL that you can share with the intended recipient. + +### Using stdin + +You can also create a note from the contents of a file or the output of another command: + +```bash +cat file.txt | enclosed create +``` + +This is useful for sending longer text or data generated by other commands. + +### With Full Options + +The CLI allows you to set additional security options such as password protection, self-destruction after reading, and time-to-live (TTL) for the note: + +```bash +enclosed create --deleteAfterReading --password "mypassword" --ttl 3600 "This is a secure message." +``` +### Options Summary + +- `--deleteAfterReading`: Enable self-destruction after the note is read. +- `--password `: Protect the note with a password. +- `--ttl `: Set the time-to-live (TTL) for the note in seconds. + +## Viewing a Note + +The Enclosed CLI can also be used to view notes directly from the terminal. + +### Basic Usage + +To view a note, use the `view` command followed by the note's URL: + +```bash +enclosed view +``` + +If the note is password-protected, the CLI will prompt you for the password. + +### Providing the Password Directly + +You can provide the password directly with the `--password` option to avoid the prompt: + +```bash +enclosed view --password "mypassword" +``` + +## Configuring the Enclosed Instance + +By default, the CLI uses the public instance at [enclosed.cc](https://enclosed.cc). If you are running your own instance of Enclosed, you can configure the CLI to use your server. + +### Set the Instance URL + +To set your instance URL, run: + +```bash +enclosed config set instance-url https://your-enclosed-instance.com +``` + +This command will configure the CLI to use your instance for creating and viewing notes. + +## Updating the CLI + +To update the Enclosed CLI to the latest version, simply re-run the installation command: + +### Using npm + +```bash +npm install -g @enclosed/cli +``` + +### Using yarn + +```bash +yarn global add @enclosed/cli +``` + +### Using pnpm + +```bash +pnpm add -g @enclosed/cli +``` + +This will ensure that you have the latest features and security updates. + +## Uninstalling the CLI + +If you need to remove the Enclosed CLI, you can uninstall it with the following commands: + +### Using npm + +```bash +npm uninstall -g @enclosed/cli +``` + +### Using yarn + +```bash +yarn global remove @enclosed/cli +``` + +### Using pnpm + +```bash +pnpm remove -g @enclosed/cli +``` + +## Advanced Usage + +For more advanced usage, you can refer to the CLI's help command, which provides detailed information on all available commands and options: + +```bash +enclosed --help +``` + +This will display the complete list of commands and options available in the Enclosed CLI. + +## Next Steps + +Now that you're familiar with the basic and advanced features of the Enclosed CLI, you can start integrating it into your workflows. Whether you're automating note creation or managing secure communication from the terminal, the Enclosed CLI is a powerful tool for ensuring your messages remain private and secure. diff --git a/packages/docs/src/integrations/npm-package.md b/packages/docs/src/integrations/npm-package.md new file mode 100644 index 00000000..2885d881 --- /dev/null +++ b/packages/docs/src/integrations/npm-package.md @@ -0,0 +1,32 @@ +# NPM Package + +::: warning +This documentation is a work in progress. +::: + +The Enclosed lib is available as an npm package. You can use it to create and manage Enclosed notes. + +## Installation + +You can install the Enclosed Lib using npm, yarn, or pnpm. + +### Using npm + +```bash +npm install -g @enclosed/lib +``` + +### Using yarn + +```bash +yarn global add @enclosed/lib +``` + +### Using pnpm + +```bash +pnpm add -g @enclosed/lib +``` + + + diff --git a/packages/docs/src/public/apple-touch-icon.png b/packages/docs/src/public/apple-touch-icon.png new file mode 100644 index 00000000..bcb28fbf Binary files /dev/null and b/packages/docs/src/public/apple-touch-icon.png differ diff --git a/packages/docs/src/public/favicon-16x16.png b/packages/docs/src/public/favicon-16x16.png new file mode 100644 index 00000000..e7dccdb6 Binary files /dev/null and b/packages/docs/src/public/favicon-16x16.png differ diff --git a/packages/docs/src/public/favicon-32x32.png b/packages/docs/src/public/favicon-32x32.png new file mode 100644 index 00000000..84c4f227 Binary files /dev/null and b/packages/docs/src/public/favicon-32x32.png differ diff --git a/packages/docs/src/public/favicon.ico b/packages/docs/src/public/favicon.ico new file mode 100644 index 00000000..ff93a47c Binary files /dev/null and b/packages/docs/src/public/favicon.ico differ diff --git a/packages/docs/src/public/humans.txt b/packages/docs/src/public/humans.txt new file mode 100644 index 00000000..e2d90924 --- /dev/null +++ b/packages/docs/src/public/humans.txt @@ -0,0 +1,4 @@ +/* TEAM */ +Developer: Corentin Thomasset +Site: https://corentin.tech +Twitter: @cthmsst \ No newline at end of file diff --git a/packages/docs/src/public/logo-dark.svg b/packages/docs/src/public/logo-dark.svg new file mode 100644 index 00000000..c9003115 --- /dev/null +++ b/packages/docs/src/public/logo-dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/src/public/logo-light.svg b/packages/docs/src/public/logo-light.svg new file mode 100644 index 00000000..ff063dae --- /dev/null +++ b/packages/docs/src/public/logo-light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/docs/src/public/og-image.png b/packages/docs/src/public/og-image.png new file mode 100644 index 00000000..0400fd1f Binary files /dev/null and b/packages/docs/src/public/og-image.png differ diff --git a/packages/docs/src/public/robots.txt b/packages/docs/src/public/robots.txt new file mode 100644 index 00000000..6f27bb66 --- /dev/null +++ b/packages/docs/src/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: \ No newline at end of file diff --git a/packages/docs/src/self-hosting/configuration.md b/packages/docs/src/self-hosting/configuration.md new file mode 100644 index 00000000..c312bbcc --- /dev/null +++ b/packages/docs/src/self-hosting/configuration.md @@ -0,0 +1,39 @@ +# Self-Host Configuration + +Configuring your self-hosted instance of Enclosed allows you to customize the application to better suit your environment and requirements. This guide covers the key environment variables you can set to control various aspects of the application, including port settings, security options, and storage configurations. + +## Environment Variables + +Enclosed is configured primarily through environment variables. Below is a list of the available variables, along with their descriptions and default values. + +| Environment Variable | Description | Default Value | +| -------------------- | ----------- | ------------- | +| `PORT` | The port to listen on when using node server | `8787` | +| `SERVER_API_ROUTES_TIMEOUT_MS` | The maximum time in milliseconds for a route to complete before timing out | `5000` | +| `SERVER_CORS_ORIGINS` | The CORS origin for the api server | _No default value_ | +| `NOTES_MAX_ENCRYPTED_CONTENT_LENGTH` | The maximum length of the encrypted content of a note allowed by the api | `5242880` | +| `TASK_DELETE_EXPIRED_NOTES_ENABLED` | Whether to enable a periodic task to delete expired notes (not available for cloudflare) | `true` | +| `TASK_DELETE_EXPIRED_NOTES_CRON` | The frequency with which to run the task to delete expired notes (cron syntax) | `0 * * * *` | +| `TASK_DELETE_EXPIRED_NOTES_RUN_ON_STARTUP` | Whether the task to delete expired notes should run on startup | `true` | +| `STORAGE_DRIVER_FS_LITE_PATH` | (only in node env) The path to the directory where the data will be stored | `./.data` | +| `STORAGE_DRIVER_CLOUDFLARE_KV_BINDING` | (only in cloudflare env) The name of the Cloudflare KV binding to use | `notes` | + +## Applying Configuration Changes + +To apply your configuration changes, ensure that you have exported the environment variables in your shell or included them in your environment configuration file. Then, restart your Enclosed instance to apply the changes. + +For Docker deployments, you can pass the environment variables directly when running the container: + +```bash +docker run \ + -d --name enclosed \ + --restart unless-stopped \ + -p 8787:8787 \ + -v /path/to/local/data:/app/.data \ + -e SERVER_CORS_ORIGINS="https://example.com" \ + ghcr.io/corentin-th/enclosed +``` + +## Next Steps + +Once your instance is configured, you can proceed to explore advanced deployment options or set up monitoring to ensure your Enclosed instance runs smoothly. For a more complex setup, consider using [Docker Compose](./docker-compose) or deploying on a cloud provider. diff --git a/packages/docs/src/self-hosting/docker-compose.md b/packages/docs/src/self-hosting/docker-compose.md new file mode 100644 index 00000000..25bd6a15 --- /dev/null +++ b/packages/docs/src/self-hosting/docker-compose.md @@ -0,0 +1,119 @@ +# Docker Compose Installation + +Using Docker Compose allows you to define and manage multi-container Docker applications. For Enclosed, Docker Compose simplifies the process of setting up and maintaining the application, especially when you want to include additional services or need persistent storage. + +## Prerequisites + +Ensure that you have Docker and Docker Compose installed on your system. You can install Docker Compose by following the instructions on the [official Docker Compose website](https://docs.docker.com/compose/install/). + +## Docker Compose Configuration + +Below is a sample `docker-compose.yml` file that you can use to deploy Enclosed. This configuration includes options for persistent storage and automatic restart. + +```yaml +version: '3.8' + +services: + enclosed: + image: corentinth/enclosed + container_name: enclosed + ports: + - '8787:8787' + volumes: + - enclosed-data:/app/.data + restart: unless-stopped + +volumes: + enclosed-data: + driver: local +``` + +### Explanation of the Configuration + +- **version**: Specifies the version of Docker Compose file format. +- **services**: Defines the services that will be run. In this case, only the `enclosed` service is defined. +- **image**: Specifies the Docker image to use for the `enclosed` service. +- **container_name**: Names the container "enclosed" for easy identification. +- **ports**: Maps port 8787 on your host to port 8787 in the container, making the application accessible on your local machine. +- **volumes**: + - `enclosed-data:/app/.data`: Maps a local volume to the container's data directory for persistent storage. +- **environment**: Defines environment variables to configure the Enclosed instance. You can adjust these values according to your needs. +- **restart**: Configures the container to always restart unless it is explicitly stopped. + +### Persistent Storage + +The `volumes` section in the `docker-compose.yml` file maps a named volume (`enclosed-data`) to the container’s data directory. This ensures that your data is not lost when the container is stopped or removed. + +### Customizing the Environment + +You can modify the environment variables under the `environment` section to customize your instance. For example, you can change the `PORT`, set different CORS origins, or adjust the note size limit. + +## Running Enclosed with Docker Compose + +Once you have your `docker-compose.yml` file configured, you can start the Enclosed service with the following commands: + +### Download the Docker Compose File + +You can download the `docker-compose.yml` file directly from the repository: + +```bash +curl -O https://raw.githubusercontent.com/CorentinTh/enclosed/main/docker-compose.yml +``` + +### Start the Service + +To start Enclosed using Docker Compose, run: + +```bash +docker-compose up -d +``` + +- `-d`: Runs the containers in detached mode (in the background). + +This command will pull the Enclosed image if it is not already available locally, create the container, and start the application. + +### Managing the Service + +#### View Logs + +To view the logs for the Enclosed service, run: + +```bash +docker-compose logs -f enclosed +``` + +#### Stop the Service + +To stop the Enclosed service, use: + +```bash +docker-compose down +``` + +This will stop and remove the container, but your data will be preserved in the volume. + +#### Restart the Service + +If you make changes to the `docker-compose.yml` file or environment variables, you can restart the service with: + +```bash +docker-compose down +docker-compose up -d +``` + +## Updating Enclosed + +To update your Enclosed instance to the latest version, pull the latest image and restart the service: + +```bash +docker-compose pull enclosed +docker-compose up -d +``` + +## Advanced Configuration + +If you want to include additional services (like a reverse proxy or database) or manage more complex deployments, you can expand the `docker-compose.yml` file accordingly. Docker Compose allows for flexibility in defining multi-container applications, making it a powerful tool for managing your Enclosed instance. + +## Next Steps + +Once your Enclosed instance is up and running with Docker Compose, you can explore further customization options, integrate with other services, or set up monitoring and backups to ensure the smooth operation of your deployment. diff --git a/packages/docs/src/self-hosting/docker.md b/packages/docs/src/self-hosting/docker.md new file mode 100644 index 00000000..8950ce5d --- /dev/null +++ b/packages/docs/src/self-hosting/docker.md @@ -0,0 +1,107 @@ +--- +outline: deep +--- + +# Docker Installation + +Enclosed can be easily installed and run using Docker. This method is recommended for users who want a quick and straightforward way to deploy their own instance of Enclosed with minimal setup. + +## Prerequisites + +Before you begin, ensure that you have Docker installed on your system. You can download and install Docker from the [official Docker website](https://www.docker.com/get-started). + +## Basic Docker Run + +To run Enclosed using Docker, you can use the following command: + +From Docker Hub +```bash +docker run -d --name enclosed --restart unless-stopped -p 8787:8787 corentinth/enclosed +``` + +From GitHub Container Registry +```bash +docker run -d --name enclosed --restart unless-stopped -p 8787:8787 ghcr.io/corentin-th/enclosed +``` + +This command will download the Enclosed image and start the application, making it accessible at `http://localhost:8787`. + +### Explanation of the Command + +- `-d`: Runs the container in detached mode (in the background). +- `--name enclosed`: Names the container "enclosed" for easy identification. +- `--restart unless-stopped`: Configures the container to always restart unless it is explicitly stopped. +- `-p 8787:8787`: Maps port 8787 on your host to port 8787 in the container, making the application accessible on your local machine. +- `corentinth/enclosed` or `ghcr.io/corentin-th/enclosed`: Specifies the Docker image to use. + +## Docker with Volume Persistence + +To ensure that your notes and settings are preserved even if the container is stopped or removed, you can run Enclosed with volume persistence. Replace `/path/to/local/data` with the path to your local data directory: + +From Docker Hub: +```bash +docker run -d --name enclosed --restart unless-stopped -p 8787:8787 -v /path/to/local/data:/app/.data --user $(id -u):$(id -g) corentinth/enclosed +``` + +From GitHub Container Registry: +```bash +docker run -d --name enclosed --restart unless-stopped -p 8787:8787 -v /path/to/local/data:/app/.data --user $(id -u):$(id -g) ghcr.io/corentin-th/enclosed +``` + +### Explanation of Additional Flags + +- `-v /path/to/local/data:/app/.data`: Maps a local directory to the container's data directory, ensuring that data is stored persistently on your host machine. +- `--user $(id -u):$(id -g)`: Ensures that the container runs with the same user ID and group ID as your current user, preventing potential permission issues with the mounted volume. + +## Managing the Docker Container + +Once Enclosed is running in a Docker container, you can manage it using the following commands: + +### Stopping the Container + +To stop the Enclosed container, run: + +```bash +docker stop enclosed +``` + +### Restarting the Container + +To restart the container, use: + +```bash +docker start enclosed +``` + +### Removing the Container + +If you need to remove the container, stop it first and then remove it with: + +```bash +docker stop enclosed +docker rm enclosed +``` + +## Updating Enclosed + +To update your Enclosed instance to the latest version, first remove the existing container, pull the latest image, and then run the container again: + +```bash +docker stop enclosed +docker rm enclosed + +# From Docker Hub +docker pull corentinth/enclosed + +# Or from GitHub Container Registry +docker pull ghcr.io/corentin-th/enclosed + +# Run the container again +docker run -d --name enclosed --restart unless-stopped -p 8787:8787 -v /path/to/local/data:/app/.data --user $(id -u):$(id -g) corentinth/enclosed +``` + +This will ensure that you are using the latest version of Enclosed with all your previous data intact. + +## Next Steps + +Once you have Enclosed up and running, you can explore [configuration options](./configuration) to customize your instance further. For more advanced setups, consider using [Docker Compose](./docker-compose) to manage your Enclosed deployment. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f5257ad3..b3c866b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,6 +208,12 @@ importers: packages/deploy-cloudflare: {} + packages/docs: + devDependencies: + vitepress: + specifier: ^1.3.4 + version: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(postcss@8.4.41)(search-insights@2.17.0)(terser@5.31.6)(typescript@5.5.4) + packages/lib: dependencies: lodash-es: @@ -244,6 +250,71 @@ importers: packages: + '@algolia/autocomplete-core@1.9.3': + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3': + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-preset-algolia@1.9.3': + resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.9.3': + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/cache-browser-local-storage@4.24.0': + resolution: {integrity: sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==} + + '@algolia/cache-common@4.24.0': + resolution: {integrity: sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==} + + '@algolia/cache-in-memory@4.24.0': + resolution: {integrity: sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==} + + '@algolia/client-account@4.24.0': + resolution: {integrity: sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==} + + '@algolia/client-analytics@4.24.0': + resolution: {integrity: sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==} + + '@algolia/client-common@4.24.0': + resolution: {integrity: sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==} + + '@algolia/client-personalization@4.24.0': + resolution: {integrity: sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==} + + '@algolia/client-search@4.24.0': + resolution: {integrity: sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==} + + '@algolia/logger-common@4.24.0': + resolution: {integrity: sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==} + + '@algolia/logger-console@4.24.0': + resolution: {integrity: sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==} + + '@algolia/recommend@4.24.0': + resolution: {integrity: sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==} + + '@algolia/requester-browser-xhr@4.24.0': + resolution: {integrity: sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==} + + '@algolia/requester-common@4.24.0': + resolution: {integrity: sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==} + + '@algolia/requester-node-http@4.24.0': + resolution: {integrity: sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==} + + '@algolia/transporter@4.24.0': + resolution: {integrity: sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -511,6 +582,29 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@docsearch/css@3.6.1': + resolution: {integrity: sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==} + + '@docsearch/js@3.6.1': + resolution: {integrity: sha512-erI3RRZurDr1xES5hvYJ3Imp7jtrXj6f1xYIzDzxiS7nNBufYWPbJwrmMqWC5g9y165PmxEmN9pklGCdLi0Iqg==} + + '@docsearch/react@3.6.1': + resolution: {integrity: sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + '@es-joy/jsdoccomment@0.43.1': resolution: {integrity: sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==} engines: {node: '>=16'} @@ -1492,6 +1586,15 @@ packages: cpu: [x64] os: [win32] + '@shikijs/core@1.16.1': + resolution: {integrity: sha512-aI0hBtw+a6KsJp2jcD4YuQqKpeCbURMZbhHVozDknJpm+KJqeMRkEnfBC8BaKE/5XC+uofPgCLsa/TkTk0Ba0w==} + + '@shikijs/transformers@1.16.1': + resolution: {integrity: sha512-mfbe4YMov+1eyIBU3F6BtaPmLgDkRQaVse8xsBlKTVAcNF3cbZMRCyUz2N6gJOMKLJiv9T5gapBPbRxrDMuoxA==} + + '@shikijs/vscode-textmate@9.2.0': + resolution: {integrity: sha512-5FinaOp6Vdh/dl4/yaOTh0ZeKch+rYS8DUb38V3GMKYVkdqzxw53lViRKUYkVILRiVQT7dcPC7VvAKOR73zVtQ==} + '@solid-primitives/event-listener@2.3.3': resolution: {integrity: sha512-DAJbl+F0wrFW2xmcV8dKMBhk9QLVLuBSW+TR4JmIfTaObxd13PuL7nqaXnaYKDWOYa6otB00qcCUIGbuIhSUgQ==} peerDependencies: @@ -1615,21 +1718,33 @@ packages: '@types/fs-extra@11.0.4': resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} '@types/lodash@4.17.7': resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + '@types/mdast@3.0.15': resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/mute-stream@0.0.4': resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} @@ -1651,6 +1766,9 @@ packages: '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + '@types/wrap-ansi@3.0.0': resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} @@ -1801,6 +1919,13 @@ packages: peerDependencies: vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + '@vitejs/plugin-vue@5.1.3': + resolution: {integrity: sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + '@vitest/coverage-v8@2.0.5': resolution: {integrity: sha512-qeFcySCg5FLO2bHHSa0tAZAOnAUbp4L6/A5JDuj9+bt53JREl8hpLjLHEWF0e/gWc8INVpJaqA7+Ene2rclpZg==} peerDependencies: @@ -1851,9 +1976,82 @@ packages: '@vue/compiler-ssr@3.4.38': resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} + '@vue/devtools-api@7.3.9': + resolution: {integrity: sha512-D+GTYtFg68bqSu66EugQUydsOqaDlPLNmYw5oYk8k81uBu9/bVTUrqlAJrAA9Am7MXhKz2gWdDkopY6sOBf/Bg==} + + '@vue/devtools-kit@7.3.9': + resolution: {integrity: sha512-Gr17nA+DaQzqyhNx1DUJr1CJRzTRfbIuuC80ZgU8MD/qNO302tv9la+ROi+Uaw+ULVwU9T71GnwLy4n8m9Lspg==} + + '@vue/devtools-shared@7.3.9': + resolution: {integrity: sha512-CdfMRZKXyI8vw+hqOcQIiLihB6Hbbi7WNZGp7LsuH1Qe4aYAFmTaKjSciRZ301oTnwmU/knC/s5OGuV6UNiNoA==} + + '@vue/reactivity@3.4.38': + resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==} + + '@vue/runtime-core@3.4.38': + resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==} + + '@vue/runtime-dom@3.4.38': + resolution: {integrity: sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==} + + '@vue/server-renderer@3.4.38': + resolution: {integrity: sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==} + peerDependencies: + vue: 3.4.38 + '@vue/shared@3.4.38': resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} + '@vueuse/core@11.0.3': + resolution: {integrity: sha512-RENlh64+SYA9XMExmmH1a3TPqeIuJBNNB/63GT35MZI+zpru3oMRUA6cEFr9HmGqEgUisurwGwnIieF6qu3aXw==} + + '@vueuse/integrations@11.0.3': + resolution: {integrity: sha512-w6CDisaxs19S5Fd+NPPLFaA3GoX5gxuxrbTTBu0EYap7oH13w75L6C/+7e9mcoF9akhcR6GyYajwVMQEjdapJg==} + peerDependencies: + async-validator: ^4 + axios: ^1 + change-case: ^5 + drauu: ^0.4 + focus-trap: ^7 + fuse.js: ^7 + idb-keyval: ^6 + jwt-decode: ^4 + nprogress: ^0.2 + qrcode: ^1.5 + sortablejs: ^1 + universal-cookie: ^7 + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@11.0.3': + resolution: {integrity: sha512-+FtbO4SD5WpsOcQTcC0hAhNlOid6QNLzqedtquTtQ+CRNBoAt9GuV07c6KNHK1wCmlq8DFPwgiLF2rXwgSHX5Q==} + + '@vueuse/shared@11.0.3': + resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==} + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -1890,6 +2088,9 @@ packages: ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + algoliasearch@4.24.0: + resolution: {integrity: sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -1969,6 +2170,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + birpc@0.2.17: + resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==} + blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} @@ -2162,6 +2366,10 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + core-js-compat@3.38.1: resolution: {integrity: sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==} @@ -2675,6 +2883,9 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + focus-trap@7.5.4: + resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} + foreground-child@3.3.0: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} @@ -3140,6 +3351,9 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + mdast-util-from-markdown@0.8.5: resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} @@ -3222,6 +3436,12 @@ packages: resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} engines: {node: '>=16 || 14 >=14.17'} + minisearch@7.1.0: + resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mkdist@1.5.4: resolution: {integrity: sha512-GEmKYJG5K1YGFIq3t0K3iihZ8FTgXphLf/4UjbmpXIAtBFn4lEjXk3pXNTSfy7EtcEXhp2Nn1vzw5pIus6RY3g==} hasBin: true @@ -3639,6 +3859,9 @@ packages: resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} + preact@10.23.2: + resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -3749,6 +3972,9 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rollup-plugin-dts@6.1.1: resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} engines: {node: '>=16'} @@ -3806,6 +4032,9 @@ packages: scule@1.3.0: resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + search-insights@2.17.0: + resolution: {integrity: sha512-AskayU3QNsXQzSL6v4LTYST7NNfs2HWyHHB+sdORP9chsytAhro5XRfToAMI/LAVYgNbzowVZTMfBRodgbUHKg==} + secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} @@ -3844,6 +4073,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + shiki@1.16.1: + resolution: {integrity: sha512-tCJIMaxDVB1mEIJ5TvfZU7kCPB5eo9fli5+21Olc/bmyv+w8kye3JOp+LZRmGkAyT71hrkefQhTiY+o9mBikRQ==} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -3916,6 +4148,10 @@ packages: spdx-license-ids@3.0.20: resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -3984,6 +4220,10 @@ packages: peerDependencies: postcss: ^8.4.31 + superjson@2.2.1: + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + engines: {node: '>=16'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -4016,6 +4256,9 @@ packages: resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} engines: {node: '>=18'} + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + tailwind-merge@2.5.2: resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==} @@ -4328,6 +4571,18 @@ packages: vite: optional: true + vitepress@1.3.4: + resolution: {integrity: sha512-I1/F6OW1xl3kW4PaIMC6snxjWgf3qfziq2aqsDoFc/Gt41WbcRv++z8zjw8qGRIJ+I4bUW7ZcKFDHHN/jkH9DQ==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + vitest@2.0.5: resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -4353,12 +4608,31 @@ packages: jsdom: optional: true + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue-eslint-parser@9.4.3: resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' + vue@3.4.38: + resolution: {integrity: sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + w3c-xmlserializer@5.0.0: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} @@ -4497,6 +4771,110 @@ packages: snapshots: + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.0)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.0)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + search-insights: 2.17.0 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + '@algolia/client-search': 4.24.0 + algoliasearch: 4.24.0 + + '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)': + dependencies: + '@algolia/client-search': 4.24.0 + algoliasearch: 4.24.0 + + '@algolia/cache-browser-local-storage@4.24.0': + dependencies: + '@algolia/cache-common': 4.24.0 + + '@algolia/cache-common@4.24.0': {} + + '@algolia/cache-in-memory@4.24.0': + dependencies: + '@algolia/cache-common': 4.24.0 + + '@algolia/client-account@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-analytics@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-common@4.24.0': + dependencies: + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-personalization@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/client-search@4.24.0': + dependencies: + '@algolia/client-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/logger-common@4.24.0': {} + + '@algolia/logger-console@4.24.0': + dependencies: + '@algolia/logger-common': 4.24.0 + + '@algolia/recommend@4.24.0': + dependencies: + '@algolia/cache-browser-local-storage': 4.24.0 + '@algolia/cache-common': 4.24.0 + '@algolia/cache-in-memory': 4.24.0 + '@algolia/client-common': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/logger-console': 4.24.0 + '@algolia/requester-browser-xhr': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/requester-node-http': 4.24.0 + '@algolia/transporter': 4.24.0 + + '@algolia/requester-browser-xhr@4.24.0': + dependencies: + '@algolia/requester-common': 4.24.0 + + '@algolia/requester-common@4.24.0': {} + + '@algolia/requester-node-http@4.24.0': + dependencies: + '@algolia/requester-common': 4.24.0 + + '@algolia/transporter@4.24.0': + dependencies: + '@algolia/cache-common': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 @@ -4815,6 +5193,30 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@docsearch/css@3.6.1': {} + + '@docsearch/js@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.0)': + dependencies: + '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.0) + preact: 10.23.2 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.0)': + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.0) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) + '@docsearch/css': 3.6.1 + algoliasearch: 4.24.0 + optionalDependencies: + search-insights: 2.17.0 + transitivePeerDependencies: + - '@algolia/client-search' + '@es-joy/jsdoccomment@0.43.1': dependencies: '@types/eslint': 8.56.12 @@ -5546,6 +5948,17 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.21.0': optional: true + '@shikijs/core@1.16.1': + dependencies: + '@shikijs/vscode-textmate': 9.2.0 + '@types/hast': 3.0.4 + + '@shikijs/transformers@1.16.1': + dependencies: + shiki: 1.16.1 + + '@shikijs/vscode-textmate@9.2.0': {} + '@solid-primitives/event-listener@2.3.3(solid-js@1.8.22)': dependencies: '@solid-primitives/utils': 6.2.3(solid-js@1.8.22) @@ -5701,6 +6114,10 @@ snapshots: '@types/node': 22.5.1 optional: true + '@types/hast@3.0.4': + dependencies: + '@types/unist': 2.0.11 + '@types/json-schema@7.0.15': {} '@types/jsonfile@6.1.4': @@ -5708,16 +6125,25 @@ snapshots: '@types/node': 22.5.1 optional: true + '@types/linkify-it@5.0.0': {} + '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.7 '@types/lodash@4.17.7': {} + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + '@types/mdast@3.0.15': dependencies: '@types/unist': 2.0.11 + '@types/mdurl@2.0.0': {} + '@types/mute-stream@0.0.4': dependencies: '@types/node': 22.5.1 @@ -5738,6 +6164,8 @@ snapshots: '@types/unist@2.0.11': {} + '@types/web-bluetooth@0.0.20': {} + '@types/wrap-ansi@3.0.0': {} '@typescript-eslint/eslint-plugin@8.3.0(@typescript-eslint/parser@8.3.0(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4))(eslint@9.9.1(jiti@1.21.6))(typescript@5.5.4)': @@ -5983,6 +6411,11 @@ snapshots: - rollup - supports-color + '@vitejs/plugin-vue@5.1.3(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4))': + dependencies: + vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) + vue: 3.4.38(typescript@5.5.4) + '@vitest/coverage-v8@2.0.5(vitest@2.0.5(@types/node@22.5.1)(jsdom@25.0.0)(terser@5.31.6))': dependencies: '@ampproject/remapping': 2.3.0 @@ -6072,8 +6505,78 @@ snapshots: '@vue/compiler-dom': 3.4.38 '@vue/shared': 3.4.38 + '@vue/devtools-api@7.3.9': + dependencies: + '@vue/devtools-kit': 7.3.9 + + '@vue/devtools-kit@7.3.9': + dependencies: + '@vue/devtools-shared': 7.3.9 + birpc: 0.2.17 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + + '@vue/devtools-shared@7.3.9': + dependencies: + rfdc: 1.4.1 + + '@vue/reactivity@3.4.38': + dependencies: + '@vue/shared': 3.4.38 + + '@vue/runtime-core@3.4.38': + dependencies: + '@vue/reactivity': 3.4.38 + '@vue/shared': 3.4.38 + + '@vue/runtime-dom@3.4.38': + dependencies: + '@vue/reactivity': 3.4.38 + '@vue/runtime-core': 3.4.38 + '@vue/shared': 3.4.38 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.38(vue@3.4.38(typescript@5.5.4))': + dependencies: + '@vue/compiler-ssr': 3.4.38 + '@vue/shared': 3.4.38 + vue: 3.4.38(typescript@5.5.4) + '@vue/shared@3.4.38': {} + '@vueuse/core@11.0.3(vue@3.4.38(typescript@5.5.4))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 11.0.3 + '@vueuse/shared': 11.0.3(vue@3.4.38(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/integrations@11.0.3(focus-trap@7.5.4)(vue@3.4.38(typescript@5.5.4))': + dependencies: + '@vueuse/core': 11.0.3(vue@3.4.38(typescript@5.5.4)) + '@vueuse/shared': 11.0.3(vue@3.4.38(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + optionalDependencies: + focus-trap: 7.5.4 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@11.0.3': {} + + '@vueuse/shared@11.0.3(vue@3.4.38(typescript@5.5.4))': + dependencies: + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -6112,6 +6615,24 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 + algoliasearch@4.24.0: + dependencies: + '@algolia/cache-browser-local-storage': 4.24.0 + '@algolia/cache-common': 4.24.0 + '@algolia/cache-in-memory': 4.24.0 + '@algolia/client-account': 4.24.0 + '@algolia/client-analytics': 4.24.0 + '@algolia/client-common': 4.24.0 + '@algolia/client-personalization': 4.24.0 + '@algolia/client-search': 4.24.0 + '@algolia/logger-common': 4.24.0 + '@algolia/logger-console': 4.24.0 + '@algolia/recommend': 4.24.0 + '@algolia/requester-browser-xhr': 4.24.0 + '@algolia/requester-common': 4.24.0 + '@algolia/requester-node-http': 4.24.0 + '@algolia/transporter': 4.24.0 + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -6184,6 +6705,8 @@ snapshots: binary-extensions@2.3.0: {} + birpc@0.2.17: {} + blake3-wasm@2.1.5: {} boolbase@1.0.0: {} @@ -6377,6 +6900,10 @@ snapshots: cookie@0.5.0: {} + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + core-js-compat@3.38.1: dependencies: browserslist: 4.23.3 @@ -7054,6 +7581,10 @@ snapshots: flatted@3.3.1: {} + focus-trap@7.5.4: + dependencies: + tabbable: 6.2.0 + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.3 @@ -7513,6 +8044,8 @@ snapshots: dependencies: semver: 7.6.3 + mark.js@8.11.1: {} + mdast-util-from-markdown@0.8.5: dependencies: '@types/mdast': 3.0.15 @@ -7602,6 +8135,10 @@ snapshots: minipass@7.1.2: {} + minisearch@7.1.0: {} + + mitt@3.0.1: {} + mkdist@1.5.4(typescript@5.5.4): dependencies: autoprefixer: 10.4.20(postcss@8.4.41) @@ -8018,6 +8555,8 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 + preact@10.23.2: {} + prelude-ls@1.2.1: {} pretty-bytes@6.1.1: {} @@ -8112,6 +8651,8 @@ snapshots: reusify@1.0.4: {} + rfdc@1.4.1: {} + rollup-plugin-dts@6.1.1(rollup@3.29.4)(typescript@5.5.4): dependencies: magic-string: 0.30.11 @@ -8186,6 +8727,8 @@ snapshots: scule@1.3.0: {} + search-insights@2.17.0: {} + secure-json-parse@2.7.0: {} selfsigned@2.4.1: @@ -8211,6 +8754,12 @@ snapshots: shebang-regex@3.0.0: {} + shiki@1.16.1: + dependencies: + '@shikijs/core': 1.16.1 + '@shikijs/vscode-textmate': 9.2.0 + '@types/hast': 3.0.4 + siginfo@2.0.0: {} signal-exit@4.1.0: {} @@ -8287,6 +8836,8 @@ snapshots: spdx-license-ids@3.0.20: {} + speakingurl@14.0.1: {} + split2@4.2.0: {} stable-hash@0.0.4: {} @@ -8350,6 +8901,10 @@ snapshots: postcss: 8.4.41 postcss-selector-parser: 6.1.2 + superjson@2.2.1: + dependencies: + copy-anything: 3.0.5 + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -8383,6 +8938,8 @@ snapshots: system-architecture@0.1.0: {} + tabbable@6.2.0: {} + tailwind-merge@2.5.2: {} tapable@2.2.1: {} @@ -8694,6 +9251,54 @@ snapshots: optionalDependencies: vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) + vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.1)(postcss@8.4.41)(search-insights@2.17.0)(terser@5.31.6)(typescript@5.5.4): + dependencies: + '@docsearch/css': 3.6.1 + '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.0) + '@shikijs/core': 1.16.1 + '@shikijs/transformers': 1.16.1 + '@types/markdown-it': 14.1.2 + '@vitejs/plugin-vue': 5.1.3(vite@5.4.2(@types/node@22.5.1)(terser@5.31.6))(vue@3.4.38(typescript@5.5.4)) + '@vue/devtools-api': 7.3.9 + '@vue/shared': 3.4.38 + '@vueuse/core': 11.0.3(vue@3.4.38(typescript@5.5.4)) + '@vueuse/integrations': 11.0.3(focus-trap@7.5.4)(vue@3.4.38(typescript@5.5.4)) + focus-trap: 7.5.4 + mark.js: 8.11.1 + minisearch: 7.1.0 + shiki: 1.16.1 + vite: 5.4.2(@types/node@22.5.1)(terser@5.31.6) + vue: 3.4.38(typescript@5.5.4) + optionalDependencies: + postcss: 8.4.41 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - sass-embedded + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + vitest@2.0.5(@types/node@22.5.1)(jsdom@25.0.0)(terser@5.31.6): dependencies: '@ampproject/remapping': 2.3.0 @@ -8728,6 +9333,10 @@ snapshots: - supports-color - terser + vue-demi@0.14.10(vue@3.4.38(typescript@5.5.4)): + dependencies: + vue: 3.4.38(typescript@5.5.4) + vue-eslint-parser@9.4.3(eslint@9.9.1(jiti@1.21.6)): dependencies: debug: 4.3.6 @@ -8741,6 +9350,16 @@ snapshots: transitivePeerDependencies: - supports-color + vue@3.4.38(typescript@5.5.4): + dependencies: + '@vue/compiler-dom': 3.4.38 + '@vue/compiler-sfc': 3.4.38 + '@vue/runtime-dom': 3.4.38 + '@vue/server-renderer': 3.4.38(vue@3.4.38(typescript@5.5.4)) + '@vue/shared': 3.4.38 + optionalDependencies: + typescript: 5.5.4 + w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0