diff options
Diffstat (limited to 'website')
52 files changed, 3951 insertions, 0 deletions
diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..0d28533 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,138 @@ +### Node template +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + + +# wrangler files +.wrangler +.dev.vars* +!.dev.vars.example +!.env.example diff --git a/website/.mcp.json b/website/.mcp.json new file mode 100644 index 0000000..cc35acb --- /dev/null +++ b/website/.mcp.json @@ -0,0 +1,13 @@ +{ + "mcpServers": { + "chrome-devtools": { + "type": "stdio", + "command": "bunx", + "args": [ + "chrome-devtools-mcp", + "--executablePath=/Applications/Chromium.app/Contents/MacOS/Chromium" + ], + "env": {} + } + } +}
\ No newline at end of file diff --git a/website/.vitepress/config.mts b/website/.vitepress/config.mts new file mode 100644 index 0000000..a3fcb56 --- /dev/null +++ b/website/.vitepress/config.mts @@ -0,0 +1,50 @@ +import { execSync } from 'node:child_process'; +import { defineConfig } from 'vitepress'; +import { en } from './config/en'; +import { ja } from './config/ja'; + +const gitRoot = execSync('git rev-parse --show-toplevel').toString().trim(); +const commitHash = execSync(`git log -1 --format=%H -- ${gitRoot}/website/`) + .toString() + .trim() + .slice(0, 7); + +export default defineConfig({ + cleanUrls: true, + description: 'Next-generation channel chat plugin for Paper/Velocity', + head: [['link', { href: '/favicon.ico', rel: 'icon' }]], + locales: { + en: { + label: 'English', + lang: 'en-US', + link: '/en/', + themeConfig: { + ...en, + footer: { + copyright: 'Copyright © 2026 m1sk9', + message: `<a href="https://github.com/m1sk9/LunaticChat/commit/${commitHash}">LunaticChat/website@${commitHash}</a>`, + }, + }, + }, + root: { + label: '日本語', + lang: 'ja-JP', + themeConfig: { + ...ja, + footer: { + copyright: 'Copyright © 2026 m1sk9', + message: `<a href="https://github.com/m1sk9/LunaticChat/commit/${commitHash}">LunaticChat/website@${commitHash}</a>`, + }, + }, + }, + }, + outDir: './dist', + srcDir: 'src', + themeConfig: { + socialLinks: [ + { icon: 'github', link: 'https://github.com/m1sk9/LunaticChat' }, + ], + }, + title: 'LunaticChat', + titleTemplate: 'LunaticChat', +}); diff --git a/website/.vitepress/config/en.ts b/website/.vitepress/config/en.ts new file mode 100644 index 0000000..3a05016 --- /dev/null +++ b/website/.vitepress/config/en.ts @@ -0,0 +1,74 @@ +import type { DefaultTheme } from 'vitepress'; + +export const en: DefaultTheme.Config = { + editLink: { + pattern: 'https://github.com/m1sk9/LunaticChat/edit/main/website/src/:path', + text: 'Edit this page on GitHub', + }, + nav: [ + { link: '/en/download', text: 'Download' }, + { link: '/en/docs/getting-started', text: 'Documentation' }, + ], + sidebar: { + '/en/docs/': [ + { + link: '/en/docs/getting-started', + text: 'Getting Started', + }, + { + link: '/en/docs/configuration', + text: 'Configuration', + }, + { + link: '/en/docs/permissions', + text: 'Permissions', + }, + { + text: 'Feature Guides', + items: [ + { + link: '/en/docs/features/direct-message', + text: 'Direct Messages', + }, + { + link: '/en/docs/features/channel-chat', + text: 'Channel Chat', + }, + { + link: '/en/docs/features/japanese-conversion', + text: 'Romaji Conversion', + }, + { + link: '/en/docs/features/velocity', + text: 'Velocity Integration', + }, + { + link: '/en/docs/features/message-logging', + text: 'Message Logging', + }, + { + link: '/en/docs/features/admin', + text: 'Admin Features', + }, + ], + }, + { + text: 'Reference', + items: [ + { + link: '/en/docs/reference/commands', + text: 'Commands', + }, + { + link: '/en/docs/reference/message-format', + text: 'Message Format', + }, + { + link: '/en/docs/reference/player-settings', + text: 'Player Settings', + }, + ], + }, + ], + }, +}; diff --git a/website/.vitepress/config/ja.ts b/website/.vitepress/config/ja.ts new file mode 100644 index 0000000..e74102c --- /dev/null +++ b/website/.vitepress/config/ja.ts @@ -0,0 +1,74 @@ +import type { DefaultTheme } from 'vitepress'; + +export const ja: DefaultTheme.Config = { + editLink: { + pattern: 'https://github.com/m1sk9/LunaticChat/edit/main/website/src/:path', + text: 'GitHub で編集', + }, + nav: [ + { link: '/download', text: 'ダウンロード' }, + { link: '/docs/getting-started', text: 'ドキュメント' }, + ], + sidebar: { + '/docs/': [ + { + link: '/docs/getting-started', + text: 'はじめる', + }, + { + link: '/docs/configuration', + text: '設定', + }, + { + link: '/docs/permissions', + text: 'パーミッション', + }, + { + text: '機能ガイド', + items: [ + { + link: '/docs/features/direct-message', + text: 'ダイレクトメッセージ', + }, + { + link: '/docs/features/channel-chat', + text: 'チャンネルチャット', + }, + { + link: '/docs/features/japanese-conversion', + text: 'ローマ字変換', + }, + { + link: '/docs/features/velocity', + text: 'Velocity 連携', + }, + { + link: '/docs/features/message-logging', + text: 'メッセージログ', + }, + { + link: '/docs/features/admin', + text: '管理者向け機能', + }, + ], + }, + { + text: 'リファレンス', + items: [ + { + link: '/docs/reference/commands', + text: 'コマンド一覧', + }, + { + link: '/docs/reference/message-format', + text: 'メッセージフォーマット', + }, + { + link: '/docs/reference/player-settings', + text: 'プレイヤー設定', + }, + ], + }, + ], + }, +}; diff --git a/website/.vitepress/theme/components/DownloadCard.vue b/website/.vitepress/theme/components/DownloadCard.vue new file mode 100644 index 0000000..019a8f8 --- /dev/null +++ b/website/.vitepress/theme/components/DownloadCard.vue @@ -0,0 +1,380 @@ +<script setup lang="ts"> +import { computed } from 'vue'; +import { useData } from 'vitepress'; +import { data } from './download.data'; + +const { lang } = useData(); +const isEn = computed(() => lang.value === 'en-US'); + +const t = computed(() => + isEn.value + ? { + title: 'Download', + description: 'Download the latest releases of LunaticChat.', + compatible: 'Paper and Velocity Compatibility', + requirements: 'Requirements', + javaReq: '25 or later', + paperReq: '26.1.x or later', + velocityReq: '3.4.x or later', + noRelease: 'No release', + releaseDate: 'Release date', + fileSize: 'File size', + download: 'Download', + releaseNotes: 'Release notes', + modrinthDesc: 'LunaticChat is also available on Modrinth.', + notYetReleased: 'Not yet released.', + devBuilds: 'Development Builds', + devBuildsDesc: + 'The latest build from the main branch is available from CI. Development builds are not guaranteed to be stable.', + viewCiBuilds: 'View latest CI builds', + compatNotice: + 'Paper and Velocity plugins are versioned with a protocol version. For MINOR version changes, update Velocity first. For MAJOR version changes, update all servers simultaneously.', + compatLink: 'See Velocity Integration - Protocol Version for details.', + } + : { + title: 'ダウンロード', + description: 'LunaticChat の最新リリースをダウンロードできます。', + compatible: 'Paper / Velocity の互換性', + requirements: '動作要件', + javaReq: '25 以降', + paperReq: '26.1.x 以降', + velocityReq: '3.4.x 以降', + noRelease: 'リリースなし', + releaseDate: 'リリース日', + fileSize: 'ファイルサイズ', + download: 'ダウンロード', + releaseNotes: 'リリースノート', + modrinthDesc: 'LunaticChat は Modrinth でも公開しています。', + notYetReleased: 'まだリリースされていません。', + devBuilds: '開発ビルド', + devBuildsDesc: + '最新の main ブランチのビルドは CI から取得できます。開発ビルドは安定性が保証されていません。', + viewCiBuilds: '最新の CI ビルドを確認', + compatNotice: + 'Paper プラグインと Velocity プラグインはプロトコルバージョンで互換性が管理されています.MINOR バージョン変更時は Velocity を先にアップデートしてください.MAJOR バージョン変更時は全サーバーを同時にアップデートする必要があります.', + compatLink: '詳細は Velocity 連携 - プロトコルバージョン を参照してください.', + }, +); + +function formatSize(bytes: number | null): string { + if (!bytes) return '-'; + const mb = bytes / (1024 * 1024); + return `${mb.toFixed(1)} MB`; +} + +function formatDate(dateStr: string | null): string { + if (!dateStr) return '-'; + const locale = isEn.value ? 'en-US' : 'ja-JP'; + return new Date(dateStr).toLocaleDateString(locale, { + year: 'numeric', + month: 'long', + day: 'numeric', + }); +} +</script> + +<template> + <div class="download-page"> + <h1>{{ t.title }}</h1> + <p>{{ t.description }}</p> + + <div class="download-requirements"> + <p class="download-requirements-title">{{ t.requirements }}</p> + <ul> + <li><strong>Java</strong>: {{ t.javaReq }}</li> + <li><strong>Paper / Folia</strong>: {{ t.paperReq }}</li> + <li><strong>Velocity</strong>: {{ t.velocityReq }}</li> + </ul> + </div> + + <div class="download-compat-notice"> + <p class="download-compat-title">{{ t.compatible }}</p> + <p>{{ t.compatNotice }}</p> + <p><a :href="isEn ? '/en/docs/features/velocity#protocol-version' : '/docs/features/velocity#プロトコルバージョン'">{{ t.compatLink }}</a></p> + </div> + + <div class="download-grid"> + <!-- Paper / Folia --> + <div class="download-card"> + <div class="download-card-header"> + <img src="/assets/brand/paper.svg" alt="Paper" class="download-icon" /> + <div> + <h2>Paper / Folia</h2> + <p class="download-version" v-if="data.paper">v{{ data.paper.version }}</p> + <p class="download-version" v-else>{{ t.noRelease }}</p> + </div> + </div> + <div class="download-card-body" v-if="data.paper"> + <dl class="download-meta"> + <div> + <dt>{{ t.releaseDate }}</dt> + <dd>{{ formatDate(data.paper.publishedAt) }}</dd> + </div> + <div> + <dt>{{ t.fileSize }}</dt> + <dd>{{ formatSize(data.paper.fileSize) }}</dd> + </div> + <div> + <dd><code>{{ data.paper.fileName ?? '-' }}</code></dd> + </div> + </dl> + <div class="download-actions"> + <a v-if="data.paper.downloadUrl" :href="data.paper.downloadUrl" class="download-btn primary">{{ t.download }}</a> + <a :href="data.paper.releaseUrl" class="download-btn" target="_blank" rel="noopener">{{ t.releaseNotes }}</a> + </div> + </div> + <div class="download-card-body" v-else> + <p class="download-empty">{{ t.notYetReleased }}</p> + </div> + </div> + + <!-- Velocity --> + <div class="download-card"> + <div class="download-card-header"> + <img src="/assets/brand/velocity.svg" alt="Velocity" class="download-icon" /> + <div> + <h2>Velocity</h2> + <p class="download-version" v-if="data.velocity">v{{ data.velocity.version }}</p> + <p class="download-version" v-else>{{ t.noRelease }}</p> + </div> + </div> + <div class="download-card-body" v-if="data.velocity"> + <dl class="download-meta"> + <div> + <dt>{{ t.releaseDate }}</dt> + <dd>{{ formatDate(data.velocity.publishedAt) }}</dd> + </div> + <div> + <dt>{{ t.fileSize }}</dt> + <dd>{{ formatSize(data.velocity.fileSize) }}</dd> + </div> + <div> + <dd><code>{{ data.velocity.fileName ?? '-' }}</code></dd> + </div> + </dl> + <div class="download-actions"> + <a v-if="data.velocity.downloadUrl" :href="data.velocity.downloadUrl" class="download-btn primary">{{ t.download }}</a> + <a :href="data.velocity.releaseUrl" class="download-btn" target="_blank" rel="noopener">{{ t.releaseNotes }}</a> + </div> + </div> + <div class="download-card-body" v-else> + <p class="download-empty">{{ t.notYetReleased }}</p> + </div> + </div> + </div> + + <h2>Modrinth</h2> + <p>{{ t.modrinthDesc }}</p> + <div class="download-ci"> + <a href="https://modrinth.com/plugin/lunaticchat" class="download-btn" target="_blank" rel="noopener">Modrinth</a> + </div> + + <h2>{{ t.devBuilds }}</h2> + <p>{{ t.devBuildsDesc }}</p> + <div class="download-ci"> + <a :href="data.ci.url" class="download-btn" target="_blank" rel="noopener">{{ t.viewCiBuilds }}</a> + </div> + </div> +</template> + +<style scoped> +.download-page { + max-width: 768px; + margin: 0 auto; + padding: 48px 24px; +} + +.download-page h1 { + font-size: 2rem; + font-weight: 700; + margin-bottom: 8px; +} + +.download-page > p { + color: var(--vp-c-text-2); + margin-bottom: 24px; +} + +.download-page h2 { + font-size: 1.25rem; + font-weight: 600; + margin-top: 40px; + margin-bottom: 8px; + border: none; + padding: 0; +} + +.download-requirements { + border: 1px solid var(--vp-c-brand-soft); + background: var(--vp-c-brand-soft); + border-radius: 8px; + padding: 16px 20px; + margin-bottom: 24px; +} + +.download-requirements-title { + font-weight: 600; + margin-bottom: 8px; +} + +.download-requirements ul { + margin: 0; + padding-left: 20px; +} + +.download-requirements li { + font-size: 0.9rem; + line-height: 1.7; +} + +.download-compat-notice { + border: 1px solid var(--vp-c-warning-soft); + background: var(--vp-c-warning-soft); + border-radius: 8px; + padding: 16px 20px; + margin-bottom: 24px; + font-size: 0.9rem; + line-height: 1.7; +} + +.download-compat-notice p { + margin: 0; +} + +.download-compat-notice p + p { + margin-top: 8px; +} + +.download-compat-title { + font-weight: 600; + margin-bottom: 8px !important; +} + +.download-compat-notice a { + color: var(--vp-c-brand-1); + text-decoration: underline; +} + +.download-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20px; + margin: 24px 0; +} + +@media (max-width: 640px) { + .download-grid { + grid-template-columns: 1fr; + } +} + +.download-card { + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + overflow: hidden; + background: var(--vp-c-bg-soft); +} + +.download-card-header { + display: flex; + align-items: center; + gap: 16px; + padding: 24px 24px 0; +} + +.download-card-header h2 { + margin: 0; + font-size: 1.25rem; +} + +.download-icon { + width: 40px; + height: 40px; + object-fit: contain; + filter: brightness(0) saturate(100%); +} + +:global(.dark .download-icon) { + filter: brightness(0) saturate(100%) invert(1); +} + +.download-version { + margin: 2px 0 0; + font-size: 0.875rem; + color: var(--vp-c-text-2); +} + +.download-card-body { + padding: 20px 24px 24px; +} + +.download-meta { + margin: 0 0 20px; + padding: 0; +} + +.download-meta div { + display: flex; + justify-content: space-between; + padding: 6px 0; + border-bottom: 1px solid var(--vp-c-divider); + font-size: 0.875rem; +} + +.download-meta div:last-child { + border-bottom: none; +} + +.download-meta dt { + color: var(--vp-c-text-2); +} + +.download-meta dd { + margin: 0; + color: var(--vp-c-text-1); +} + +.download-actions { + display: flex; + gap: 8px; +} + +.download-btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 8px 20px; + border-radius: 8px; + font-size: 0.875rem; + font-weight: 500; + text-decoration: none !important; + color: var(--vp-c-text-1); + border: 1px solid var(--vp-c-divider); + background: var(--vp-c-bg); + transition: border-color 0.25s, background 0.25s; +} + +.download-btn:hover { + border-color: var(--vp-c-brand-1); +} + +.download-btn.primary { + background: var(--vp-button-brand-bg); + color: var(--vp-button-brand-text); + border-color: var(--vp-button-brand-border); +} + +.download-btn.primary:hover { + background: var(--vp-button-brand-hover-bg); + border-color: var(--vp-button-brand-hover-border); +} + +.download-empty { + color: var(--vp-c-text-3); + font-size: 0.875rem; +} + +.download-ci { + margin: 16px 0; +} +</style> diff --git a/website/.vitepress/theme/components/download.data.ts b/website/.vitepress/theme/components/download.data.ts new file mode 100644 index 0000000..11e0489 --- /dev/null +++ b/website/.vitepress/theme/components/download.data.ts @@ -0,0 +1,105 @@ +const REPO = 'm1sk9/LunaticChat'; + +interface ReleaseAsset { + name: string; + size: number; + browser_download_url: string; +} + +interface GitHubRelease { + tag_name: string; + published_at: string; + html_url: string; + assets: ReleaseAsset[]; +} + +interface PlatformRelease { + version: string; + publishedAt: string; + releaseUrl: string; + downloadUrl: string | null; + fileName: string | null; + fileSize: number | null; +} + +interface CIBuild { + url: string; +} + +export interface DownloadData { + paper: PlatformRelease | null; + velocity: PlatformRelease | null; + ci: CIBuild; +} + +async function fetchLatestRelease( + tagPrefix: string, +): Promise<GitHubRelease | null> { + const res = await fetch( + `https://api.github.com/repos/${REPO}/releases?per_page=20`, + ); + if (!res.ok) return null; + + const releases: GitHubRelease[] = await res.json(); + return ( + releases.find( + (r) => + r.tag_name.startsWith(tagPrefix) || r.tag_name.startsWith('v'), + ) ?? null + ); +} + +function parsePlatformRelease( + release: GitHubRelease | null, + jarPattern: RegExp, +): PlatformRelease | null { + if (!release) return null; + + const asset = release.assets.find((a) => jarPattern.test(a.name)); + const version = release.tag_name.replace(/^(paper\/|velocity\/)?v/, ''); + + return { + version, + publishedAt: release.published_at, + releaseUrl: release.html_url, + downloadUrl: asset?.browser_download_url ?? null, + fileName: asset?.name ?? null, + fileSize: asset?.size ?? null, + }; +} + +export default { + async load(): Promise<DownloadData> { + // Fetch all recent releases and find the latest for each platform + const res = await fetch( + `https://api.github.com/repos/${REPO}/releases?per_page=30`, + ); + const releases: GitHubRelease[] = res.ok ? await res.json() : []; + + // Find latest Paper release (paper/v* or v*) + const paperRelease = + releases.find((r) => r.tag_name.startsWith('paper/v')) ?? + releases.find((r) => /^v\d/.test(r.tag_name)) ?? + null; + + // Find latest Velocity release (velocity/v* or v*) + const velocityRelease = + releases.find((r) => r.tag_name.startsWith('velocity/v')) ?? + releases.find((r) => /^v\d/.test(r.tag_name)) ?? + null; + + return { + paper: parsePlatformRelease( + paperRelease, + /^LunaticChat-[\d.]+\.jar$/, + ), + velocity: parsePlatformRelease( + velocityRelease, + /^LunaticChat-[\d.]+-velocity\.jar$/, + ), + ci: { + url: `https://github.com/${REPO}/actions/workflows/ci.yaml?query=branch%3Amain`, + }, + }; + }, +}; diff --git a/website/.vitepress/theme/custom.css b/website/.vitepress/theme/custom.css new file mode 100644 index 0000000..1f928a1 --- /dev/null +++ b/website/.vitepress/theme/custom.css @@ -0,0 +1,188 @@ +/* ── Home page custom styles ── */ + +/* Hero tagline emphasis */ +.VPHero .tagline { + font-size: 1.2rem !important; + max-width: 560px; +} + +/* ── Feature showcase: alternating text + image ── */ +.feature-showcase { + max-width: 1152px; + margin: 0 auto; + padding: 64px 24px; + display: flex; + align-items: center; + gap: 48px; +} + +.feature-showcase.reverse { + flex-direction: row-reverse; +} + +.feature-showcase-text { + flex: 3; + min-width: 0; +} + +.feature-showcase-text h2 { + font-size: 1.75rem; + font-weight: 700; + line-height: 1.3; + margin-bottom: 16px; +} + +.feature-showcase-text p { + color: var(--vp-c-text-2); + font-size: 1rem; + line-height: 1.7; + margin-bottom: 12px; +} + +.feature-showcase-text ul { + list-style: none; + padding: 0; + margin: 16px 0 0; +} + +.feature-showcase-text ul li { + position: relative; + padding-left: 24px; + color: var(--vp-c-text-2); + font-size: 0.95rem; + line-height: 1.7; + margin-bottom: 8px; +} + +.feature-showcase-text ul li::before { + content: ''; + position: absolute; + left: 0; + top: 10px; + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--vp-c-brand-1); +} + +.feature-showcase-image { + flex: 3; + min-width: 0; +} + +.feature-showcase-image img { + width: 100%; + border-radius: 12px; + border: 1px solid var(--vp-c-divider); + box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08); +} + +.feature-showcase-image .image-placeholder { + width: 100%; + aspect-ratio: 16 / 10; + border-radius: 12px; + border: 2px dashed var(--vp-c-divider); + background: var(--vp-c-bg-soft); + display: flex; + align-items: center; + justify-content: center; + color: var(--vp-c-text-3); + font-size: 0.875rem; +} + +@media (max-width: 768px) { + .feature-showcase, + .feature-showcase.reverse { + flex-direction: column; + padding: 40px 24px; + gap: 32px; + } +} + +/* ── Platform cards ── */ +.platform-section { + max-width: 1024px; + margin: 0 auto; + padding: 64px 24px; + text-align: center; +} + +.platform-section h2 { + font-size: 1.75rem; + font-weight: 700; + margin-bottom: 8px; +} + +.platform-section .section-desc { + color: var(--vp-c-text-2); + margin-bottom: 32px; + font-size: 1rem; +} + +.platform-cards { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 16px; +} + +@media (max-width: 640px) { + .platform-cards { + grid-template-columns: 1fr; + } +} + +.platform-card { + display: block; + border: 1px solid var(--vp-c-divider); + border-radius: 12px; + padding: 24px 16px; + background: var(--vp-c-bg-soft); + transition: border-color 0.25s, box-shadow 0.25s; + text-decoration: none !important; + color: inherit; +} + +.platform-card:hover { + border-color: var(--vp-c-brand-1); + box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); +} + +.platform-icon { + margin-bottom: 12px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; +} + +.platform-icon img { + width: 40px; + height: 40px; + object-fit: contain; + filter: brightness(0) saturate(100%); +} + +.dark .platform-icon img { + filter: brightness(0) saturate(100%) invert(1); +} + +.platform-card .name { + font-size: 1.1rem; + font-weight: 600; + margin-bottom: 8px; + color: var(--vp-c-text-1); +} + +.platform-card .desc { + font-size: 0.875rem; + color: var(--vp-c-text-2); + line-height: 1.6; +} + +/* ── Divider ── */ +.home-divider { + max-width: 1024px; + margin: 0 auto; + border: none; + border-top: 1px solid var(--vp-c-divider); +} diff --git a/website/.vitepress/theme/index.ts b/website/.vitepress/theme/index.ts new file mode 100644 index 0000000..bc82522 --- /dev/null +++ b/website/.vitepress/theme/index.ts @@ -0,0 +1,11 @@ +import type { Theme } from 'vitepress'; +import DefaultTheme from 'vitepress/theme'; +import DownloadCard from './components/DownloadCard.vue'; +import './custom.css'; + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + app.component('DownloadCard', DownloadCard); + }, +} satisfies Theme; diff --git a/website/biome.jsonc b/website/biome.jsonc new file mode 100644 index 0000000..ac66012 --- /dev/null +++ b/website/biome.jsonc @@ -0,0 +1,55 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.4.10/schema.json", + "files": { + "ignoreUnknown": true, + "includes": [ + ".vitepress/config.mts", + "biome.jsonc", + ".vitepress/config/**", + ".vitepress/theme/*.ts" + ] + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 80, + "attributePosition": "auto" + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false, + "quoteStyle": "single", + "attributePosition": "auto" + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noShadowRestrictedNames": "off" + }, + "style": { + "noParameterAssign": "error", + "useAsConstAssertion": "error", + "useDefaultParameterLast": "error", + "useEnumInitializers": "error", + "useSelfClosingElements": "error", + "useSingleVarDeclarator": "error", + "noUnusedTemplateLiteral": "error", + "useNumberNamespace": "error", + "noInferrableTypes": "error", + "noUselessElse": "error" + } + } + } +} diff --git a/website/bun.lock b/website/bun.lock new file mode 100644 index 0000000..63d664a --- /dev/null +++ b/website/bun.lock @@ -0,0 +1,566 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "dependencies": { + "wrangler": "^4.69.0", + }, + "devDependencies": { + "@biomejs/biome": "2.4.10", + "@types/bun": "^1.3.11", + "husky": "^9.1.7", + "vitepress": "^1.6.4", + }, + }, + }, + "packages": { + "@algolia/abtesting": ["@algolia/abtesting@1.15.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-2yuIC48rUuHGhU1U5qJ9kJHaxYpJ0jpDHJVI5ekOxSMYXlH4+HP+pA31G820lsAznfmu2nzDV7n5RO44zIY1zw=="], + + "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.17.7", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q=="], + + "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A=="], + + "@algolia/autocomplete-preset-algolia": ["@algolia/autocomplete-preset-algolia@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA=="], + + "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.17.7", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg=="], + + "@algolia/client-abtesting": ["@algolia/client-abtesting@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-h6M7HzPin+45/l09q0r2dYmocSSt2MMGOOk5c4O5K/bBBlEwf1BKfN6z+iX4b8WXcQQhf7rgQwC52kBZJt/ZZw=="], + + "@algolia/client-analytics": ["@algolia/client-analytics@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-048T9/Z8OeLmTk8h76QUqaNFp7Rq2VgS2Zm6Y2tNMYGQ1uNuzePY/udB5l5krlXll7ZGflyCjFvRiOtlPZpE9g=="], + + "@algolia/client-common": ["@algolia/client-common@5.49.1", "", {}, "sha512-vp5/a9ikqvf3mn9QvHN8PRekn8hW34aV9eX+O0J5mKPZXeA6Pd5OQEh2ZWf7gJY6yyfTlLp5LMFzQUAU+Fpqpg=="], + + "@algolia/client-insights": ["@algolia/client-insights@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-B6N7PgkvYrul3bntTz/l6uXnhQ2bvP+M7NqTcayh681tSqPaA5cJCUBp/vrP7vpPRpej4Eeyx2qz5p0tE/2N2g=="], + + "@algolia/client-personalization": ["@algolia/client-personalization@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-v+4DN+lkYfBd01Hbnb9ZrCHe7l+mvihyx218INRX/kaCXROIWUDIT1cs3urQxfE7kXBFnLsqYeOflQALv/gA5w=="], + + "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-Un11cab6ZCv0W+Jiak8UktGIqoa4+gSNgEZNfG8m8eTsXGqwIEr370H3Rqwj87zeNSlFpH2BslMXJ/cLNS1qtg=="], + + "@algolia/client-search": ["@algolia/client-search@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-Nt9hri7nbOo0RipAsGjIssHkpLMHHN/P7QqENywAq5TLsoYDzUyJGny8FEiD/9KJUxtGH8blGpMedilI6kK3rA=="], + + "@algolia/ingestion": ["@algolia/ingestion@1.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-b5hUXwDqje0Y4CpU6VL481DXgPgxpTD5sYMnfQTHKgUispGnaCLCm2/T9WbJo1YNUbX3iHtYDArp804eD6CmRQ=="], + + "@algolia/monitoring": ["@algolia/monitoring@1.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-bvrXwZ0WsL3rN6Q4m4QqxsXFCo6WAew7sAdrpMQMK4Efn4/W920r9ptOuckejOSSvyLr9pAWgC5rsHhR2FYuYw=="], + + "@algolia/recommend": ["@algolia/recommend@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-h2yz3AGeGkQwNgbLmoe3bxYs8fac4An1CprKTypYyTU/k3Q+9FbIvJ8aS1DoBKaTjSRZVoyQS7SZQio6GaHbZw=="], + + "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1" } }, "sha512-2UPyRuUR/qpqSqH8mxFV5uBZWEpxhGPHLlx9Xf6OVxr79XO2ctzZQAhsmTZ6X22x+N8MBWpB9UEky7YU2HGFgA=="], + + "@algolia/requester-fetch": ["@algolia/requester-fetch@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1" } }, "sha512-N+xlE4lN+wpuT+4vhNEwPVlrfN+DWAZmSX9SYhbz986Oq8AMsqdntOqUyiOXVxYsQtfLwmiej24vbvJGYv1Qtw=="], + + "@algolia/requester-node-http": ["@algolia/requester-node-http@5.49.1", "", { "dependencies": { "@algolia/client-common": "5.49.1" } }, "sha512-zA5bkUOB5PPtTr182DJmajCiizHp0rCJQ0Chf96zNFvkdESKYlDeYA3tQ7r2oyHbu/8DiohAQ5PZ85edctzbXA=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="], + + "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "@biomejs/biome": ["@biomejs/biome@2.4.10", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.10", "@biomejs/cli-darwin-x64": "2.4.10", "@biomejs/cli-linux-arm64": "2.4.10", "@biomejs/cli-linux-arm64-musl": "2.4.10", "@biomejs/cli-linux-x64": "2.4.10", "@biomejs/cli-linux-x64-musl": "2.4.10", "@biomejs/cli-win32-arm64": "2.4.10", "@biomejs/cli-win32-x64": "2.4.10" }, "bin": { "biome": "bin/biome" } }, "sha512-xxA3AphFQ1geij4JTHXv4EeSTda1IFn22ye9LdyVPoJU19fNVl0uzfEuhsfQ4Yue/0FaLs2/ccVi4UDiE7R30w=="], + + "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-vuzzI1cWqDVzOMIkYyHbKqp+AkQq4K7k+UCXWpkYcY/HDn1UxdsbsfgtVpa40shem8Kax4TLDLlx8kMAecgqiw=="], + + "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-14fzASRo+BPotwp7nWULy2W5xeUyFnTaq1V13Etrrxkrih+ez/2QfgFm5Ehtf5vSjtgx/IJycMMpn5kPd5ZNaA=="], + + "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-7MH1CMW5uuxQ/s7FLST63qF8B3Hgu2HRdZ7tA1X1+mk+St4JOuIrqdhIBnnyqeyWJNI+Bww7Es5QZ0wIc1Cmkw=="], + + "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-WrJY6UuiSD/Dh+nwK2qOTu8kdMDlLV3dLMmychIghHPAysWFq1/DGC1pVZx8POE3ZkzKR3PUUnVrtZfMfaJjyQ=="], + + "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.10", "", { "os": "linux", "cpu": "x64" }, "sha512-tZLvEEi2u9Xu1zAqRjTcpIDGVtldigVvzug2fTuPG0ME/g8/mXpRPcNgLB22bGn6FvLJpHHnqLnwliOu8xjYrg=="], + + "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.10", "", { "os": "linux", "cpu": "x64" }, "sha512-kDTi3pI6PBN6CiczsWYOyP2zk0IJI08EWEQyDMQWW221rPaaEz6FvjLhnU07KMzLv8q3qSuoB93ua6inSQ55Tw=="], + + "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.10", "", { "os": "win32", "cpu": "arm64" }, "sha512-umwQU6qPzH+ISTf/eHyJ/QoQnJs3V9Vpjz2OjZXe9MVBZ7prgGafMy7yYeRGnlmDAn87AKTF3Q6weLoMGpeqdQ=="], + + "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.10", "", { "os": "win32", "cpu": "x64" }, "sha512-aW/JU5GuyH4uxMrNYpoC2kjaHlyJGLgIa3XkhPEZI0uKhZhJZU8BuEyJmvgzSPQNGozBwWjC972RaNdcJ9KyJg=="], + + "@cloudflare/kv-asset-handler": ["@cloudflare/kv-asset-handler@0.4.2", "", {}, "sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ=="], + + "@cloudflare/unenv-preset": ["@cloudflare/unenv-preset@2.14.0", "", { "peerDependencies": { "unenv": "2.0.0-rc.24", "workerd": "^1.20260218.0" }, "optionalPeers": ["workerd"] }, "sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg=="], + + "@cloudflare/workerd-darwin-64": ["@cloudflare/workerd-darwin-64@1.20260305.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-chhKOpymo0Eh9J3nymrauMqKGboCc4uz/j0gA1G4gioMnKsN2ZDKJ+qjRZDnCoVGy8u2C4pxlmyIfsXCAfIzhQ=="], + + "@cloudflare/workerd-darwin-arm64": ["@cloudflare/workerd-darwin-arm64@1.20260305.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-K9aG2OQk5bBfOP+fyGPqLcqZ9OR3ra6uwnxJ8f2mveq2A2LsCI7ZeGxQiAj75Ti80ytH/gJffZIx4Np2JtU3aQ=="], + + "@cloudflare/workerd-linux-64": ["@cloudflare/workerd-linux-64@1.20260305.0", "", { "os": "linux", "cpu": "x64" }, "sha512-tt7XUoIw/cYFeGbkPkcZ6XX1aZm26Aju/4ih+DXxOosbBeGshFSrNJDBfAKKOvkjsAZymJ+WWVDBU+hmNaGfwA=="], + + "@cloudflare/workerd-linux-arm64": ["@cloudflare/workerd-linux-arm64@1.20260305.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-72QTkY5EzylmvCZ8ZTrnJ9DctmQsfSof1OKyOWqu/pv/B2yACfuPMikq8RpPxvVu7hhS0ztGP6ZvXz72Htq4Zg=="], + + "@cloudflare/workerd-windows-64": ["@cloudflare/workerd-windows-64@1.20260305.0", "", { "os": "win32", "cpu": "x64" }, "sha512-BA0uaQPOaI2F6mJtBDqplGnQQhpXCzwEMI33p/TnDxtSk9u8CGIfBFuI6uqo8mJ6ijIaPjeBLGOn2CiRMET4qg=="], + + "@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="], + + "@docsearch/css": ["@docsearch/css@3.8.2", "", {}, "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ=="], + + "@docsearch/js": ["@docsearch/js@3.8.2", "", { "dependencies": { "@docsearch/react": "3.8.2", "preact": "^10.0.0" } }, "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ=="], + + "@docsearch/react": ["@docsearch/react@3.8.2", "", { "dependencies": { "@algolia/autocomplete-core": "1.17.7", "@algolia/autocomplete-preset-algolia": "1.17.7", "@docsearch/css": "3.8.2", "algoliasearch": "^5.14.2" }, "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" }, "optionalPeers": ["@types/react", "react", "react-dom", "search-insights"] }, "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg=="], + + "@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.3", "", { "os": "android", "cpu": "arm64" }, "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.27.3", "", { "os": "android", "cpu": "x64" }, "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.3", "", { "os": "linux", "cpu": "arm" }, "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.3", "", { "os": "linux", "cpu": "ia32" }, "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.3", "", { "os": "linux", "cpu": "none" }, "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.3", "", { "os": "linux", "cpu": "x64" }, "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.3", "", { "os": "none", "cpu": "x64" }, "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.3", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.3", "", { "os": "none", "cpu": "arm64" }, "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.3", "", { "os": "sunos", "cpu": "x64" }, "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + + "@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.71", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-rNoDFbq1fAYiEexBvrw613/xiUOPEu5MKVV/X8lI64AgdTzLQUUemr9f9fplxUMPoxCBP2rWzlhOEeTHk/Sf0Q=="], + + "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], + + "@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="], + + "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="], + + "@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="], + + "@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="], + + "@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="], + + "@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="], + + "@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="], + + "@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="], + + "@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="], + + "@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="], + + "@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="], + + "@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="], + + "@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="], + + "@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="], + + "@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="], + + "@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="], + + "@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="], + + "@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="], + + "@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="], + + "@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="], + + "@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="], + + "@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="], + + "@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="], + + "@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="], + + "@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="], + + "@poppinss/colors": ["@poppinss/colors@4.1.6", "", { "dependencies": { "kleur": "^4.1.5" } }, "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg=="], + + "@poppinss/dumper": ["@poppinss/dumper@0.6.5", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@sindresorhus/is": "^7.0.2", "supports-color": "^10.0.0" } }, "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw=="], + + "@poppinss/exception": ["@poppinss/exception@1.2.3", "", {}, "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.59.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.59.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.59.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.59.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.59.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.59.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.59.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.59.0", "", { "os": "linux", "cpu": "none" }, "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.59.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.59.0", "", { "os": "linux", "cpu": "x64" }, "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.59.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.59.0", "", { "os": "none", "cpu": "arm64" }, "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.59.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.59.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.59.0", "", { "os": "win32", "cpu": "x64" }, "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA=="], + + "@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="], + + "@shikijs/langs": ["@shikijs/langs@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w=="], + + "@shikijs/themes": ["@shikijs/themes@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw=="], + + "@shikijs/transformers": ["@shikijs/transformers@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/types": "2.5.0" } }, "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg=="], + + "@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@sindresorhus/is": ["@sindresorhus/is@7.2.0", "", {}, "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw=="], + + "@speed-highlight/core": ["@speed-highlight/core@1.2.14", "", {}, "sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA=="], + + "@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="], + + "@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], + + "@types/node": ["@types/node@25.5.2", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "@vitejs/plugin-vue": ["@vitejs/plugin-vue@5.2.4", "", { "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA=="], + + "@vue/compiler-core": ["@vue/compiler-core@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/shared": "3.5.29", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw=="], + + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.29", "", { "dependencies": { "@vue/compiler-core": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg=="], + + "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.29", "", { "dependencies": { "@babel/parser": "^7.29.0", "@vue/compiler-core": "3.5.29", "@vue/compiler-dom": "3.5.29", "@vue/compiler-ssr": "3.5.29", "@vue/shared": "3.5.29", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.6", "source-map-js": "^1.2.1" } }, "sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA=="], + + "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.29", "", { "dependencies": { "@vue/compiler-dom": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw=="], + + "@vue/devtools-api": ["@vue/devtools-api@7.7.9", "", { "dependencies": { "@vue/devtools-kit": "^7.7.9" } }, "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g=="], + + "@vue/devtools-kit": ["@vue/devtools-kit@7.7.9", "", { "dependencies": { "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA=="], + + "@vue/devtools-shared": ["@vue/devtools-shared@7.7.9", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA=="], + + "@vue/reactivity": ["@vue/reactivity@3.5.29", "", { "dependencies": { "@vue/shared": "3.5.29" } }, "sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA=="], + + "@vue/runtime-core": ["@vue/runtime-core@3.5.29", "", { "dependencies": { "@vue/reactivity": "3.5.29", "@vue/shared": "3.5.29" } }, "sha512-8DpW2QfdwIWOLqtsNcds4s+QgwSaHSJY/SUe04LptianUQ/0xi6KVsu/pYVh+HO3NTVvVJjIPL2t6GdeKbS4Lg=="], + + "@vue/runtime-dom": ["@vue/runtime-dom@3.5.29", "", { "dependencies": { "@vue/reactivity": "3.5.29", "@vue/runtime-core": "3.5.29", "@vue/shared": "3.5.29", "csstype": "^3.2.3" } }, "sha512-AHvvJEtcY9tw/uk+s/YRLSlxxQnqnAkjqvK25ZiM4CllCZWzElRAoQnCM42m9AHRLNJ6oe2kC5DCgD4AUdlvXg=="], + + "@vue/server-renderer": ["@vue/server-renderer@3.5.29", "", { "dependencies": { "@vue/compiler-ssr": "3.5.29", "@vue/shared": "3.5.29" }, "peerDependencies": { "vue": "3.5.29" } }, "sha512-G/1k6WK5MusLlbxSE2YTcqAAezS+VuwHhOvLx2KnQU7G2zCH6KIb+5Wyt6UjMq7a3qPzNEjJXs1hvAxDclQH+g=="], + + "@vue/shared": ["@vue/shared@3.5.29", "", {}, "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg=="], + + "@vueuse/core": ["@vueuse/core@12.8.2", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" } }, "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ=="], + + "@vueuse/integrations": ["@vueuse/integrations@12.8.2", "", { "dependencies": { "@vueuse/core": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7" }, "optionalPeers": ["async-validator", "axios", "change-case", "drauu", "focus-trap", "fuse.js", "idb-keyval", "jwt-decode", "nprogress", "qrcode", "sortablejs", "universal-cookie"] }, "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g=="], + + "@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="], + + "@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="], + + "algoliasearch": ["algoliasearch@5.49.1", "", { "dependencies": { "@algolia/abtesting": "1.15.1", "@algolia/client-abtesting": "5.49.1", "@algolia/client-analytics": "5.49.1", "@algolia/client-common": "5.49.1", "@algolia/client-insights": "5.49.1", "@algolia/client-personalization": "5.49.1", "@algolia/client-query-suggestions": "5.49.1", "@algolia/client-search": "5.49.1", "@algolia/ingestion": "1.49.1", "@algolia/monitoring": "1.49.1", "@algolia/recommend": "5.49.1", "@algolia/requester-browser-xhr": "5.49.1", "@algolia/requester-fetch": "5.49.1", "@algolia/requester-node-http": "5.49.1" } }, "sha512-X3Pp2aRQhg4xUC6PQtkubn5NpRKuUPQ9FPDQlx36SmpFwwH2N0/tw4c+NXV3nw3PsgeUs+BuWGP0gjz3TvENLQ=="], + + "birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="], + + "blake3-wasm": ["blake3-wasm@2.1.5", "", {}, "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g=="], + + "bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="], + + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="], + + "copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="], + + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], + + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "error-stack-parser-es": ["error-stack-parser-es@1.0.5", "", {}, "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA=="], + + "esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], + + "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "focus-trap": ["focus-trap@7.8.0", "", { "dependencies": { "tabbable": "^6.4.0" } }, "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="], + + "is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="], + + "kleur": ["kleur@4.1.5", "", {}, "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "mark.js": ["mark.js@8.11.1", "", {}, "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "miniflare": ["miniflare@4.20260305.0", "", { "dependencies": { "@cspotcode/source-map-support": "0.8.1", "sharp": "^0.34.5", "undici": "7.18.2", "workerd": "1.20260305.0", "ws": "8.18.0", "youch": "4.1.0-beta.10" }, "bin": { "miniflare": "bootstrap.js" } }, "sha512-jVhtKJtiwaZa3rI+WgoLvSJmEazDsoUmAPYRUmEe2VO6VSbvkhbnDRm+dsPbYRatgNIExwrpqG1rv96jHiSb0w=="], + + "minisearch": ["minisearch@7.2.0", "", {}, "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg=="], + + "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="], + + "path-to-regexp": ["path-to-regexp@6.3.0", "", {}, "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + + "preact": ["preact@10.28.4", "", {}, "sha512-uKFfOHWuSNpRFVTnljsCluEFq57OKT+0QdOiQo8XWnQ/pSvg7OpX5eNOejELXJMWy+BwM2nobz0FkvzmnpCNsQ=="], + + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + + "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + + "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="], + + "search-insights": ["search-insights@2.17.3", "", {}, "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ=="], + + "semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="], + + "sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="], + + "shiki": ["shiki@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="], + + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="], + + "supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="], + + "tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="], + + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + + "undici": ["undici@7.18.2", "", {}, "sha512-y+8YjDFzWdQlSE9N5nzKMT3g4a5UBX1HKowfdXh0uvAnTaqqwqB92Jt4UXBAeKekDs5IaDKyJFR4X1gYVCgXcw=="], + + "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + + "unenv": ["unenv@2.0.0-rc.24", "", { "dependencies": { "pathe": "^2.0.3" } }, "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], + + "vitepress": ["vitepress@1.6.4", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg=="], + + "vue": ["vue@3.5.29", "", { "dependencies": { "@vue/compiler-dom": "3.5.29", "@vue/compiler-sfc": "3.5.29", "@vue/runtime-dom": "3.5.29", "@vue/server-renderer": "3.5.29", "@vue/shared": "3.5.29" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-BZqN4Ze6mDQVNAni0IHeMJ5mwr8VAJ3MQC9FmprRhcBYENw+wOAAjRj8jfmN6FLl0j96OXbR+CjWhmAmM+QGnA=="], + + "workerd": ["workerd@1.20260305.0", "", { "optionalDependencies": { "@cloudflare/workerd-darwin-64": "1.20260305.0", "@cloudflare/workerd-darwin-arm64": "1.20260305.0", "@cloudflare/workerd-linux-64": "1.20260305.0", "@cloudflare/workerd-linux-arm64": "1.20260305.0", "@cloudflare/workerd-windows-64": "1.20260305.0" }, "bin": { "workerd": "bin/workerd" } }, "sha512-JkhfCLU+w+KbQmZ9k49IcDYc78GBo7eG8Mir8E2+KVjR7otQAmpcLlsous09YLh8WQ3Bt3Mi6/WMStvMAPukeA=="], + + "wrangler": ["wrangler@4.69.0", "", { "dependencies": { "@cloudflare/kv-asset-handler": "0.4.2", "@cloudflare/unenv-preset": "2.14.0", "blake3-wasm": "2.1.5", "esbuild": "0.27.3", "miniflare": "4.20260305.0", "path-to-regexp": "6.3.0", "unenv": "2.0.0-rc.24", "workerd": "1.20260305.0" }, "optionalDependencies": { "fsevents": "~2.3.2" }, "peerDependencies": { "@cloudflare/workers-types": "^4.20260305.0" }, "optionalPeers": ["@cloudflare/workers-types"], "bin": { "wrangler": "bin/wrangler.js", "wrangler2": "bin/wrangler.js" } }, "sha512-EmVfIM65I5b4ITHe3Y9R7zQyf4NUBQ1leStakMlWiVR9n6VlDwuEltyQI2l3i0JciDnWyR3uqe+T6C08ivniTQ=="], + + "ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="], + + "youch": ["youch@4.1.0-beta.10", "", { "dependencies": { "@poppinss/colors": "^4.1.5", "@poppinss/dumper": "^0.6.4", "@speed-highlight/core": "^1.2.7", "cookie": "^1.0.2", "youch-core": "^0.3.3" } }, "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ=="], + + "youch-core": ["youch-core@0.3.3", "", { "dependencies": { "@poppinss/exception": "^1.2.2", "error-stack-parser-es": "^1.0.5" } }, "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "vite/esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "vite/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "vite/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "vite/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "vite/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "vite/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "vite/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "vite/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "vite/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "vite/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "vite/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "vite/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "vite/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "vite/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "vite/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "vite/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "vite/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "vite/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "vite/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "vite/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "vite/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "vite/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000..361214b --- /dev/null +++ b/website/package.json @@ -0,0 +1,22 @@ +{ + "scripts": { + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview", + "format": "biome format --write .", + "format:check": "biome ci .", + "lint": "biome lint .", + "lint:fix": "biome lint --write .", + "check": "biome check --write .", + "deploy": "wrangler deploy" + }, + "devDependencies": { + "@biomejs/biome": "2.4.10", + "@types/bun": "^1.3.11", + "husky": "^9.1.7", + "vitepress": "^1.6.4" + }, + "dependencies": { + "wrangler": "^4.69.0" + } +} diff --git a/website/src/assets/brand/LICENSE b/website/src/assets/brand/LICENSE new file mode 100644 index 0000000..bff9945 --- /dev/null +++ b/website/src/assets/brand/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 PaperMC Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/website/src/assets/brand/folia.svg b/website/src/assets/brand/folia.svg new file mode 100644 index 0000000..59a821b --- /dev/null +++ b/website/src/assets/brand/folia.svg @@ -0,0 +1,3 @@ +<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> +<path d="M17,8C8,10 5.9,16.17 3.82,21.34L5.71,22L6.66,19.7C7.14,19.87 7.64,20 8,20C19,20 22,3 22,3C21,5 14,5.25 9,6.25C4,7.25 2,11.5 2,13.5C2,15.5 3.75,17.25 3.75,17.25C7,8 17,8 17,8Z" fill="currentColor"/> +</svg> diff --git a/website/src/assets/brand/paper.svg b/website/src/assets/brand/paper.svg new file mode 100644 index 0000000..126e636 --- /dev/null +++ b/website/src/assets/brand/paper.svg @@ -0,0 +1,3 @@ +<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M23.9871 1.00449L20.5586 21.5759C20.5185 21.8303 20.3579 22.0446 20.13 22.1781C20.0027 22.2479 19.8599 22.2847 19.7147 22.2853C19.6044 22.2824 19.4956 22.2597 19.3933 22.2183L13.3263 19.7406L10.0852 23.6917C10.0062 23.7893 9.90612 23.8677 9.79248 23.921C9.67884 23.9744 9.55459 24.0014 9.42905 23.9999C9.32829 24.0017 9.22817 23.9835 9.13446 23.9464C8.96962 23.8865 8.82722 23.7773 8.72657 23.6336C8.62593 23.49 8.57192 23.3188 8.57187 23.1434V18.4686L20.1433 4.28567L5.82693 16.6739L0.536782 14.5044C0.228637 14.3839 0.0278925 14.1029 0.00104276 13.7679C-0.0067358 13.6096 0.029121 13.4521 0.104701 13.3128C0.18028 13.1734 0.292678 13.0575 0.429633 12.9777L22.7146 0.120453C22.8439 0.0420511 22.9921 0.000404741 23.1432 4.67454e-06C23.3151 -0.000564065 23.4831 0.0507774 23.6253 0.147303C23.7607 0.241085 23.8667 0.3715 23.9308 0.523296C23.9949 0.675093 24.0144 0.841995 23.9871 1.00449Z" fill="currentColor"/> +</svg> diff --git a/website/src/assets/brand/velocity.svg b/website/src/assets/brand/velocity.svg new file mode 100644 index 0000000..ee24f2b --- /dev/null +++ b/website/src/assets/brand/velocity.svg @@ -0,0 +1,12 @@ +<svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g clip-path="url(#clip0_313_379)"> +<path d="M15.9489 15.1371L11.7286 9.37874C11.6243 9.23621 11.4813 9.12653 11.3166 9.06265C11.1519 8.99876 10.9724 8.98334 10.7992 9.01821L4.06776 10.3784C3.93676 10.4053 3.81314 10.4603 3.70538 10.5395C3.59762 10.6187 3.50827 10.7203 3.44346 10.8372L0.115968 16.8516C0.0302571 17.0061 -0.00934416 17.1819 0.00185928 17.3583C0.0130627 17.5346 0.0746008 17.7041 0.179177 17.8465L4.40956 23.6213C4.51392 23.7638 4.65689 23.8735 4.82158 23.9374C4.98627 24.0012 5.16581 24.0167 5.33898 23.9818L12.0502 22.6263C12.1813 22.5994 12.305 22.5444 12.4128 22.465C12.5206 22.3857 12.6099 22.2839 12.6745 22.1667L16.0129 16.1344C16.0988 15.9795 16.1384 15.8031 16.1271 15.6264C16.1157 15.4496 16.0539 15.2798 15.9489 15.1371V15.1371ZM11.3096 20.9282C11.2305 20.9864 11.1406 21.0283 11.0453 21.0517C10.9499 21.0751 10.8508 21.0795 10.7538 21.0645C10.6567 21.0496 10.5636 21.0157 10.4796 20.9647C10.3957 20.9137 10.3227 20.8467 10.2647 20.7675L7.84553 17.4712C7.70493 17.2801 7.51283 17.1331 7.29171 17.0473C7.07058 16.9615 6.82959 16.9404 6.59694 16.9866L2.49375 17.8161C2.39752 17.8356 2.2984 17.8359 2.20205 17.8171C2.10569 17.7982 2.01399 17.7606 1.93218 17.7063C1.85036 17.652 1.78004 17.5822 1.72523 17.5007C1.67042 17.4193 1.63218 17.3278 1.61272 17.2316C1.57333 17.0376 1.6125 16.8359 1.72163 16.6707C1.83077 16.5055 2.00096 16.3904 2.19487 16.3506L6.64298 15.4516C6.81991 15.4157 6.98695 15.3418 7.13259 15.2351C7.27823 15.1284 7.39899 14.9914 7.48656 14.8335L9.71919 10.8021C9.81511 10.629 9.97577 10.501 10.1659 10.4461C10.3561 10.3912 10.5603 10.414 10.7337 10.5095C10.9068 10.6054 11.0348 10.7661 11.0897 10.9562C11.1446 11.1464 11.1218 11.3506 11.0263 11.524L8.96926 15.2502C8.8545 15.4584 8.80155 15.695 8.81662 15.9322C8.83168 16.1694 8.91415 16.3974 9.05432 16.5894L11.4735 19.8849C11.5899 20.045 11.638 20.2448 11.6073 20.4404C11.5766 20.636 11.4695 20.8115 11.3096 20.9282V20.9282Z" fill="currentColor"/> +<path d="M30.0103 16.182C30.4339 16.182 30.7774 15.8385 30.7774 15.4149C30.7774 14.9912 30.4339 14.6478 30.0103 14.6478C29.5866 14.6478 29.2432 14.9912 29.2432 15.4149C29.2432 15.8385 29.5866 16.182 30.0103 16.182Z" fill="currentColor"/> +<path d="M33.2757 17.7162H19.4031C19.1997 17.7162 19.0046 17.6354 18.8607 17.4915C18.7168 17.3477 18.636 17.1525 18.636 16.9491C18.636 16.7457 18.7168 16.5505 18.8607 16.4067C19.0046 16.2628 19.1997 16.182 19.4031 16.182H27.6922C27.8915 16.1756 28.0805 16.092 28.2193 15.9488C28.358 15.8055 28.4356 15.6139 28.4356 15.4145C28.4356 15.2151 28.358 15.0235 28.2193 14.8803C28.0805 14.737 27.8915 14.6534 27.6922 14.647H22.214C22.0106 14.647 21.8154 14.5662 21.6716 14.4223C21.5277 14.2785 21.4469 14.0834 21.4469 13.8799C21.4469 13.6765 21.5277 13.4813 21.6716 13.3375C21.8154 13.1936 22.0106 13.1128 22.214 13.1128H30.514C30.7133 13.1064 30.9024 13.0228 31.0411 12.8796C31.1798 12.7363 31.2574 12.5447 31.2574 12.3453C31.2574 12.1459 31.1798 11.9543 31.0411 11.8111C30.9024 11.6678 30.7133 11.5842 30.514 11.5778H13.3404L15.9484 15.1371C16.0528 15.2796 16.1143 15.449 16.1255 15.6253C16.1367 15.8016 16.0972 15.9775 16.0116 16.1321L12.6732 22.1643C12.6423 22.22 12.6057 22.2723 12.564 22.3204H29.1304C29.3339 22.3204 29.529 22.2396 29.6728 22.0957C29.8167 21.9518 29.8975 21.7567 29.8975 21.5533C29.8975 21.3498 29.8167 21.1547 29.6728 21.0109C29.529 20.867 29.3339 20.7862 29.1304 20.7862H24.9531C24.8503 20.7895 24.7478 20.772 24.6518 20.7349C24.5558 20.6978 24.4683 20.6418 24.3944 20.5702C24.3205 20.4987 24.2617 20.4129 24.2216 20.3182C24.1814 20.2234 24.1607 20.1216 24.1607 20.0187C24.1607 19.9158 24.1814 19.8139 24.2216 19.7192C24.2617 19.6244 24.3205 19.5387 24.3944 19.4671C24.4683 19.3955 24.5558 19.3395 24.6518 19.3024C24.7478 19.2653 24.8503 19.2479 24.9531 19.2512H33.2757C33.3786 19.2545 33.4811 19.237 33.577 19.2C33.673 19.1629 33.7606 19.1069 33.8345 19.0353C33.9084 18.9637 33.9672 18.8779 34.0073 18.7832C34.0474 18.6884 34.0681 18.5866 34.0681 18.4837C34.0681 18.3808 34.0474 18.2789 34.0073 18.1842C33.9672 18.0894 33.9084 18.0037 33.8345 17.9321C33.7606 17.8605 33.673 17.8045 33.577 17.7674C33.4811 17.7303 33.3786 17.7129 33.2757 17.7162V17.7162Z" fill="currentColor"/> +</g> +<defs> +<clipPath id="clip0_313_379"> +<rect width="34" height="34" fill="white"/> +</clipPath> +</defs> +</svg> diff --git a/website/src/assets/features/channel-chat.png b/website/src/assets/features/channel-chat.png Binary files differnew file mode 100644 index 0000000..4f9dab2 --- /dev/null +++ b/website/src/assets/features/channel-chat.png diff --git a/website/src/assets/features/cross-chat.png b/website/src/assets/features/cross-chat.png Binary files differnew file mode 100644 index 0000000..34857e2 --- /dev/null +++ b/website/src/assets/features/cross-chat.png diff --git a/website/src/assets/features/dm.png b/website/src/assets/features/dm.png Binary files differnew file mode 100644 index 0000000..bcc429d --- /dev/null +++ b/website/src/assets/features/dm.png diff --git a/website/src/assets/features/romaji.png b/website/src/assets/features/romaji.png Binary files differnew file mode 100644 index 0000000..fd1dd9b --- /dev/null +++ b/website/src/assets/features/romaji.png diff --git a/website/src/assets/icon.png b/website/src/assets/icon.png Binary files differnew file mode 100644 index 0000000..064445a --- /dev/null +++ b/website/src/assets/icon.png diff --git a/website/src/docs/configuration.md b/website/src/docs/configuration.md new file mode 100644 index 0000000..8e603de --- /dev/null +++ b/website/src/docs/configuration.md @@ -0,0 +1,73 @@ +--- +layout: doc +--- + +# 設定 + +LunaticChat の設定は `plugins/LunaticChat/config.yml` で管理されます.サーバーの初回起動時にデフォルトの設定ファイルが生成されます. + +## グローバル設定 + +| キー | 型 | デフォルト | 説明 | +|------|------|------------|------| +| `debug` | Boolean | `false` | デバッグログを有効にする | +| `userSettingsFilePath` | String | `"player-settings.yaml"` | プレイヤー設定ファイルのパス | +| `checkForUpdates` | Boolean | `true` | 起動時にアップデートを確認する | +| `language` | String | `"en"` | プラグインの言語 (`en` / `ja`) | + +## 機能設定 (`features`) + +### クイックリプライ (`features.quickReplies`) + +| キー | 型 | デフォルト | 説明 | +|------|------|------------|------| +| `enabled` | Boolean | `true` | `/reply` コマンドを有効にする | + +### ローマ字変換 (`features.japaneseConversion`) + +| キー | 型 | デフォルト | 説明 | +|------|------|------------|------| +| `enabled` | Boolean | `false` | ローマ字→ひらがな変換を有効にする | +| `cache.maxEntries` | Int | `500` | 変換キャッシュの最大エントリ数 | +| `cache.saveIntervalSeconds` | Int | `300` | キャッシュのディスク保存間隔(秒) | +| `cache.filePath` | String | `"conversion_cache.json"` | キャッシュファイルのパス | +| `api.timeout` | Long | `3000` | API リクエストのタイムアウト(ミリ秒) | +| `api.retryAttempts` | Int | `2` | API リクエスト失敗時のリトライ回数 | + +### チャンネルチャット (`features.channelChat`) + +| キー | 型 | デフォルト | 説明 | +|------|------|------------|------| +| `enabled` | Boolean | `false` | チャンネルチャット機能を有効にする | +| `maxChannelsPerServer` | Int | `0` | サーバーあたりの最大チャンネル数(`0` = 無制限) | +| `maxMembersPerChannel` | Int | `0` | チャンネルあたりの最大メンバー数(`0` = 無制限) | +| `maxMembershipPerPlayer` | Int | `0` | プレイヤーあたりの最大参加チャンネル数(`0` = 無制限) | + +#### メッセージログ (`features.channelChat.messageLogging`) + +| キー | 型 | デフォルト | 説明 | +|------|------|------------|------| +| `enabled` | Boolean | `true` | チャンネルメッセージを NDJSON ファイルに記録する | +| `retentionDays` | Int | `30` | ログファイルの保持日数(`0` = 無期限) | +| `maxFileSizeMB` | Int | `100` | 単一ログファイルの最大サイズ(MB) | + +### Velocity 連携 (`features.velocityIntegration`) + +| キー | 型 | デフォルト | 説明 | +|------|------|------------|------| +| `enabled` | Boolean | `false` | Velocity プロキシとの連携を有効にする | +| `crossServerGlobalChat` | Boolean | `false` | サーバー間グローバルチャットを有効にする | +| `serverName` | String | `"Unknown"` | クロスサーバーチャットで表示されるサーバー名 | +| `messageDeduplicationCacheSize` | Int | `100` | メッセージ重複排除キャッシュのサイズ | + +## メッセージフォーマット (`messageFormat`) + +| キー | デフォルト | 利用可能なプレースホルダー | +|------|------------|--------------------------| +| `directMessageFormat` | `§7[§e{sender} §7>> §e{recipient}§7] §f{message}` | `{sender}`, `{recipient}`, `{message}` | +| `channelMessageFormat` | `§7[§b#{channel}§7] §e{sender}: §f{message}` | `{sender}`, `{message}`, `{channel}` | +| `crossServerGlobalChatFormat` | `§7[§6{server}§7] §e{sender}: §f{message}` | `{sender}`, `{message}`, `{server}` | + +## デフォルト設定ファイル + +[GitHub で確認する](https://github.com/m1sk9/LunaticChat/blob/main/platform-paper/src/main/resources/config.yml) diff --git a/website/src/docs/features/admin.md b/website/src/docs/features/admin.md new file mode 100644 index 0000000..57d38c0 --- /dev/null +++ b/website/src/docs/features/admin.md @@ -0,0 +1,74 @@ +--- +layout: doc +--- + +# 管理者向け機能 + +サーバー管理者向けの機能をまとめて解説します.これらの機能は主に OP 権限を持つプレイヤーが利用できます. + +## プラグインステータス (`/lc status`) + +プラグインの動作状況を一覧で確認できます. + +``` +/lc status +``` + +表示される情報: + +- プラグインバージョン (Git コミットハッシュ付き) +- ヘルスステータス (OK / Degraded) +- 各機能の有効/無効状態 +- 設定値 (デバッグモード,アップデート確認,言語) +- GitHub,Modrinth,ドキュメントへのリンク + +## スパイモード + +`lunaticchat.spy` パーミッション (デフォルト: op) を持つプレイヤーは,サーバー上で送受信されるすべてのダイレクトメッセージを閲覧できます. + +- スパイプレイヤーにはローマ字変換前の元のメッセージが表示されます +- ホバーテキストでスパイメッセージであることが示されます +- スパイプレイヤー自身は通常の送受信者リストには含まれません + +## チャンネルバイパス + +`lunaticchat.channelbypass` パーミッション (デフォルト: op) を持つプレイヤーは,チャンネルに関する以下の制限を無視できます. + +- キック・BAN の対象にならない +- オーナーでなくてもチャンネルを削除できる + +## アップデート通知 + +`checkForUpdates` が `true` (デフォルト) の場合,プラグインは起動時に新しいバージョンが利用可能か確認します.`lunaticchat.noticeupdate` パーミッション (デフォルト: op) を持つプレイヤーがサーバーに参加した際にアップデート通知が表示されます. + +```yaml +# config.yml +checkForUpdates: true +``` + +## デバッグモード + +`debug` を `true` にすると,プラグインの詳細なログが出力されます.問題の調査やバグ報告時に有用です. + +```yaml +# config.yml +debug: true +``` + +## 言語設定 + +プレイヤーに表示されるメッセージの言語を切り替えられます.プラグインログやコンソール出力には影響せず,英語のみ出力となります. + +```yaml +# config.yml +language: "ja" # "en" または "ja" +``` + +## 管理者パーミッション一覧 + +| パーミッション | デフォルト | 説明 | +|---------------|-----------|------| +| `lunaticchat.spy` | op | 全ダイレクトメッセージの閲覧 | +| `lunaticchat.channelbypass` | op | チャンネル制限のバイパス | +| `lunaticchat.noticeupdate` | op | アップデート通知の受信 | +| `lunaticchat.command.lcv.status` | op | `/lcv status` コマンドの使用 | diff --git a/website/src/docs/features/channel-chat.md b/website/src/docs/features/channel-chat.md new file mode 100644 index 0000000..b0caa43 --- /dev/null +++ b/website/src/docs/features/channel-chat.md @@ -0,0 +1,92 @@ +--- +layout: doc +--- + +# チャンネルチャット + +チャンネルを作成してグループごとに会話を分離できます.この機能を利用するには `config.yml` で `features.channelChat.enabled` を `true` に設定してください. + +## チャンネルの作成 + +``` +/lc channel create <channelId> <name> [description] [isPrivate] +``` + +- `channelId`: チャンネルの一意な識別子 (英数字, `_`, `-` のみ, 3〜30文字) +- `name`: チャンネルの表示名 +- `description`: チャンネルの説明 (省略可) +- `isPrivate`: プライベートチャンネルにする場合は `true` (デフォルト: `false`) + +作成者は自動的にオーナーになります. + +## チャンネルへの参加・退出 + +``` +/lc channel join <channelId> # チャンネルに参加 +/lc channel leave # アクティブチャンネルから退出 +/lc channel switch <channelId> # アクティブチャンネルを切り替え +``` + +プライベートチャンネルに参加するには,オーナーまたはモデレーターからの招待が必要です. + +## アクティブチャンネル + +プレイヤーは複数のチャンネルに参加できますが,一度にアクティブにできるチャンネルは1つです.チャットメッセージはアクティブチャンネルに送信されます.`/lc channel switch` でアクティブチャンネルを切り替えられます. + +``` +/lc channel status # 現在のアクティブチャンネルと参加チャンネル一覧を表示 +``` + +## ロールと権限 + +チャンネルには3つのロールがあります. + +| ロール | 権限 | +|--------|------| +| **OWNER** | チャンネルの削除,モデレーター管理,オーナー譲渡,メンバー管理 | +| **MODERATOR** | メンバーの招待,キック,BAN/BAN解除 | +| **MEMBER** | チャットへの参加,チャンネル情報の閲覧 | + +### モデレーター管理 (オーナーのみ) + +``` +/lc channel mod <playerName> # モデレーター権限の付与/剥奪 +/lc channel ownership <playerName> # オーナー権限の譲渡 +``` + +### メンバー管理 (オーナー / モデレーター) + +``` +/lc channel invite <playerName> # プレイヤーを招待 +/lc channel kick <playerName> # プレイヤーをキック +/lc channel ban <playerName> # プレイヤーを BAN +/lc channel unban <playerName> # BAN を解除 +``` + +## 制限設定 + +`config.yml` でチャンネルの上限を設定できます (すべて `0` で無制限) . + +| 設定キー | 説明 | +|----------|------| +| `maxChannelsPerServer` | サーバーあたりの最大チャンネル数 | +| `maxMembersPerChannel` | チャンネルあたりの最大メンバー数 | +| `maxMembershipPerPlayer` | プレイヤーあたりの最大参加チャンネル数 | + +## メッセージログ + +チャンネルメッセージは NDJSON 形式でログファイルに記録できます.ファイルは日次でローテーションされ,`maxFileSizeMB` を超えるとサフィックス付きの新しいファイルが作成されます. + +```json +{"timestamp":"2026-04-05T14:23:45.123Z","playerId":"550e8400-...","playerName":"Steve","channelId":"general","message":"Hello!"} +``` + +ログ設定の詳細は[設定ページ](/docs/configuration)の `features.channelChat.messageLogging` を参照してください. + +## バイパス権限 + +`lunaticchat.channelbypass` パーミッション (デフォルト: op) を持つプレイヤーは,キック・BAN の保護やチャンネルの強制削除が可能です. + +## メッセージフォーマット + +チャンネルメッセージの表示形式は `config.yml` の `messageFormat.channelMessageFormat` でカスタマイズできます.詳細は[メッセージフォーマット](/docs/reference/message-format)を参照してください. diff --git a/website/src/docs/features/direct-message.md b/website/src/docs/features/direct-message.md new file mode 100644 index 0000000..7b12aff --- /dev/null +++ b/website/src/docs/features/direct-message.md @@ -0,0 +1,52 @@ +--- +layout: doc +--- + +# ダイレクトメッセージ + +プレイヤー間で 1対1 のプライベートメッセージを送受信できます. + +## 基本的な使い方 + +### メッセージの送信 + +``` +/tell <player> <message> +``` + +エイリアス: `/t`, `/msg`, `/m`, `/w`, `/whisper` + +指定したプレイヤーにダイレクトメッセージを送信します.受信したメッセージをクリックすると,送信者への返信コマンドが自動入力されます. + +### クイック返信 + +``` +/reply <message> +``` + +エイリアス: `/r` + +最後にメッセージを送ってきたプレイヤーに返信します.該当するプレイヤーがいない場合は,最後にメッセージを送った相手に送信されます. + +クイック返信を利用するには `config.yml` で `features.quickReplies.enabled` が `true` (デフォルト) である必要があります. + +## 通知設定 + +プレイヤーはダイレクトメッセージ受信時のサウンド通知を個別に制御できます. + +``` +/lc settings notice on # 通知を有効化 +/lc settings notice off # 通知を無効化 +``` + +## ローマ字変換との連携 + +[ローマ字変換](/docs/features/japanese-conversion)が有効な場合,ダイレクトメッセージの内容も自動的に日本語に変換されます.変換はプレイヤーの `japanese` 設定に従います. + +## スパイ機能 + +`lunaticchat.spy` パーミッション (デフォルト: op) を持つプレイヤーは,サーバー上のすべてのダイレクトメッセージを閲覧できます.スパイプレイヤーには変換前のメッセージが表示されます. + +## メッセージフォーマット + +ダイレクトメッセージの表示形式は `config.yml` の `messageFormat.directMessageFormat` でカスタマイズできます.詳細は[メッセージフォーマット](/docs/reference/message-format)を参照してください. diff --git a/website/src/docs/features/japanese-conversion.md b/website/src/docs/features/japanese-conversion.md new file mode 100644 index 0000000..e5e751b --- /dev/null +++ b/website/src/docs/features/japanese-conversion.md @@ -0,0 +1,62 @@ +--- +layout: doc +--- + +# ローマ字変換 + +ローマ字で入力したチャットメッセージを自動的に日本語に変換します.この機能を利用するには `config.yml` で `features.japaneseConversion.enabled` を `true` に設定してください. + +## 変換の仕組み + +変換は2段階で行われます. + +1. **ローマ字 → ひらがな**: プラグイン内蔵の Trie ベースの変換エンジンでローマ字をひらがなに変換します +2. **ひらがな → 漢字/カナ**: Google IME API を使用してひらがなを自然な日本語に変換します + +### 変換例 + +``` +入力: konnichiha sekai +変換1: こんにちは せかい +変換2: こんにちは 世界 +``` + +## 変換対象 + +- 通常チャット +- ダイレクトメッセージ (`/tell`, `/reply`) +- チャンネルチャット + +入力が有効なローマ字でない場合 (英単語などが含まれる場合),変換は行われずそのまま送信されます. + +## プレイヤー設定 + +プレイヤーは個別に変換のオン/オフを切り替えられます. + +``` +/lc settings japanese on # 変換を有効化 +/lc settings japanese off # 変換を無効化 +``` + +## キャッシュ + +変換結果は単語単位でキャッシュされ,同じ単語の再変換時には API を呼び出さずにキャッシュから取得します.キャッシュは JSON ファイルとしてディスクに定期保存されます. + +| 設定キー | デフォルト | 説明 | +|----------|-----------|------| +| `cache.maxEntries` | `500` | キャッシュの最大エントリ数 | +| `cache.saveIntervalSeconds` | `300` | ディスク保存の間隔 (秒) | +| `cache.filePath` | `"conversion_cache.json"` | キャッシュファイルのパス | + +キャッシュが上限に達すると,古いエントリの10%が自動的に削除されます. + +## API 設定 + +Google IME API への接続に関する設定です. + +| 設定キー | デフォルト | 説明 | +|----------|-----------|------| +| `api.timeout` | `3000` | リクエストタイムアウト (ミリ秒) | +| `api.retryAttempts` | `2` | 失敗時のリトライ回数 | + +API がタイムアウトまたは失敗した場合,ひらがなのまま送信されます. diff --git a/website/src/docs/features/message-logging.md b/website/src/docs/features/message-logging.md new file mode 100644 index 0000000..944b9e9 --- /dev/null +++ b/website/src/docs/features/message-logging.md @@ -0,0 +1,94 @@ +--- +layout: doc +--- + +# メッセージログ + +チャンネルチャットのメッセージを NDJSON (Newline Delimited JSON) 形式でファイルに記録します.この機能はチャンネルチャットが有効な場合に利用でき,デフォルトで有効です. + +## 設定 + +```yaml +# config.yml +features: + channelChat: + enabled: true + messageLogging: + enabled: true + retentionDays: 30 + maxFileSizeMB: 100 +``` + +| 設定キー | デフォルト | 説明 | +|----------|-----------|------| +| `enabled` | `true` | メッセージログを有効にする | +| `retentionDays` | `30` | ログファイルの保持日数 (`0` で無期限保持) | +| `maxFileSizeMB` | `100` | 単一ログファイルの最大サイズ (MB) | + +## ログファイルの形式 + +ログファイルは `plugins/LunaticChat/logs/` ディレクトリに保存されます.各行が1つの JSON オブジェクトです. + +### ファイル名 + +``` +channel-messages-YYYY-MM-dd.json +``` + +ファイルサイズが `maxFileSizeMB` を超えた場合,サフィックス付きの新しいファイルが作成されます. + +``` +channel-messages-2026-04-05.json # 基本ファイル +channel-messages-2026-04-05-1.json # サイズ超過時 +channel-messages-2026-04-05-2.json # さらに超過時 +``` + +### エントリ形式 + +各行は以下の JSON 構造を持ちます. + +```json +{ + "timestamp": "2026-04-05T14:23:45.123Z", + "playerId": "550e8400-e29b-41d4-a716-446655440000", + "playerName": "Steve", + "channelId": "general", + "message": "Hello everyone!" +} +``` + +| フィールド | 型 | 説明 | +|-----------|------|------| +| `timestamp` | String | ISO 8601 形式のタイムスタンプ (UTC) | +| `playerId` | String | プレイヤーの UUID | +| `playerName` | String | プレイヤーの表示名 | +| `channelId` | String | メッセージが送信されたチャンネルの ID | +| `message` | String | メッセージの内容 | + +## ファイルローテーション + +- **日次ローテーション**: 日付が変わると新しいファイルが作成されます +- **サイズローテーション**: `maxFileSizeMB` を超えるとサフィックス付きファイルに切り替わります +- **自動クリーンアップ**: `retentionDays` で指定した日数を超えたログファイルは自動的に削除されます (`0` の場合は削除されません) + +## ログの活用例 + +NDJSON 形式のため,`jq` などのツールで簡単にフィルタリング・集計が可能です. + +### 特定チャンネルのメッセージを抽出 + +```bash +jq 'select(.channelId == "general")' channel-messages-2026-04-05.json +``` + +### 特定プレイヤーのメッセージを抽出 + +```bash +jq 'select(.playerName == "Steve")' channel-messages-2026-04-05.json +``` + +### メッセージ数をチャンネルごとに集計 + +```bash +jq -s 'group_by(.channelId) | map({channel: .[0].channelId, count: length})' channel-messages-2026-04-05.json +``` diff --git a/website/src/docs/features/velocity.md b/website/src/docs/features/velocity.md new file mode 100644 index 0000000..d1394ec --- /dev/null +++ b/website/src/docs/features/velocity.md @@ -0,0 +1,109 @@ +--- +layout: doc +--- + +# Velocity 連携 + +Velocity プロキシを経由して複数の Paper / Folia サーバー間でグローバルチャットをリレーします. + +## セットアップ + +### 1. Velocity プラグインの導入 + +`LunaticChat-<version>-velocity.jar` を Velocity の `plugins/` ディレクトリに配置し,プロキシを再起動します. + +### 2. Paper 側の設定 + +各 Paper サーバーの `config.yml` で以下を設定します. + +```yaml +features: + velocityIntegration: + enabled: true + crossServerGlobalChat: true + serverName: "survival" # Velocity 設定のサーバー名に合わせる +``` + +### 3. 接続の確認 + +``` +/lcv status +``` + +接続状態,プロトコルバージョン,Velocity プラグインのバージョンなどを確認できます (パーミッション: `lunaticchat.command.lcv.status`, デフォルト: op) . + +## クロスサーバーグローバルチャット + +`crossServerGlobalChat` を `true` にすると,プレイヤーのチャットメッセージが Velocity を経由して他のすべての Paper サーバーに中継されます. + +### メッセージの流れ + +1. プレイヤーがチャットメッセージを送信 +2. Paper サーバーがメッセージを Velocity に送信 +3. Velocity が送信元以外の全サーバーにメッセージを中継 +4. 各サーバーのプレイヤーにメッセージが表示される + +### メッセージ重複排除 + +各メッセージに一意な ID が付与され,キャッシュにより同じメッセージが重複して表示されることを防ぎます.キャッシュサイズは `messageDeduplicationCacheSize` (デフォルト: `100`) で設定できます. + +## プロトコルバージョン + +Paper と Velocity 間の互換性はプロトコルバージョンで管理されます.接続時にハンドシェイクが行われ,互換性のないバージョン同士では接続が拒否されます. + +### バージョンバンプルール + +| レベル | 変更例 | 互換性 | デプロイ順序 | +|--------|--------|--------|-------------| +| PATCH (1.0.0 → 1.0.1) | optional フィールド追加,新 sub-channel 追加 | 完全互換 (`ignoreUnknownKeys=true` で安全) | 順不同,いつでも | +| MINOR (1.0.x → 1.1.0) | required フィールド追加,既存 sub-channel のセマンティクス変更 | `MIN_SUPPORTED_MINOR` の範囲内で後方互換 | **Velocity を先に更新** → 各 Paper を順次更新 | +| MAJOR (1.x.x → 2.0.0) | ワイヤフォーマット変更,sub-channel 削除/リネーム | 非互換 | **全サーバー同時デプロイ** | + +### 互換性判定 + +ハンドシェイク時に以下のルールで互換性が判定されます: + +- **MAJOR** が一致すること +- リモートの **MINOR** が `MIN_SUPPORTED_MINOR` 以上かつ自身の MINOR 以下であること +- **PATCH** は互換性判定に影響しない + +#### 例: Velocity がプロトコル 1.2.0 で `MIN_SUPPORTED_MINOR=1` の場合 + +| Paper プロトコル | 結果 | +|-----------------|------| +| 1.1.x | 接続 OK | +| 1.2.x | 接続 OK | +| 1.0.x | 拒否 (`MIN_SUPPORTED_MINOR` より古い) | +| 1.3.x | 拒否 (Velocity より新しい) | +| 2.0.x | 拒否 (MAJOR 不一致) | + +### 運用サイクル + +1. **プロトコル変更なし** → Paper / Velocity を独立にデプロイ可能 +2. **PATCH 変更** → どちら側からでも自由にデプロイ +3. **MINOR 変更** → Velocity を先行更新し,`MIN_SUPPORTED_MINOR` で旧 Paper の猶予期間を設定.全 Paper 更新後に `MIN_SUPPORTED_MINOR` を引き上げ +4. **MAJOR 変更** → メンテナンスウィンドウで一括更新 + +## 接続状態 + +| 状態 | 説明 | +|------|------| +| `DISCONNECTED` | 未接続 | +| `HANDSHAKING` | ハンドシェイク中 | +| `CONNECTED` | 接続済み | +| `FAILED` | 接続失敗 | + +ハンドシェイクのタイムアウトは5秒です.タイムアウトした場合,状態は `FAILED` になります. + +## 設定一覧 + +| 設定キー | デフォルト | 説明 | +|----------|-----------|------| +| `enabled` | `false` | Velocity 連携を有効にする | +| `crossServerGlobalChat` | `false` | クロスサーバーグローバルチャットを有効にする | +| `serverName` | `"Unknown"` | クロスサーバーチャットで表示されるサーバー名 | +| `messageDeduplicationCacheSize` | `100` | メッセージ重複排除キャッシュのサイズ | + +## メッセージフォーマット + +クロスサーバーチャットの表示形式は `config.yml` の `messageFormat.crossServerGlobalChatFormat` でカスタマイズできます.詳細は[メッセージフォーマット](/docs/reference/message-format)を参照してください. diff --git a/website/src/docs/getting-started.md b/website/src/docs/getting-started.md new file mode 100644 index 0000000..63b52d5 --- /dev/null +++ b/website/src/docs/getting-started.md @@ -0,0 +1,47 @@ +--- +layout: doc +--- + +# はじめる + +LunaticChat を導入するための手順を説明します. + +## 動作要件 + +| 項目 | 要件 | +|------|------| +| Minecraft | 26.1 以降 | +| Java | 25 以降 | +| サーバー | Paper, Folia, または Velocity | + +## ダウンロード + +以下のいずれかからプラグイン JAR をダウンロードできます. + +- [GitHub Releases](https://github.com/m1sk9/LunaticChat/releases) +- [Modrinth](https://modrinth.com/project/lunaticchat) + +Paper / Folia サーバーには `LunaticChat-<version>.jar` を,Velocity プロキシには `LunaticChat-<version>-velocity.jar` を使用してください. + +## インストール + +### Paper / Folia + +1. ダウンロードした `LunaticChat-<version>.jar` をサーバーの `plugins/` ディレクトリに配置します +2. サーバーを起動 (または再起動) します +3. `plugins/LunaticChat/config.yml` が自動生成されます +4. 必要に応じて[設定](/docs/configuration)を変更し,サーバーを再起動します + +### Velocity + +1. ダウンロードした `LunaticChat-<version>-velocity.jar` を Velocity の `plugins/` ディレクトリに配置します +2. Velocity プロキシを起動 (または再起動) します +3. Paper 側の `config.yml` で `features.velocityIntegration.enabled` を `true` に設定します +4. 詳細は [Velocity 連携](/docs/features/velocity)を参照してください + +## 次のステップ + +- [設定](/docs/configuration) - `config.yml` の全設定項目を確認する +- [ダイレクトメッセージ](/docs/features/direct-message) - DM 機能の使い方 +- [チャンネルチャット](/docs/features/channel-chat) - チャンネル機能の使い方 +- [コマンド一覧](/docs/reference/commands) - 全コマンドのリファレンス diff --git a/website/src/docs/permissions.md b/website/src/docs/permissions.md new file mode 100644 index 0000000..3fb20f5 --- /dev/null +++ b/website/src/docs/permissions.md @@ -0,0 +1,50 @@ +--- +layout: doc +--- + +# パーミッション + +LunaticChat のすべてのパーミッションノードの一覧です. + +## コマンドパーミッション + +すべてのコマンドパーミッションはデフォルトで全プレイヤーに付与されています. + +| パーミッション | 説明 | +|---------------|------| +| `lunaticchat.command.lc` | `/lc` コマンドの使用 | +| `lunaticchat.command.tell` | `/tell` コマンドの使用 | +| `lunaticchat.command.reply` | `/reply` コマンドの使用 | +| `lunaticchat.command.lc.settings` | `/lc settings` の使用 | +| `lunaticchat.command.lc.status` | `/lc status` の使用 | + +### チャンネル関連 + +| パーミッション | 説明 | +|---------------|------| +| `lunaticchat.command.lc.channel` | `/lc channel` の使用 | +| `lunaticchat.command.lc.channel.create` | チャンネルの作成 | +| `lunaticchat.command.lc.channel.list` | チャンネル一覧の表示 | +| `lunaticchat.command.lc.channel.join` | チャンネルへの参加 | +| `lunaticchat.command.lc.channel.leave` | チャンネルからの退出 | +| `lunaticchat.command.lc.channel.switch` | アクティブチャンネルの切り替え | +| `lunaticchat.command.lc.channel.status` | チャンネル参加状況の確認 | +| `lunaticchat.command.lc.channel.info` | チャンネル情報の表示 | +| `lunaticchat.command.lc.channel.delete` | チャンネルの削除 | +| `lunaticchat.command.lc.channel.invite` | チャンネルへの招待 | +| `lunaticchat.command.lc.channel.kick` | チャンネルからのキック | +| `lunaticchat.command.lc.channel.ban` | チャンネルからの BAN | +| `lunaticchat.command.lc.channel.unban` | チャンネル BAN の解除 | +| `lunaticchat.command.lc.channel.mod` | モデレーター権限の付与・剥奪 | +| `lunaticchat.command.lc.channel.ownership` | チャンネルオーナーの譲渡 | + +## 管理者パーミッション + +以下のパーミッションはデフォルトで OP のみに付与されています. + +| パーミッション | デフォルト | 説明 | +|---------------|-----------|------| +| `lunaticchat.spy` | op | サーバー上の全ダイレクトメッセージを閲覧 | +| `lunaticchat.noticeupdate` | op | アップデート通知の受信 | +| `lunaticchat.channelbypass` | op | チャンネル制限のバイパス(キック・BAN 保護,強制削除) | +| `lunaticchat.command.lcv.status` | op | `/lcv status` コマンドの使用 | diff --git a/website/src/docs/reference/commands.md b/website/src/docs/reference/commands.md new file mode 100644 index 0000000..4c40b9b --- /dev/null +++ b/website/src/docs/reference/commands.md @@ -0,0 +1,157 @@ +--- +layout: doc +--- + +# コマンド一覧 + +LunaticChat で使用できるすべてのコマンドのリファレンスです. + +## ダイレクトメッセージ + +### `/tell <player> <message>` + +プレイヤーにダイレクトメッセージを送信します. + +- **エイリアス**: `t`, `msg`, `m`, `w`, `whisper` +- **パーミッション**: `lunaticchat.command.tell` + +### `/reply <message>` + +最後にメッセージを送ってきたプレイヤーに返信します. + +- **エイリアス**: `r` +- **パーミッション**: `lunaticchat.command.reply` +- **前提条件**: クイックリプライ機能が有効であること + +## メインコマンド (`/lc`) + +**エイリアス**: `lunaticchat` + +### `/lc status` + +プラグインのバージョン,ヘルス,有効な機能,設定値を表示します. + +- **パーミッション**: `lunaticchat.command.lc.status` + +### `/lc settings [key] [on|off]` + +プレイヤー個人の設定を確認・変更します.引数なしで設定一覧を表示します. + +- **パーミッション**: `lunaticchat.command.lc.settings` +- **設定キー**: `japanese`, `notice`, `chNotice`(詳細は[プレイヤー設定](/docs/reference/player-settings)を参照) + +## チャンネルコマンド (`/lc channel`) + +チャンネルチャット機能が有効な場合にのみ使用できます. + +### 作成・探索 + +#### `/lc channel create <channelId> <name> [description] [isPrivate]` + +新しいチャンネルを作成します.作成者がオーナーになります. + +- **パーミッション**: `lunaticchat.command.lc.channel.create` +- `channelId`: 英数字,アンダースコア,ハイフンのみ使用可能 +- `isPrivate`: `true` / `false`(デフォルト: `false`) + +#### `/lc channel list [page]` + +公開チャンネルの一覧を表示します(1ページ10件). + +- **パーミッション**: `lunaticchat.command.lc.channel.list` + +#### `/lc channel info [channelId]` + +チャンネルの詳細情報を表示します.引数なしでアクティブチャンネルの情報を表示します. + +- **パーミッション**: `lunaticchat.command.lc.channel.info` + +### 参加・退出 + +#### `/lc channel join <channelId>` + +チャンネルに参加します.プライベートチャンネルには招待が必要です. + +- **パーミッション**: `lunaticchat.command.lc.channel.join` + +#### `/lc channel leave` + +アクティブチャンネルから退出します. + +- **パーミッション**: `lunaticchat.command.lc.channel.leave` + +#### `/lc channel switch <channelId>` + +参加済みの別チャンネルをアクティブに切り替えます. + +- **パーミッション**: `lunaticchat.command.lc.channel.switch` + +#### `/lc channel status` + +自分のチャンネル参加状況(アクティブチャンネルと参加チャンネル一覧)を表示します. + +- **パーミッション**: `lunaticchat.command.lc.channel.status` + +### モデレーション(オーナー / モデレーター) + +#### `/lc channel invite <playerName>` + +プレイヤーをアクティブチャンネルに招待します.プライベートチャンネルの制限をバイパスします. + +- **パーミッション**: `lunaticchat.command.lc.channel.invite` +- **必要ロール**: OWNER または MODERATOR + +#### `/lc channel kick <playerName>` + +プレイヤーをアクティブチャンネルからキックします. + +- **パーミッション**: `lunaticchat.command.lc.channel.kick` +- **必要ロール**: OWNER または MODERATOR + +#### `/lc channel ban <playerName>` + +プレイヤーをアクティブチャンネルから BAN します.BAN されたプレイヤーは再参加できません. + +- **パーミッション**: `lunaticchat.command.lc.channel.ban` +- **必要ロール**: OWNER または MODERATOR + +#### `/lc channel unban <playerName>` + +プレイヤーのチャンネル BAN を解除します. + +- **パーミッション**: `lunaticchat.command.lc.channel.unban` +- **必要ロール**: OWNER または MODERATOR + +### 管理(オーナーのみ) + +#### `/lc channel delete <channelId>` + +チャンネルを削除します. + +- **パーミッション**: `lunaticchat.command.lc.channel.delete` +- **必要ロール**: OWNER(`lunaticchat.channelbypass` 権限で制限をバイパス可能) + +#### `/lc channel mod <playerName>` + +チャンネルメンバーのモデレーター権限を付与・剥奪します. + +- **パーミッション**: `lunaticchat.command.lc.channel.mod` +- **必要ロール**: OWNER + +#### `/lc channel ownership <playerName>` + +チャンネルのオーナー権限を別のメンバーに譲渡します. + +- **パーミッション**: `lunaticchat.command.lc.channel.ownership` +- **必要ロール**: OWNER + +## Velocity コマンド (`/lcv`) + +**エイリアス**: `lunaticvelocity` + +### `/lcv status` + +Velocity プロキシとの接続状態,プロトコルバージョン,オンラインプレイヤー数を表示します. + +- **パーミッション**: `lunaticchat.command.lcv.status` +- **デフォルト**: op のみ diff --git a/website/src/docs/reference/message-format.md b/website/src/docs/reference/message-format.md new file mode 100644 index 0000000..7ae42e9 --- /dev/null +++ b/website/src/docs/reference/message-format.md @@ -0,0 +1,86 @@ +--- +layout: doc +--- + +# メッセージフォーマット + +`config.yml` の `messageFormat` セクションで,チャットメッセージの表示形式をカスタマイズできます. + +## プレースホルダー + +| プレースホルダー | 説明 | 使用可能なフォーマット | +|----------------|------|----------------------| +| `{sender}` | メッセージの送信者名 | すべて | +| `{recipient}` | メッセージの受信者名 | `directMessageFormat` | +| `{message}` | メッセージの内容 | すべて | +| `{channel}` | チャンネル名 | `channelMessageFormat` | +| `{server}` | サーバー名 | `crossServerGlobalChatFormat` | + +## フォーマット一覧 + +### `directMessageFormat` + +`/tell` や `/reply` で送信されるダイレクトメッセージの表示形式です. + +**デフォルト:** +``` +§7[§e{sender} §7>> §e{recipient}§7] §f{message} +``` + +**表示例:** <span style="color: gray">[</span><span style="color: gold">Steve</span> <span style="color: gray">>></span> <span style="color: gold">Alex</span><span style="color: gray">]</span> <span style="color: white">こんにちは!</span> + +### `channelMessageFormat` + +チャンネルチャットで送信されるメッセージの表示形式です. + +**デフォルト:** +``` +§7[§b#{channel}§7] §e{sender}: §f{message} +``` + +**表示例:** <span style="color: gray">[</span><span style="color: aqua">#general</span><span style="color: gray">]</span> <span style="color: gold">Steve:</span> <span style="color: white">こんにちは!</span> + +### `crossServerGlobalChatFormat` + +Velocity 連携時のクロスサーバーグローバルチャットの表示形式です. + +**デフォルト:** +``` +§7[§6{server}§7] §e{sender}: §f{message} +``` + +**表示例:** <span style="color: gray">[</span><span style="color: gold">survival</span><span style="color: gray">]</span> <span style="color: gold">Steve:</span> <span style="color: white">こんにちは!</span> + +## カラーコード + +Minecraft のセクション記号(`§`)を使ったカラーコードが使用できます. + +| コード | 色 | +|--------|------| +| `§0` | 黒 | +| `§1` | 濃い青 | +| `§2` | 濃い緑 | +| `§3` | 濃い水色 | +| `§4` | 濃い赤 | +| `§5` | 濃い紫 | +| `§6` | 金色 | +| `§7` | 灰色 | +| `§8` | 濃い灰色 | +| `§9` | 青 | +| `§a` | 緑 | +| `§b` | 水色 | +| `§c` | 赤 | +| `§d` | ピンク | +| `§e` | 黄色 | +| `§f` | 白 | + +### 装飾コード + +| コード | 効果 | +|--------|------| +| `§l` | **太字** | +| `§o` | *斜体* | +| `§n` | <u>下線</u> | +| `§m` | ~~取り消し線~~ | +| `§k` | 難読化(文字がランダムに変化) | +| `§r` | リセット | diff --git a/website/src/docs/reference/player-settings.md b/website/src/docs/reference/player-settings.md new file mode 100644 index 0000000..bbd294d --- /dev/null +++ b/website/src/docs/reference/player-settings.md @@ -0,0 +1,50 @@ +--- +layout: doc +--- + +# プレイヤー設定 + +プレイヤーは `/lc settings` コマンドで個人設定を変更できます.設定はサーバーの `player-settings.yaml`(設定ファイルの `userSettingsFilePath` で変更可能)に UUID ごとに保存されます. + +## コマンド + +``` +/lc settings # 設定一覧を表示 +/lc settings <key> # 現在の値を確認 +/lc settings <key> on|off # 値を変更 +``` + +## 設定キー + +| キー | 説明 | デフォルト | +|------|------|-----------| +| `japanese` | ローマ字→日本語変換を有効にする | `true` | +| `notice` | ダイレクトメッセージの通知を有効にする | `true` | +| `chNotice` | チャンネルメッセージの通知を有効にする | `true` | + +### `japanese` + +ローマ字で入力したチャットメッセージを自動的に日本語(ひらがな)に変換します.この設定はサーバー側で `features.japaneseConversion.enabled` が `true` の場合にのみ機能します. + +``` +/lc settings japanese on # 変換を有効化 +/lc settings japanese off # 変換を無効化 +``` + +### `notice` + +ダイレクトメッセージ(`/tell` / `/reply`)を受信した際の通知を制御します. + +``` +/lc settings notice on # 通知を有効化 +/lc settings notice off # 通知を無効化 +``` + +### `chNotice` + +チャンネルチャットのメッセージを受信した際の通知を制御します.この設定はサーバー側で `features.channelChat.enabled` が `true` の場合にのみ機能します. + +``` +/lc settings chNotice on # 通知を有効化 +/lc settings chNotice off # 通知を無効化 +``` diff --git a/website/src/download.md b/website/src/download.md new file mode 100644 index 0000000..ef1167b --- /dev/null +++ b/website/src/download.md @@ -0,0 +1,6 @@ +--- +layout: page +title: ダウンロード +--- + +<DownloadCard /> diff --git a/website/src/en/docs/configuration.md b/website/src/en/docs/configuration.md new file mode 100644 index 0000000..e7891b3 --- /dev/null +++ b/website/src/en/docs/configuration.md @@ -0,0 +1,73 @@ +--- +layout: doc +--- + +# Configuration + +LunaticChat's configuration is managed in `plugins/LunaticChat/config.yml`. A default configuration file is generated on the server's first startup. + +## Global Settings + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| `debug` | Boolean | `false` | Enable debug logging | +| `userSettingsFilePath` | String | `"player-settings.yaml"` | Path to the player settings file | +| `checkForUpdates` | Boolean | `true` | Check for updates on startup | +| `language` | String | `"en"` | Plugin language (`en` / `ja`) | + +## Feature Settings (`features`) + +### Quick Replies (`features.quickReplies`) + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| `enabled` | Boolean | `true` | Enable the `/reply` command | + +### Japanese Conversion (`features.japaneseConversion`) + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| `enabled` | Boolean | `false` | Enable romaji-to-hiragana conversion | +| `cache.maxEntries` | Int | `500` | Maximum number of conversion cache entries | +| `cache.saveIntervalSeconds` | Int | `300` | Interval (in seconds) for saving cache to disk | +| `cache.filePath` | String | `"conversion_cache.json"` | Path to the cache file | +| `api.timeout` | Long | `3000` | API request timeout (in milliseconds) | +| `api.retryAttempts` | Int | `2` | Number of retries on API request failure | + +### Channel Chat (`features.channelChat`) + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| `enabled` | Boolean | `false` | Enable the channel chat feature | +| `maxChannelsPerServer` | Int | `0` | Maximum channels per server (`0` = unlimited) | +| `maxMembersPerChannel` | Int | `0` | Maximum members per channel (`0` = unlimited) | +| `maxMembershipPerPlayer` | Int | `0` | Maximum channel memberships per player (`0` = unlimited) | + +#### Message Logging (`features.channelChat.messageLogging`) + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| `enabled` | Boolean | `true` | Log channel messages to an NDJSON file | +| `retentionDays` | Int | `30` | Log file retention period in days (`0` = indefinite) | +| `maxFileSizeMB` | Int | `100` | Maximum size of a single log file (MB) | + +### Velocity Integration (`features.velocityIntegration`) + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| `enabled` | Boolean | `false` | Enable integration with the Velocity proxy | +| `crossServerGlobalChat` | Boolean | `false` | Enable cross-server global chat | +| `serverName` | String | `"Unknown"` | Server name displayed in cross-server chat | +| `messageDeduplicationCacheSize` | Int | `100` | Size of the message deduplication cache | + +## Message Format (`messageFormat`) + +| Key | Default | Available Placeholders | +|-----|---------|----------------------| +| `directMessageFormat` | `§7[§e{sender} §7>> §e{recipient}§7] §f{message}` | `{sender}`, `{recipient}`, `{message}` | +| `channelMessageFormat` | `§7[§b#{channel}§7] §e{sender}: §f{message}` | `{sender}`, `{message}`, `{channel}` | +| `crossServerGlobalChatFormat` | `§7[§6{server}§7] §e{sender}: §f{message}` | `{sender}`, `{message}`, `{server}` | + +## Default Configuration File + +[View on GitHub](https://github.com/m1sk9/LunaticChat/blob/main/platform-paper/src/main/resources/config.yml) diff --git a/website/src/en/docs/features/admin.md b/website/src/en/docs/features/admin.md new file mode 100644 index 0000000..c3a3d2f --- /dev/null +++ b/website/src/en/docs/features/admin.md @@ -0,0 +1,74 @@ +--- +layout: doc +--- + +# Admin Features + +This page covers features intended for server administrators. These features are primarily available to players with OP permissions. + +## Plugin Status (`/lc status`) + +View an overview of the plugin's operational status. + +``` +/lc status +``` + +Displayed information: + +- Plugin version (with Git commit hash) +- Health status (OK / Degraded) +- Enabled/disabled state of each feature +- Configuration values (debug mode, update checking, language) +- Links to GitHub, Modrinth, and documentation + +## Spy Mode + +Players with the `lunaticchat.spy` permission (default: op) can view all direct messages sent and received on the server. + +- Spy players see the original message before romaji conversion +- Hover text indicates the message is a spy message +- Spy players themselves are not included in the normal sender/recipient list + +## Channel Bypass + +Players with the `lunaticchat.channelbypass` permission (default: op) can bypass the following channel restrictions. + +- Cannot be kicked or banned +- Can delete channels even without being the owner + +## Update Notifications + +When `checkForUpdates` is `true` (default), the plugin checks for new versions at startup. Players with the `lunaticchat.noticeupdate` permission (default: op) receive an update notification when they join the server. + +```yaml +# config.yml +checkForUpdates: true +``` + +## Debug Mode + +Setting `debug` to `true` enables verbose plugin logging. This is useful for troubleshooting issues or submitting bug reports. + +```yaml +# config.yml +debug: true +``` + +## Language Setting + +You can change the language of messages displayed to players. Plugin logs and console output are not affected and remain in English only. + +```yaml +# config.yml +language: "ja" # "en" or "ja" +``` + +## Admin Permissions Reference + +| Permission | Default | Description | +|-----------|---------|-------------| +| `lunaticchat.spy` | op | View all direct messages | +| `lunaticchat.channelbypass` | op | Bypass channel restrictions | +| `lunaticchat.noticeupdate` | op | Receive update notifications | +| `lunaticchat.command.lcv.status` | op | Use the `/lcv status` command | diff --git a/website/src/en/docs/features/channel-chat.md b/website/src/en/docs/features/channel-chat.md new file mode 100644 index 0000000..68d216e --- /dev/null +++ b/website/src/en/docs/features/channel-chat.md @@ -0,0 +1,92 @@ +--- +layout: doc +--- + +# Channel Chat + +Create channels to separate conversations by group. To use this feature, set `features.channelChat.enabled` to `true` in `config.yml`. + +## Creating a Channel + +``` +/lc channel create <channelId> <name> [description] [isPrivate] +``` + +- `channelId`: A unique identifier for the channel (alphanumeric, `_`, `-` only, 3-30 characters) +- `name`: The display name of the channel +- `description`: A description of the channel (optional) +- `isPrivate`: Set to `true` to make the channel private (default: `false`) + +The creator automatically becomes the owner. + +## Joining and Leaving Channels + +``` +/lc channel join <channelId> # Join a channel +/lc channel leave # Leave the active channel +/lc channel switch <channelId> # Switch the active channel +``` + +Joining a private channel requires an invitation from the owner or a moderator. + +## Active Channel + +Players can join multiple channels, but only one channel can be active at a time. Chat messages are sent to the active channel. Use `/lc channel switch` to change the active channel. + +``` +/lc channel status # Display the current active channel and list of joined channels +``` + +## Roles and Permissions + +Channels have three roles. + +| Role | Permissions | +|------|-------------| +| **OWNER** | Delete the channel, manage moderators, transfer ownership, manage members | +| **MODERATOR** | Invite, kick, ban/unban members | +| **MEMBER** | Participate in chat, view channel information | + +### Moderator Management (Owner Only) + +``` +/lc channel mod <playerName> # Grant/revoke moderator permissions +/lc channel ownership <playerName> # Transfer ownership +``` + +### Member Management (Owner / Moderator) + +``` +/lc channel invite <playerName> # Invite a player +/lc channel kick <playerName> # Kick a player +/lc channel ban <playerName> # Ban a player +/lc channel unban <playerName> # Unban a player +``` + +## Limit Settings + +You can set channel limits in `config.yml` (set to `0` for unlimited). + +| Setting Key | Description | +|-------------|-------------| +| `maxChannelsPerServer` | Maximum number of channels per server | +| `maxMembersPerChannel` | Maximum number of members per channel | +| `maxMembershipPerPlayer` | Maximum number of channels a player can join | + +## Message Logging + +Channel messages can be logged in NDJSON format. Files are rotated daily, and a new file with a suffix is created when `maxFileSizeMB` is exceeded. + +```json +{"timestamp":"2026-04-05T14:23:45.123Z","playerId":"550e8400-...","playerName":"Steve","channelId":"general","message":"Hello!"} +``` + +See the `features.channelChat.messageLogging` section on the [Configuration page](/en/docs/configuration) for logging settings. + +## Bypass Permission + +Players with the `lunaticchat.channelbypass` permission (default: op) are protected from kicks and bans, and can force-delete channels. + +## Message Format + +The display format for channel messages can be customized via `messageFormat.channelMessageFormat` in `config.yml`. See [Message Format](/en/docs/reference/message-format) for details. diff --git a/website/src/en/docs/features/direct-message.md b/website/src/en/docs/features/direct-message.md new file mode 100644 index 0000000..7a88ecd --- /dev/null +++ b/website/src/en/docs/features/direct-message.md @@ -0,0 +1,52 @@ +--- +layout: doc +--- + +# Direct Message + +Send and receive private 1-on-1 messages between players. + +## Basic Usage + +### Sending a Message + +``` +/tell <player> <message> +``` + +Aliases: `/t`, `/msg`, `/m`, `/w`, `/whisper` + +Sends a direct message to the specified player. Clicking on a received message will auto-fill the reply command to the sender. + +### Quick Reply + +``` +/reply <message> +``` + +Alias: `/r` + +Replies to the last player who sent you a message. If there is no such player, the message is sent to the last player you messaged. + +To use quick reply, `features.quickReplies.enabled` must be `true` (default) in `config.yml`. + +## Notification Settings + +Players can individually control the sound notification when receiving direct messages. + +``` +/lc settings notice on # Enable notifications +/lc settings notice off # Disable notifications +``` + +## Integration with Japanese Conversion + +When [Japanese Conversion](/en/docs/features/japanese-conversion) is enabled, direct message content is also automatically converted to Japanese. Conversion follows each player's `japanese` setting. + +## Spy Feature + +Players with the `lunaticchat.spy` permission (default: op) can view all direct messages on the server. Spy players see the original message before conversion. + +## Message Format + +The display format for direct messages can be customized via `messageFormat.directMessageFormat` in `config.yml`. See [Message Format](/en/docs/reference/message-format) for details. diff --git a/website/src/en/docs/features/japanese-conversion.md b/website/src/en/docs/features/japanese-conversion.md new file mode 100644 index 0000000..3bcd52b --- /dev/null +++ b/website/src/en/docs/features/japanese-conversion.md @@ -0,0 +1,62 @@ +--- +layout: doc +--- + +# Japanese Conversion + +Automatically converts chat messages typed in romaji into Japanese. To use this feature, set `features.japaneseConversion.enabled` to `true` in `config.yml`. + +## How Conversion Works + +Conversion is performed in two stages. + +1. **Romaji to Hiragana**: The plugin's built-in Trie-based conversion engine converts romaji to hiragana +2. **Hiragana to Kanji/Katakana**: The Google IME API converts hiragana into natural Japanese + +### Conversion Example + +``` +Input: konnichiha sekai +Stage 1: こんにちは せかい +Stage 2: こんにちは 世界 +``` + +## Conversion Targets + +- Normal chat +- Direct messages (`/tell`, `/reply`) +- Channel chat + +If the input is not valid romaji (e.g., contains English words), no conversion is performed and the message is sent as-is. + +## Player Settings + +Players can individually toggle conversion on or off. + +``` +/lc settings japanese on # Enable conversion +/lc settings japanese off # Disable conversion +``` + +## Cache + +Conversion results are cached per word. When the same word is converted again, the result is retrieved from cache instead of calling the API. The cache is periodically saved to disk as a JSON file. + +| Setting Key | Default | Description | +|-------------|---------|-------------| +| `cache.maxEntries` | `500` | Maximum number of cache entries | +| `cache.saveIntervalSeconds` | `300` | Interval for saving to disk (seconds) | +| `cache.filePath` | `"conversion_cache.json"` | Path to the cache file | + +When the cache reaches its limit, the oldest 10% of entries are automatically removed. + +## API Settings + +Settings related to the connection to the Google IME API. + +| Setting Key | Default | Description | +|-------------|---------|-------------| +| `api.timeout` | `3000` | Request timeout (milliseconds) | +| `api.retryAttempts` | `2` | Number of retry attempts on failure | + +If the API times out or fails, the message is sent in hiragana as-is. diff --git a/website/src/en/docs/features/message-logging.md b/website/src/en/docs/features/message-logging.md new file mode 100644 index 0000000..5e929bc --- /dev/null +++ b/website/src/en/docs/features/message-logging.md @@ -0,0 +1,94 @@ +--- +layout: doc +--- + +# Message Logging + +Records channel chat messages in NDJSON (Newline Delimited JSON) format to files. This feature is available when channel chat is enabled and is turned on by default. + +## Configuration + +```yaml +# config.yml +features: + channelChat: + enabled: true + messageLogging: + enabled: true + retentionDays: 30 + maxFileSizeMB: 100 +``` + +| Setting Key | Default | Description | +|-------------|---------|-------------| +| `enabled` | `true` | Enable message logging | +| `retentionDays` | `30` | Number of days to retain log files (`0` for unlimited retention) | +| `maxFileSizeMB` | `100` | Maximum size of a single log file (MB) | + +## Log File Format + +Log files are saved in the `plugins/LunaticChat/logs/` directory. Each line is a single JSON object. + +### File Naming + +``` +channel-messages-YYYY-MM-dd.json +``` + +When the file size exceeds `maxFileSizeMB`, a new file with a suffix is created. + +``` +channel-messages-2026-04-05.json # Base file +channel-messages-2026-04-05-1.json # On size overflow +channel-messages-2026-04-05-2.json # On further overflow +``` + +### Entry Format + +Each line has the following JSON structure. + +```json +{ + "timestamp": "2026-04-05T14:23:45.123Z", + "playerId": "550e8400-e29b-41d4-a716-446655440000", + "playerName": "Steve", + "channelId": "general", + "message": "Hello everyone!" +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `timestamp` | String | ISO 8601 timestamp (UTC) | +| `playerId` | String | Player UUID | +| `playerName` | String | Player display name | +| `channelId` | String | ID of the channel the message was sent to | +| `message` | String | Message content | + +## File Rotation + +- **Daily rotation**: A new file is created when the date changes +- **Size rotation**: Switches to a suffixed file when `maxFileSizeMB` is exceeded +- **Automatic cleanup**: Log files older than the number of days specified by `retentionDays` are automatically deleted (no deletion when set to `0`) + +## Usage Examples + +Since the format is NDJSON, you can easily filter and aggregate logs using tools like `jq`. + +### Extract Messages from a Specific Channel + +```bash +jq 'select(.channelId == "general")' channel-messages-2026-04-05.json +``` + +### Extract Messages from a Specific Player + +```bash +jq 'select(.playerName == "Steve")' channel-messages-2026-04-05.json +``` + +### Count Messages by Channel + +```bash +jq -s 'group_by(.channelId) | map({channel: .[0].channelId, count: length})' channel-messages-2026-04-05.json +``` diff --git a/website/src/en/docs/features/velocity.md b/website/src/en/docs/features/velocity.md new file mode 100644 index 0000000..9241e80 --- /dev/null +++ b/website/src/en/docs/features/velocity.md @@ -0,0 +1,109 @@ +--- +layout: doc +--- + +# Velocity Integration + +Relays global chat across multiple Paper / Folia servers via a Velocity proxy. + +## Setup + +### 1. Install the Velocity Plugin + +Place `LunaticChat-<version>-velocity.jar` in the Velocity `plugins/` directory and restart the proxy. + +### 2. Paper-Side Configuration + +Set the following in each Paper server's `config.yml`. + +```yaml +features: + velocityIntegration: + enabled: true + crossServerGlobalChat: true + serverName: "survival" # Must match the server name in the Velocity configuration +``` + +### 3. Verify the Connection + +``` +/lcv status +``` + +You can check the connection status, protocol version, Velocity plugin version, and more (permission: `lunaticchat.command.lcv.status`, default: op). + +## Cross-Server Global Chat + +When `crossServerGlobalChat` is set to `true`, player chat messages are relayed via Velocity to all other Paper servers. + +### Message Flow + +1. A player sends a chat message +2. The Paper server sends the message to Velocity +3. Velocity relays the message to all servers except the sender's +4. The message is displayed to players on each server + +### Message Deduplication + +Each message is assigned a unique ID, and a cache prevents the same message from being displayed more than once. The cache size can be configured with `messageDeduplicationCacheSize` (default: `100`). + +## Protocol Version + +Compatibility between Paper and Velocity is managed by protocol version. A handshake is performed upon connection, and incompatible versions are rejected. + +### Version Bump Rules + +| Level | Example Change | Compatibility | Deployment Order | +|-------|---------------|---------------|-----------------| +| PATCH (1.0.0 -> 1.0.1) | Adding optional fields, new sub-channels | Fully compatible (safe with `ignoreUnknownKeys=true`) | Any order, anytime | +| MINOR (1.0.x -> 1.1.0) | Adding required fields, changing existing sub-channel semantics | Backward compatible within `MIN_SUPPORTED_MINOR` range | **Update Velocity first** -> then update each Paper server | +| MAJOR (1.x.x -> 2.0.0) | Wire format changes, removing/renaming sub-channels | Incompatible | **Simultaneous deployment of all servers** | + +### Compatibility Check + +Compatibility is determined during the handshake using the following rules: + +- **MAJOR** versions must match +- The remote **MINOR** must be at least `MIN_SUPPORTED_MINOR` and at most the local MINOR +- **PATCH** does not affect the compatibility check + +#### Example: Velocity with protocol 1.2.0 and `MIN_SUPPORTED_MINOR=1` + +| Paper Protocol | Result | +|---------------|--------| +| 1.1.x | Connection OK | +| 1.2.x | Connection OK | +| 1.0.x | Rejected (older than `MIN_SUPPORTED_MINOR`) | +| 1.3.x | Rejected (newer than Velocity) | +| 2.0.x | Rejected (MAJOR mismatch) | + +### Operational Cycle + +1. **No protocol change** -> Paper / Velocity can be deployed independently +2. **PATCH change** -> Deploy freely from either side +3. **MINOR change** -> Update Velocity first and set `MIN_SUPPORTED_MINOR` to allow a grace period for older Paper servers. After all Paper servers are updated, raise `MIN_SUPPORTED_MINOR` +4. **MAJOR change** -> Simultaneous update during a maintenance window + +## Connection States + +| State | Description | +|-------|-------------| +| `DISCONNECTED` | Not connected | +| `HANDSHAKING` | Handshake in progress | +| `CONNECTED` | Connected | +| `FAILED` | Connection failed | + +The handshake timeout is 5 seconds. If the handshake times out, the state becomes `FAILED`. + +## Configuration Reference + +| Setting Key | Default | Description | +|-------------|---------|-------------| +| `enabled` | `false` | Enable Velocity integration | +| `crossServerGlobalChat` | `false` | Enable cross-server global chat | +| `serverName` | `"Unknown"` | Server name displayed in cross-server chat | +| `messageDeduplicationCacheSize` | `100` | Size of the message deduplication cache | + +## Message Format + +The display format for cross-server chat can be customized via `messageFormat.crossServerGlobalChatFormat` in `config.yml`. See [Message Format](/en/docs/reference/message-format) for details. diff --git a/website/src/en/docs/getting-started.md b/website/src/en/docs/getting-started.md new file mode 100644 index 0000000..abfd2ac --- /dev/null +++ b/website/src/en/docs/getting-started.md @@ -0,0 +1,47 @@ +--- +layout: doc +--- + +# Getting Started + +This guide explains how to set up LunaticChat. + +## Requirements + +| Item | Requirement | +|------|-------------| +| Minecraft | 26.1 or later | +| Java | 25 or later | +| Server | Paper, Folia, or Velocity | + +## Download + +You can download the plugin JAR from either of the following: + +- [GitHub Releases](https://github.com/m1sk9/LunaticChat/releases) +- [Modrinth](https://modrinth.com/project/lunaticchat) + +Use `LunaticChat-<version>.jar` for Paper / Folia servers and `LunaticChat-<version>-velocity.jar` for Velocity proxies. + +## Installation + +### Paper / Folia + +1. Place the downloaded `LunaticChat-<version>.jar` into the server's `plugins/` directory +2. Start (or restart) the server +3. `plugins/LunaticChat/config.yml` will be generated automatically +4. Modify the [configuration](/en/docs/configuration) as needed and restart the server + +### Velocity + +1. Place the downloaded `LunaticChat-<version>-velocity.jar` into the Velocity `plugins/` directory +2. Start (or restart) the Velocity proxy +3. Set `features.velocityIntegration.enabled` to `true` in the Paper-side `config.yml` +4. See [Velocity Integration](/en/docs/features/velocity) for details + +## Next Steps + +- [Configuration](/en/docs/configuration) - Review all settings in `config.yml` +- [Direct Message](/en/docs/features/direct-message) - How to use the DM feature +- [Channel Chat](/en/docs/features/channel-chat) - How to use the channel feature +- [Command Reference](/en/docs/reference/commands) - Reference for all commands diff --git a/website/src/en/docs/permissions.md b/website/src/en/docs/permissions.md new file mode 100644 index 0000000..d059bba --- /dev/null +++ b/website/src/en/docs/permissions.md @@ -0,0 +1,50 @@ +--- +layout: doc +--- + +# Permissions + +A list of all permission nodes in LunaticChat. + +## Command Permissions + +All command permissions are granted to all players by default. + +| Permission | Description | +|------------|-------------| +| `lunaticchat.command.lc` | Use the `/lc` command | +| `lunaticchat.command.tell` | Use the `/tell` command | +| `lunaticchat.command.reply` | Use the `/reply` command | +| `lunaticchat.command.lc.settings` | Use `/lc settings` | +| `lunaticchat.command.lc.status` | Use `/lc status` | + +### Channel-Related + +| Permission | Description | +|------------|-------------| +| `lunaticchat.command.lc.channel` | Use `/lc channel` | +| `lunaticchat.command.lc.channel.create` | Create a channel | +| `lunaticchat.command.lc.channel.list` | View the channel list | +| `lunaticchat.command.lc.channel.join` | Join a channel | +| `lunaticchat.command.lc.channel.leave` | Leave a channel | +| `lunaticchat.command.lc.channel.switch` | Switch the active channel | +| `lunaticchat.command.lc.channel.status` | View channel membership status | +| `lunaticchat.command.lc.channel.info` | View channel information | +| `lunaticchat.command.lc.channel.delete` | Delete a channel | +| `lunaticchat.command.lc.channel.invite` | Invite to a channel | +| `lunaticchat.command.lc.channel.kick` | Kick from a channel | +| `lunaticchat.command.lc.channel.ban` | Ban from a channel | +| `lunaticchat.command.lc.channel.unban` | Unban from a channel | +| `lunaticchat.command.lc.channel.mod` | Grant or revoke moderator privileges | +| `lunaticchat.command.lc.channel.ownership` | Transfer channel ownership | + +## Admin Permissions + +The following permissions are granted to OPs only by default. + +| Permission | Default | Description | +|------------|---------|-------------| +| `lunaticchat.spy` | op | View all direct messages on the server | +| `lunaticchat.noticeupdate` | op | Receive update notifications | +| `lunaticchat.channelbypass` | op | Bypass channel restrictions (kick/ban protection, force deletion) | +| `lunaticchat.command.lcv.status` | op | Use the `/lcv status` command | diff --git a/website/src/en/docs/reference/commands.md b/website/src/en/docs/reference/commands.md new file mode 100644 index 0000000..3ed72df --- /dev/null +++ b/website/src/en/docs/reference/commands.md @@ -0,0 +1,157 @@ +--- +layout: doc +--- + +# Command Reference + +A reference for all commands available in LunaticChat. + +## Direct Messages + +### `/tell <player> <message>` + +Sends a direct message to a player. + +- **Aliases**: `t`, `msg`, `m`, `w`, `whisper` +- **Permission**: `lunaticchat.command.tell` + +### `/reply <message>` + +Replies to the last player who sent you a message. + +- **Aliases**: `r` +- **Permission**: `lunaticchat.command.reply` +- **Prerequisite**: Quick reply feature must be enabled + +## Main Command (`/lc`) + +**Aliases**: `lunaticchat` + +### `/lc status` + +Displays the plugin version, health, enabled features, and configuration values. + +- **Permission**: `lunaticchat.command.lc.status` + +### `/lc settings [key] [on|off]` + +Views or changes your personal settings. Without arguments, displays the settings list. + +- **Permission**: `lunaticchat.command.lc.settings` +- **Setting keys**: `japanese`, `notice`, `chNotice` (see [Player Settings](/en/docs/reference/player-settings) for details) + +## Channel Commands (`/lc channel`) + +Only available when the channel chat feature is enabled. + +### Create & Browse + +#### `/lc channel create <channelId> <name> [description] [isPrivate]` + +Creates a new channel. The creator becomes the owner. + +- **Permission**: `lunaticchat.command.lc.channel.create` +- `channelId`: Only alphanumeric characters, underscores, and hyphens are allowed +- `isPrivate`: `true` / `false` (default: `false`) + +#### `/lc channel list [page]` + +Displays a list of public channels (10 per page). + +- **Permission**: `lunaticchat.command.lc.channel.list` + +#### `/lc channel info [channelId]` + +Displays detailed information about a channel. Without arguments, shows information about the active channel. + +- **Permission**: `lunaticchat.command.lc.channel.info` + +### Join & Leave + +#### `/lc channel join <channelId>` + +Joins a channel. An invitation is required for private channels. + +- **Permission**: `lunaticchat.command.lc.channel.join` + +#### `/lc channel leave` + +Leaves the active channel. + +- **Permission**: `lunaticchat.command.lc.channel.leave` + +#### `/lc channel switch <channelId>` + +Switches the active channel to another channel you have already joined. + +- **Permission**: `lunaticchat.command.lc.channel.switch` + +#### `/lc channel status` + +Displays your channel membership status (active channel and list of joined channels). + +- **Permission**: `lunaticchat.command.lc.channel.status` + +### Moderation (Owner / Moderator) + +#### `/lc channel invite <playerName>` + +Invites a player to the active channel. Bypasses private channel restrictions. + +- **Permission**: `lunaticchat.command.lc.channel.invite` +- **Required role**: OWNER or MODERATOR + +#### `/lc channel kick <playerName>` + +Kicks a player from the active channel. + +- **Permission**: `lunaticchat.command.lc.channel.kick` +- **Required role**: OWNER or MODERATOR + +#### `/lc channel ban <playerName>` + +Bans a player from the active channel. Banned players cannot rejoin. + +- **Permission**: `lunaticchat.command.lc.channel.ban` +- **Required role**: OWNER or MODERATOR + +#### `/lc channel unban <playerName>` + +Unbans a player from the channel. + +- **Permission**: `lunaticchat.command.lc.channel.unban` +- **Required role**: OWNER or MODERATOR + +### Administration (Owner Only) + +#### `/lc channel delete <channelId>` + +Deletes a channel. + +- **Permission**: `lunaticchat.command.lc.channel.delete` +- **Required role**: OWNER (can be bypassed with `lunaticchat.channelbypass` permission) + +#### `/lc channel mod <playerName>` + +Grants or revokes moderator privileges for a channel member. + +- **Permission**: `lunaticchat.command.lc.channel.mod` +- **Required role**: OWNER + +#### `/lc channel ownership <playerName>` + +Transfers channel ownership to another member. + +- **Permission**: `lunaticchat.command.lc.channel.ownership` +- **Required role**: OWNER + +## Velocity Commands (`/lcv`) + +**Aliases**: `lunaticvelocity` + +### `/lcv status` + +Displays the connection status with the Velocity proxy, protocol version, and online player count. + +- **Permission**: `lunaticchat.command.lcv.status` +- **Default**: op only diff --git a/website/src/en/docs/reference/message-format.md b/website/src/en/docs/reference/message-format.md new file mode 100644 index 0000000..2669adb --- /dev/null +++ b/website/src/en/docs/reference/message-format.md @@ -0,0 +1,86 @@ +--- +layout: doc +--- + +# Message Format + +You can customize the display format of chat messages in the `messageFormat` section of `config.yml`. + +## Placeholders + +| Placeholder | Description | Available formats | +|-------------|-------------|-------------------| +| `{sender}` | Name of the message sender | All | +| `{recipient}` | Name of the message recipient | `directMessageFormat` | +| `{message}` | Message content | All | +| `{channel}` | Channel name | `channelMessageFormat` | +| `{server}` | Server name | `crossServerGlobalChatFormat` | + +## Format List + +### `directMessageFormat` + +The display format for direct messages sent via `/tell` or `/reply`. + +**Default:** +``` +§7[§e{sender} §7>> §e{recipient}§7] §f{message} +``` + +**Example:** <span style="color: gray">[</span><span style="color: gold">Steve</span> <span style="color: gray">>></span> <span style="color: gold">Alex</span><span style="color: gray">]</span> <span style="color: white">Hello!</span> + +### `channelMessageFormat` + +The display format for messages sent in channel chat. + +**Default:** +``` +§7[§b#{channel}§7] §e{sender}: §f{message} +``` + +**Example:** <span style="color: gray">[</span><span style="color: aqua">#general</span><span style="color: gray">]</span> <span style="color: gold">Steve:</span> <span style="color: white">Hello!</span> + +### `crossServerGlobalChatFormat` + +The display format for cross-server global chat when using Velocity integration. + +**Default:** +``` +§7[§6{server}§7] §e{sender}: §f{message} +``` + +**Example:** <span style="color: gray">[</span><span style="color: gold">survival</span><span style="color: gray">]</span> <span style="color: gold">Steve:</span> <span style="color: white">Hello!</span> + +## Color Codes + +You can use color codes with the Minecraft section sign (`§`). + +| Code | Color | +|------|-------| +| `§0` | Black | +| `§1` | Dark blue | +| `§2` | Dark green | +| `§3` | Dark aqua | +| `§4` | Dark red | +| `§5` | Dark purple | +| `§6` | Gold | +| `§7` | Gray | +| `§8` | Dark gray | +| `§9` | Blue | +| `§a` | Green | +| `§b` | Aqua | +| `§c` | Red | +| `§d` | Pink | +| `§e` | Yellow | +| `§f` | White | + +### Formatting Codes + +| Code | Effect | +|------|--------| +| `§l` | **Bold** | +| `§o` | *Italic* | +| `§n` | <u>Underline</u> | +| `§m` | ~~Strikethrough~~ | +| `§k` | Obfuscated (characters change randomly) | +| `§r` | Reset | diff --git a/website/src/en/docs/reference/player-settings.md b/website/src/en/docs/reference/player-settings.md new file mode 100644 index 0000000..6db48ac --- /dev/null +++ b/website/src/en/docs/reference/player-settings.md @@ -0,0 +1,50 @@ +--- +layout: doc +--- + +# Player Settings + +Players can change their personal settings using the `/lc settings` command. Settings are saved per UUID in the server's `player-settings.yaml` (the file path can be changed via `userSettingsFilePath` in the configuration file). + +## Command + +``` +/lc settings # Display settings list +/lc settings <key> # Check current value +/lc settings <key> on|off # Change value +``` + +## Setting Keys + +| Key | Description | Default | +|-----|-------------|---------| +| `japanese` | Enable romaji-to-Japanese conversion | `true` | +| `notice` | Enable direct message notifications | `true` | +| `chNotice` | Enable channel message notifications | `true` | + +### `japanese` + +Automatically converts chat messages typed in romaji to Japanese (hiragana). This setting only works when `features.japaneseConversion.enabled` is set to `true` on the server side. + +``` +/lc settings japanese on # Enable conversion +/lc settings japanese off # Disable conversion +``` + +### `notice` + +Controls notifications when receiving direct messages (`/tell` / `/reply`). + +``` +/lc settings notice on # Enable notifications +/lc settings notice off # Disable notifications +``` + +### `chNotice` + +Controls notifications when receiving channel chat messages. This setting only works when `features.channelChat.enabled` is set to `true` on the server side. + +``` +/lc settings chNotice on # Enable notifications +/lc settings chNotice off # Disable notifications +``` diff --git a/website/src/en/download.md b/website/src/en/download.md new file mode 100644 index 0000000..e629415 --- /dev/null +++ b/website/src/en/download.md @@ -0,0 +1,6 @@ +--- +layout: page +title: Download +--- + +<DownloadCard /> diff --git a/website/src/en/index.md b/website/src/en/index.md new file mode 100644 index 0000000..b823a0d --- /dev/null +++ b/website/src/en/index.md @@ -0,0 +1,153 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: 'LunaticChat' + tagline: A next-generation chat plugin for Paper, Folia and Velocity. + actions: + - theme: brand + text: Download + link: /en/download + - theme: brand + text: Documentation + link: /en/docs/getting-started + - theme: alt + text: GitHub + link: https://github.com/m1sk9/LunaticChat + +features: + - title: Channel Chat + details: Create and manage channels for group conversations between specific players. Includes private channels and moderation features. + icon: ☎️ + - title: Direct Messages + details: Send 1-on-1 chats with /tell or /msg commands. Quickly reply to the last sender with /reply. + icon: ✉️ + - title: Romaji Conversion + details: Automatically convert romaji input into Japanese. Fast performance powered by caching. + icon: 🌍 + - title: Velocity Cross-Server Chat + details: Relay global chat across multiple servers via a Velocity proxy. Join conversations from any server. + icon: 🔗 + - title: Flexible Configuration + details: Toggle features on/off with a YAML-based config file. Customize to fit your server's needs. + icon: ⚙️ + - title: Latest Version Support + details: Minimal external plugin dependencies, always supporting the latest Minecraft versions. + icon: ⛏️ +--- + +<hr class="home-divider" /> + +<!-- Section 1: Channel Chat (text left, image right) --> +<div class="feature-showcase"> + <div class="feature-showcase-text"> + <h2>Organize Conversations with Channel Chat</h2> + <p> + Create channels within your server to separate conversations by topic or group. + Communicate with only the members you need, without flooding the global chat. + </p> + <ul> + <li>Create password-protected private channels</li> + <li>Per-channel moderation (kick, mute, ban)</li> + <li>Customizable join/leave notifications</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="../assets/features/channel-chat.png" alt="LunaticChat Channel Chat feature" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 2: Direct Messages (image left, text right) --> +<div class="feature-showcase reverse"> + <div class="feature-showcase-text"> + <h2>Direct Messages & Quick Reply</h2> + <p> + Easily send private 1-on-1 chats between players. + Use the <code>/reply</code> command to instantly respond to the last sender. + </p> + <ul> + <li>Send direct messages with <code>/tell</code> / <code>/msg</code></li> + <li>Instantly reply to the last sender with <code>/reply</code></li> + <li>Messages are visible only to the sender and recipient</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="../assets/features/dm.png" alt="LunaticChat Direct Message feature" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 3: Romaji Conversion (text left, image right) --> +<div class="feature-showcase"> + <div class="feature-showcase-text"> + <h2>Automatic Romaji to Japanese Conversion</h2> + <p> + Even in environments without Japanese input support, simply type in romaji and it will be automatically converted to Japanese. + Powered by the Google IME API for natural conversion results. + </p> + <ul> + <li>Real-time romaji-to-Japanese conversion while chatting</li> + <li>Fast performance with conversion result caching</li> + <li>Per-player toggle to enable/disable conversion</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="../assets/features/romaji.png" alt="LunaticChat Romaji Conversion feature" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 4: Velocity Integration (image left, text right) --> +<div class="feature-showcase reverse"> + <div class="feature-showcase-text"> + <h2>Cross-Server Chat with Velocity</h2> + <p> + Integrate with a Velocity proxy to relay global chat across multiple Paper/Folia servers. + Players can join the same chat space regardless of which server they're on. + </p> + <ul> + <li>Relay regular chat to all servers in real time</li> + <li>Fast communication via a custom plugin messaging protocol</li> + <li>Backward compatibility guaranteed through protocol versioning</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="../assets/features/cross-chat.png" alt="LunaticChat Cross-Server Chat feature" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 5: Platforms --> +<div class="platform-section"> + <h2>Multi-Platform Support</h2> + <p class="section-desc">Flexibly deploy to match your server setup</p> + <div class="platform-cards"> + <a class="platform-card" href="https://papermc.io/software/paper/" target="_blank" rel="noopener"> + <div class="platform-icon"> + <img src="../assets/brand/paper.svg" alt="Paper" width="40" height="40" /> + </div> + <p class="name">Paper</p> + <p class="desc">The most widely used Minecraft server implementation. Full support for DM, channel chat, romaji conversion, and all features. Maintains compatibility with Bukkit/Spigot plugins.</p> + </a> + <a class="platform-card" href="https://papermc.io/software/folia" target="_blank" rel="noopener"> + <div class="platform-icon"> + <img src="../assets/brand/folia.svg" alt="Folia" width="40" height="40" /> + </div> + <p class="name">Folia</p> + <p class="desc">A multithreaded server implementation by PaperMC. Provides a stable chat experience even on large-scale servers through region-based parallel processing.</p> + </a> + <a class="platform-card" href="https://papermc.io/software/velocity" target="_blank" rel="noopener"> + <div class="platform-icon"> + <img src="../assets/brand/velocity.svg" alt="Velocity" width="40" height="40" /> + </div> + <p class="name">Velocity</p> + <p class="desc">A high-performance proxy server. Install the LunaticChat Velocity plugin to enable global chat relay across multiple Paper/Folia servers.</p> + </a> + </div> +</div> diff --git a/website/src/index.md b/website/src/index.md new file mode 100644 index 0000000..007a6ad --- /dev/null +++ b/website/src/index.md @@ -0,0 +1,153 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +hero: + name: 'LunaticChat' + tagline: A next-generation chat plugin for Paper, Folia and Velocity. + actions: + - theme: brand + text: ダウンロード + link: /download + - theme: brand + text: ドキュメント + link: /docs/getting-started + - theme: alt + text: GitHub + link: https://github.com/m1sk9/LunaticChat + +features: + - title: チャンネルチャット + details: チャンネルを作成・管理し,特定のプレイヤー間でグループチャットが可能.プライベートチャンネルやモデレーション機能も搭載 + icon: ☎️ + - title: ダイレクトメッセージ + details: /tell や /msg コマンドで 1対1 のチャットが可能./reply で直前の相手に素早く返信 + icon: ✉️ + - title: ローマ字変換 + details: ローマ字で入力したメッセージを自動的に日本語に変換.キャッシュにより高速に動作 + icon: 🌍 + - title: Velocity サーバー間連携 + details: Velocity プロキシを経由して複数サーバー間でグローバルチャットをリレー.どのサーバーにいても会話に参加可能 + icon: 🔗 + - title: 柔軟な設定 + details: YAML ベースの設定ファイルで機能の有効/無効を切り替え.サーバーの用途に合わせてカスタマイズ可能 + icon: ⚙️ + - title: 最新バージョン対応 + details: 外部プラグインへの依存を最小限に抑え,常に最新の Minecraft バージョンに対応 + icon: ⛏️ +--- + +<hr class="home-divider" /> + +<!-- Section 1: チャンネルチャット (text left, image right) --> +<div class="feature-showcase"> + <div class="feature-showcase-text"> + <h2>チャンネルチャットで会話を整理</h2> + <p> + サーバー内にチャンネルを作成して,トピックやグループごとに会話を分離できます. + 全体チャットに流れることなく,必要なメンバーだけでコミュニケーションが可能です. + </p> + <ul> + <li>パスワード付きのプライベートチャンネルを作成</li> + <li>チャンネルごとのモデレーション機能(キック・ミュート・BAN)</li> + <li>チャンネル参加・退出の通知をカスタマイズ</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="./assets/features/channel-chat.png" alt="LunaticChat のチャンネルチャット機能" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 2: ダイレクトメッセージ (image left, text right) --> +<div class="feature-showcase reverse"> + <div class="feature-showcase-text"> + <h2>ダイレクトメッセージ & クイック返信</h2> + <p> + プレイヤー間で手軽に 1対1 のプライベートチャットができます. + <code>/reply</code> コマンドで直前の相手にすぐ返信でき,テンポの良いやり取りを実現します. + </p> + <ul> + <li><code>/tell</code> / <code>/msg</code> でダイレクトメッセージを送信</li> + <li><code>/reply</code> で直前の送信者に即座に返信</li> + <li>メッセージは送信者と受信者だけに表示</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="./assets/features/dm.png" alt="LunaticChat のダイレクトメッセージ機能" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 3: ローマ字変換 (text left, image right) --> +<div class="feature-showcase"> + <div class="feature-showcase-text"> + <h2>ローマ字入力を自動で日本語に</h2> + <p> + 日本語入力に対応していない環境でも,ローマ字で入力するだけで自動的に日本語に変換されます. + Google IME API を活用し,自然な変換結果を提供します. + </p> + <ul> + <li>チャット入力時にリアルタイムでローマ字→日本語変換</li> + <li>変換結果のキャッシュで高速動作を実現</li> + <li>プレイヤーごとに変換機能のオン/オフを切り替え可能</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="./assets/features/romaji.png" alt="LunaticChat のローマ字変換機能" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 4: Velocity 連携 (image left, text right) --> +<div class="feature-showcase reverse"> + <div class="feature-showcase-text"> + <h2>Velocity でサーバー間連携</h2> + <p> + Velocity プロキシと連携して,複数の Paper/Folia サーバー間でグローバルチャットをリレーします. + プレイヤーはどのサーバーにいても,同じチャット空間で会話に参加できます. + </p> + <ul> + <li>通常チャットを全サーバーにリアルタイムでリレー</li> + <li>独自のプラグインメッセージングプロトコルで高速な通信</li> + <li>プロトコルバージョニングによる後方互換性の保証</li> + </ul> + </div> + <div class="feature-showcase-image"> + <img src="./assets/features/cross-chat.png" alt="LunaticChat のクロスチャット機能" /> + </div> +</div> + +<hr class="home-divider" /> + +<!-- Section 5: プラットフォーム --> +<div class="platform-section"> + <h2>マルチプラットフォーム対応</h2> + <p class="section-desc">サーバーの構成に合わせて柔軟に導入できます</p> + <div class="platform-cards"> + <a class="platform-card" href="https://papermc.io/software/paper/" target="_blank" rel="noopener"> + <div class="platform-icon"> + <img src="./assets/brand/paper.svg" alt="Paper" width="40" height="40" /> + </div> + <p class="name">Paper</p> + <p class="desc">最も広く利用されている Minecraft サーバー実装.DM,チャンネルチャット,ローマ字変換など全機能をフルサポート.Bukkit/Spigot プラグインとの互換性も維持</p> + </a> + <a class="platform-card" href="https://papermc.io/software/folia" target="_blank" rel="noopener"> + <div class="platform-icon"> + <img src="./assets/brand/folia.svg" alt="Folia" width="40" height="40" /> + </div> + <p class="name">Folia</p> + <p class="desc">PaperMC が開発するマルチスレッド対応のサーバー実装.リージョン分割による並列処理で,大規模サーバーでも安定したチャット体験を提供</p> + </a> + <a class="platform-card" href="https://papermc.io/software/velocity" target="_blank" rel="noopener"> + <div class="platform-icon"> + <img src="./assets/brand/velocity.svg" alt="Velocity" width="40" height="40" /> + </div> + <p class="name">Velocity</p> + <p class="desc">高性能なプロキシサーバー.LunaticChat の Velocity プラグインを導入することで,複数の Paper/Folia サーバー間でグローバルチャットのリレーを実現</p> + </a> + </div> +</div> diff --git a/website/src/public/favicon.ico b/website/src/public/favicon.ico Binary files differnew file mode 100644 index 0000000..46c0cad --- /dev/null +++ b/website/src/public/favicon.ico diff --git a/website/tsconfig.json b/website/tsconfig.json new file mode 100644 index 0000000..5f61eef --- /dev/null +++ b/website/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "ESNext", + "moduleResolution": "Bundler", + "lib": ["ESNext", "DOM", "DOM.Iterable"], + "strict": true, + "jsx": "preserve", + "skipLibCheck": true + }, + "include": [".vitepress/**/*.ts", ".vitepress/**/*.mts", ".vitepress/**/*.vue"] +} diff --git a/website/wrangler.jsonc b/website/wrangler.jsonc new file mode 100644 index 0000000..c1e3ce5 --- /dev/null +++ b/website/wrangler.jsonc @@ -0,0 +1,14 @@ +{ + "$schema": "node_modules/wrangler/config-schema.json", + "name": "lunaticchat-docs", + "compatibility_date": "2025-09-27", + "observability": { + "enabled": true + }, + "assets": { + "directory": "dist" + }, + "compatibility_flags": [ + "nodejs_compat" + ] +} |
