diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index f9c68ab..0fb9175 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -9,36 +9,50 @@ on: - main jobs: - build-and-deploy: + build: runs-on: ubuntu-latest - permissions: - contents: read - pages: write - id-token: write - steps: - name: Checkout code uses: actions/checkout@v4 + with: + submodules: recursive + fetch-depth: 0 - - name: Setup Node.js - uses: actions/setup-node@v4 + - name: Setup .NET + uses: actions/setup-dotnet@v4 with: - node-version: '18' - cache: 'npm' + dotnet-version: '10.x' - - name: Install dependencies - run: npm ci + - name: Install DocFX + run: dotnet tool install -g docfx - - name: Build docs - run: npm run docs:build + - name: Build Libraries + run: cd sampsharp-src && ./build.sh component + + - name: Build documentation + run: docfx docfx.json - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: - path: 'docs/.vitepress/dist' + path: '_site' + + deploy: + needs: build + if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/dev') + runs-on: ubuntu-latest + + permissions: + contents: read + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: - name: Deploy to GitHub Pages - if: github.event_name == 'push' && github.ref == 'refs/heads/main' id: deployment uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index eea115b..8944657 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ -node_modules/ -docs/.vitepress/dist/ -docs/.vitepress/cache/ -.DS_Store -*.local -.env.local +_site/** + +api/** +!api/index.md \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cd9d23f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sampsharp-src"] + path = sampsharp-src + url = https://github.com/ikkentim/sampsharp.git diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..345304b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Run open.mp gamemode", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/sampsharp-src/test/TestMode.OpenMp.Entities/TestMode.OpenMp.Entities.csproj" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f56dc72 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "chat.tools.terminal.autoApprove": { + "docfx": true, + "test": true + }, + "cSpell.words": ["blockquotes", "frontmatter", "sampsharp", "textdraw"] +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..976aeb9 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,13 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "docfx serve", + "type": "shell", + "command": "docfx", + "args": ["--serve"], + "isBackground": true, + "problemMatcher": [] + } + ] +} diff --git a/404.md b/404.md new file mode 100644 index 0000000..3bddf45 --- /dev/null +++ b/404.md @@ -0,0 +1,92 @@ +--- +title: Page Not Found +_disableContribution: true +_disableAfaf: true +--- + + + +
+ +
+ +#

404

+ +

Page Not Found

+ +

Sorry, we couldn't find the page you're looking for. It may have been moved or no longer exists.

+ + + +
+ +
diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..13731e8 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,166 @@ +--- +title: DocFX Cross-Reference (xref) Guide +--- + +# DocFX Cross-Reference (xref) Guide + +This file summarizes all essential knowledge for writing correct cross-references (xrefs) in DocFX-based documentation, so you never make mistakes again. + +## 1. YAML Frontmatter and UID +- Every conceptual Markdown file that should be referenced **must** have a unique `uid` in its YAML frontmatter: + ```yaml + --- + title: My Page Title + uid: my-unique-id + --- + ``` +- The `uid` must be unique within the documentation set. +- If a file has no `uid`, it **cannot** be referenced via xref. +- For API reference files, the UID is auto-generated from the API signature (e.g., `System.String`). + +## 2. Basic xref Syntax +- To reference a UID from anywhere in your docs, use: + ``` + + ``` +- Or, for Markdown link text: + ``` + [Link Text](xref:my-unique-id) + ``` +- This works for both conceptual docs and API docs. + +## 3. Best Practices +- Always check that the target file has a `uid` in its YAML frontmatter. +- Use short, descriptive UIDs (lowercase, hyphens/underscores if needed). +- Never duplicate UIDs across files. +- Prefer `xref:` links over relative links for conceptual docs when possible. +- For API docs, use the full type/member name as UID (e.g., `System.String`, `MyNamespace.MyClass.MyMethod`). + +## 4. Troubleshooting +- If an xref link does not resolve, check: + - The target file has a `uid`. + - The UID is spelled correctly. + - The UID is unique. +- Use DocFX build output to spot unresolved xrefs. + +## 5. Example +```markdown +See [the events article](xref:events) for more details. +``` + +## 6. Useful Links +- [DocFX Markdown Documentation](https://dotnet.github.io/docfx/docs/markdown.html) +- [DocFX Links and Cross References](https://dotnet.github.io/docfx/docs/links-and-cross-references.html) + +--- + +**Summary:** +- Always use `uid` in YAML frontmatter for xref targets. +- Use `xref:uid` syntax for cross-references. +- Check for uniqueness and spelling. +- Prefer xref over relative links for maintainability. + +--- + +## 7. DocFX Markdown Features Cheat Sheet + +### Alerts +Use blockquotes with special keywords for colored callouts: + +``` +> [!NOTE] +> Information the user should notice even if skimming. + +> [!TIP] +> Optional information to help a user be more successful. + +> [!IMPORTANT] +> Essential information required for user success. + +> [!CAUTION] +> Negative potential consequences of an action. + +> [!WARNING] +> Dangerous certain consequences of an action. +``` + +### Includes +Reuse content from other markdown files: + +Inline include: +``` +Text before [!INCLUDE [](<filepath>)] and after. +``` +Block include: +``` +[!INCLUDE [my-block](../../includes/my-block.md)] +``` + +### Code Snippets +Embed code from files, optionally with line/region selection and highlights: +``` +[!code-csharp[](Program.cs)] +[!code-csharp[](Program.cs#region)] +[!code-csharp[](Program.cs#L12-L16)] +[!code-csharp[](Program.cs?highlight=2,5-7,9-)] +``` + +### Tabs +Create tabbed content for platform or language variants: +``` +# [Linux](#tab/linux) +Linux content... + +# [Windows](#tab/windows) +Windows content... + +--- +``` + +### Diagrams +Embed diagrams using mermaid or PlantUML: + +**Mermaid:** +```` +```mermaid +flowchart LR + A --> B +``` +```` + +**PlantUML:** +```` +```plantuml +Bob -> Alice : hello +``` +```` + +### Math Expressions +Use LaTeX math inline or as blocks (modern template only): + +Inline: `This is inline math: $\sqrt{3x-1}$` + +Block: +``` +$$ +\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) +$$ +``` + +### Images & Video +Embed images: +``` +![alt-text](image-link.png) +``` +Embed video: +``` +> [!Video https://www.youtube.com/embed/ID] +``` + +--- + +**Summary:** +- Always use `uid` in YAML frontmatter for xref targets. +- Use `xref:uid` syntax for cross-references. +- Prefer xref over relative links for maintainability. +- Use DocFX Markdown features (alerts, includes, code snippets, tabs, diagrams, math, etc.) for rich documentation. diff --git a/README.md b/README.md index dec34bf..6a387c6 100644 --- a/README.md +++ b/README.md @@ -1,104 +1,100 @@ # SampSharp Documentation -This repository contains the SampSharp documentation source files. The site is built with [VitePress](https://vitepress.dev/), a fast, modern static site generator. +This repository contains the source files for the SampSharp documentation. The site is built with [DocFX](https://dotnet.github.io/docfx/), a powerful documentation generator designed for .NET projects. -## For Documentation Maintainers +> **For Documentation Contributors Only** +> +> This guide is intended for people contributing to the SampSharp documentation. If you're looking for SampSharp documentation, visit [sampsharp.net](https://sampsharp.net). + +## Quick Start ### Prerequisites -- Node.js 18+ -- npm +- .NET 10 SDK or later ### Running Locally -1. Install dependencies: +1. Install DocFX (one-time setup): ```bash - npm install + dotnet tool install -g docfx ``` -2. Start the development server: +2. Build the SampSharp component: ```bash - npm run docs:dev + cd sampsharp-src && ./build.sh component ``` - The site will be available at `http://localhost:5173/` - -3. Build the static site: - - ```bash - npm run docs:build - ``` +3. Start the development server: -4. Preview the production build locally: ```bash - npm run docs:preview + docfx --serve ``` -### Adding/Editing Documentation - -All documentation is written in Markdown in the `docs/` folder. - -- **Create a new page**: Add a new `.md` file in `docs/` -- **Update navigation**: Edit `docs/.vitepress/config.js` to add the page to the sidebar -- Links use absolute paths: `/page-name` not `./page-name` -- Internal links should use absolute paths -- External links require full URLs: `https://example.com` -- File names are case-sensitive on Linux/Mac - -### Project Structure + The site will be available at `http://localhost:8080/` -``` -├── docs/ -│ ├── .vitepress/ -│ │ ├── config.js # VitePress configuration -│ │ └── theme/ -│ │ ├── index.js # Theme entry point -│ │ └── style.css # Custom styles -│ ├── index.md # Home page -│ ├── introduction.md # Documentation pages -│ ├── getting-started.md -│ ├── images/ # Images and assets -│ └── ...other markdown files -├── .github/ -│ └── workflows/ -│ └── deploy.yml # GitHub Actions workflow for auto-deployment -├── package.json -└── README.md -``` - -### Troubleshooting - -**Build errors about dead links** +## Contributing -Check: +### Writing Documentation -- Internal links should use absolute paths: `/page-name` not `./page-name` -- External links should include full URLs: `https://example.com` -- File names must match exactly (case-sensitive on Linux/Mac) +All documentation is written in Markdown in the `docs/` folder. For Markdown syntax reference, see the [DocFX Markdown Documentation](https://dotnet.github.io/docfx/docs/markdown.html). -**Syntax highlighting not working for code blocks** +#### Adding a New Page -Some languages (like PAWN) may not be built-in. The build will fall back to text highlighting, which is fine. +1. Create a new `.md` file in the appropriate folder under `docs/`: + - `docs/guides/` - How-to guides and tutorials + - `docs/reference/` - Reference material + - `docs/support/` - Support content (troubleshooting, migration guides) -**Site not deploying via GitHub Actions** +2. Add a YAML frontmatter header to the file: + ```yaml + --- + title: Your Page Title + uid: unique-identifier + --- + ``` -1. Check that your repository has a `main` branch (not `master`) -2. Verify GitHub Pages is configured to use GitHub Actions as source -3. Check the Actions tab in your GitHub repository for error logs +3. Add the file reference to the corresponding `toc.yml`: + ```yaml + - href: your-page.md + ``` -## Deployment +#### Documentation Structure -The site automatically deploys to GitHub Pages when you push to the `main` branch via the GitHub Actions workflow (`.github/workflows/deploy.yml`). +``` +docs/ +├── index.md # Home page +├── getting-started.md # Getting started guide +├── core-concepts.md # Core concepts +├── guides/ +│ ├── toc.yml # Guides table of contents +│ ├── systems.md +│ ├── components.md +│ └── ... +├── reference/ +│ ├── toc.yml # Reference table of contents +│ ├── advanced-topics.md +│ └── ... +├── support/ +│ ├── toc.yml # Support table of contents +│ ├── troubleshooting.md +│ └── ... +├── legacy/ # Deprecated content +└── toc.yml # Main table of contents +``` -To manually deploy or host elsewhere: +### Markdown Tips -1. Build: `npm run docs:build` -2. Upload the contents of `docs/.vitepress/dist/` to your hosting provider -3. Configure your web server to serve the static files +- **Internal links**: Use relative paths with `.md` extension: `[link text](systems.md)` or `[link text](../guides/systems.md)` +- **External links**: Use full URLs: `[link text](https://example.com)` +- **Cross-references**: Link to other documentation pages using `<xref:uid>` (where `uid` is the page's `uid` field from frontmatter): `<xref:systems>` +- **Note blocks**: Use `> [!NOTE]` syntax for important callouts +- **Tabs**: Use DocFX tab syntax for tabbed content (see [DocFX Markdown Documentation](https://dotnet.github.io/docfx/docs/markdown.html)) +- **Code references**: Use `<xref:NameSpace.ClassName>` to create cross-references to API documentation ## Resources -- [VitePress Documentation](https://vitepress.dev/) +- [DocFX Documentation](https://dotnet.github.io/docfx/) +- [DocFX Markdown Guide](https://dotnet.github.io/docfx/docs/markdown.html) - [SampSharp Project](https://sampsharp.net/) diff --git a/api/index.md b/api/index.md new file mode 100644 index 0000000..8486f2b --- /dev/null +++ b/api/index.md @@ -0,0 +1,3 @@ +# API Reference + +This section contains the complete API reference for SampSharp. You can find detailed information about all classes, methods, properties, and events available in the framework. \ No newline at end of file diff --git a/docs/images/sampsharp.png b/assets/sampsharp.png similarity index 100% rename from docs/images/sampsharp.png rename to assets/sampsharp.png diff --git a/clean.cmd b/clean.cmd new file mode 100644 index 0000000..3a856de --- /dev/null +++ b/clean.cmd @@ -0,0 +1,15 @@ +@echo off +setlocal enabledelayedexpansion +cd /d "%~dp0" +if exist "_site" rmdir /s /q "_site" +cd /d "%~dp0api" +for /f "delims=" %%A in ('dir /b') do ( + if /i not "%%A"=="index.md" ( + if exist "%%A\*" ( + rmdir /s /q "%%A" + ) else ( + del /q "%%A" + ) + ) +) +echo Cleanup completed. Deleted _site directory and all files in ./api except index.md diff --git a/clean.sh b/clean.sh new file mode 100644 index 0000000..9949795 --- /dev/null +++ b/clean.sh @@ -0,0 +1,7 @@ +#!/bin/bash +BASE_DIR="$(dirname "$0")" +cd "$BASE_DIR" +rm -rf _site +cd "$BASE_DIR/api" +find . -maxdepth 1 -not -name "index.md" -not -name "." -exec rm -rf {} + 2>/dev/null +echo "Cleanup completed. Deleted _site directory and all files in ./api except index.md" diff --git a/docfx.json b/docfx.json new file mode 100644 index 0000000..e80c65b --- /dev/null +++ b/docfx.json @@ -0,0 +1,47 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/docfx/main/schemas/docfx.schema.json", + "metadata": [ + { + "src": [ + { + "src": "sampsharp-src", + "files": [ + "build/bin/SampSharp.OpenMp.Entities.Commands/Release/net10.0/SampSharp.OpenMp.Entities.Commands.dll", + "build/bin/SampSharp.OpenMp.Entities/Release/net10.0/SampSharp.OpenMp.Entities.dll", + "build/bin/SampSharp.OpenMp.Core/Release/net10.0/SampSharp.OpenMp.Core.dll" + ] + } + ], + "dest": "api" + } + ], + "build": { + "content": [ + { + "files": ["**/*.{md,yml}"], + "exclude": ["_site/**", "sampsharp-src/**"] + } + ], + "resource": [ + { + "files": ["docs/**/images/**", "assets/**"] + } + ], + "globalMetadata": { + "_appTitle": "SampSharp", + "_appName": "SampSharp", + "_appLogoPath": "assets/sampsharp.png", + "_appFaviconPath": "assets/sampsharp.png", + "_appFooter": "SampSharp - Copyright © 2015 - 2026 Tim Potze", + "_enableSearch": true, + "pdf": false, + "_gitContribute": { + "repo": "https://github.com/sampsharp/docs", + "branch": "main", + "apiSpecFolder": "docs" + } + }, + "template": ["default", "modern", "template/"], + "output": "_site" + } +} diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js deleted file mode 100644 index 9504fbe..0000000 --- a/docs/.vitepress/config.js +++ /dev/null @@ -1,64 +0,0 @@ -import { defineConfig } from 'vitepress' - -export default defineConfig({ - title: "SampSharp", - description: ".NET SA-MP", - head: [ - ['link', { rel: 'icon', href: '/sampsharp.png' }], - ['meta', { name: 'theme-color', content: '#3c3c3c' }] - ], - - themeConfig: { - logo: '/sampsharp.png', - - nav: [ - { text: 'Documentation', link: '/introduction' }, - { text: 'API', link: 'https://api.sampsharp.net/' }, - { text: 'Download', link: 'https://github.com/ikkentim/sampsharp/releases' } - ], - - sidebar: [ - { - text: 'Basics', - items: [ - { text: 'Introduction', link: '/introduction' }, - { text: 'Getting Started', link: '/getting-started' }, - { text: 'Running a Server in Production', link: '/production' }, - { text: 'Troubleshooting', link: '/troubleshooting' }, - { text: 'GameModeBuilder', link: '/game-mode-builder' } - ] - }, - { - text: 'Advanced', - items: [ - { text: 'Natives', link: '/natives' }, - { text: 'Threading', link: '/threading' } - ] - }, - { - text: 'GameMode Framework', - items: [ - { text: 'GameMode', link: '/gamemode-game-mode' }, - { text: 'Players', link: '/gamemode-players' }, - { text: 'Dialogs', link: '/gamemode-dialogs' }, - { text: 'TextDraws', link: '/gamemode-textdraws' }, - { text: 'Player-Commands', link: '/gamemode-player-commands' }, - { text: 'Accessing server.cfg', link: '/gamemode-accessing-server.cfg' }, - { text: 'Controllers', link: '/gamemode-controllers' }, - { text: 'Callbacks', link: '/gamemode-callbacks' }, - { text: 'Extensions', link: '/gamemode-extensions' } - ] - } - ], - - socialLinks: [ - { icon: 'github', link: 'https://github.com/ikkentim/sampsharp' }, - { icon: 'discord', link: 'https://discord.com/invite/gwcHpqp' } - ], - - footer: { - message: 'SampSharp - Copyright © 2015 - 2026 Tim Potze', - copyright: '' - } - } -}) diff --git a/docs/.vitepress/theme/CustomHome.vue b/docs/.vitepress/theme/CustomHome.vue deleted file mode 100644 index d034407..0000000 --- a/docs/.vitepress/theme/CustomHome.vue +++ /dev/null @@ -1,140 +0,0 @@ -<template> - <div class="home"> - <!-- Hero Section --> - <section class="hero"> - <div class="hero-inner"> - <div class="hero-content"> - <h1 class="tagline">{{ hero.name }}</h1> - <p class="text">{{ hero.text }}</p> - <div v-if="hero.actions" class="actions"> - <a v-for="action in hero.actions" :key="action.link" :href="action.link" :class="`action action-${action.theme}`"> - {{ action.text }} - </a> - </div> - </div> - <div v-if="hero.image" class="hero-image"> - <img :src="hero.image.src" :alt="hero.image.alt" /> - </div> - </div> - </section> - </div> -</template> - -<script setup> -import { useData } from 'vitepress' - -const { frontmatter } = useData() - -const hero = frontmatter.value.hero || {} -</script> - -<style scoped> -.home { - width: 100%; -} - -.hero { - margin: 0 auto; - padding: 5rem 2rem; -} - -.hero-inner { - display: flex; - align-items: center; - justify-content: space-between; - gap: 3rem; - margin: 0 auto; - max-width: 1200px; -} - -.hero-content { - flex: 1; -} - -.tagline { - font-size: 3.2rem; - font-weight: 700; - line-height: 1.2; - margin: 0; - color: var(--vp-c-text-1); -} - -.text { - font-size: 1.5rem; - line-height: 1.6; - color: var(--vp-c-text-2); - margin: 2rem 0; -} - -.actions { - display: flex; - gap: 1rem; -} - -.action { - display: inline-block; - padding: 0.75rem 1.5rem; - border-radius: 6px; - font-weight: 600; - text-decoration: none; - transition: all 0.3s; - border: 1px solid transparent; - cursor: pointer; -} - -.action-brand { - background-color: var(--vp-c-brand); - color: white; -} - -.action-brand:hover { - background-color: var(--vp-c-brand-dark); -} - -.action-alt { - border: 1px solid var(--vp-c-brand); - color: var(--vp-c-brand); -} - -.action-alt:hover { - background-color: var(--vp-c-brand-dimm); -} - -.hero-image { - flex: 1; - text-align: center; -} - -.hero-image img { - max-width: 100%; - height: auto; -} - -@media (max-width: 768px) { - .hero-inner { - flex-direction: column; - } - - .tagline { - font-size: 2rem; - } - - .text { - font-size: 1.1rem; - } - - .actions { - flex-direction: column; - width: 100%; - } - - .action { - width: 100%; - text-align: center; - } - - .hero { - padding: 3rem 1rem; - } -} -</style> diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js deleted file mode 100644 index 2dec657..0000000 --- a/docs/.vitepress/theme/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { h } from 'vue' -import DefaultTheme from 'vitepress/theme' -import './style.css' - -export default { - extends: DefaultTheme, - Layout() { - return h(DefaultTheme.Layout) - } -} diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css deleted file mode 100644 index 130f829..0000000 --- a/docs/.vitepress/theme/style.css +++ /dev/null @@ -1,11 +0,0 @@ -:root { - --vp-c-brand: #3c3c3c; - --vp-c-brand-dark: #2a2a2a; - --vp-c-brand-dimm: rgba(60, 60, 60, 0.08); -} - -html.dark { - --vp-c-brand: #4a4a4a; - --vp-c-brand-dark: #5a5a5a; - --vp-c-brand-dimm: rgba(74, 74, 74, 0.16); -} diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md deleted file mode 100644 index 1216a7f..0000000 --- a/docs/_Sidebar.md +++ /dev/null @@ -1,24 +0,0 @@ -Basics ------- -- [Introduction](introduction) -- [Getting Started](getting-started) -- [Running a Server in Production](production) -- [Troubleshooting](troubleshooting) -- [GameModeBuilder](game-mode-builder) - -Advanced ----- -- [Natives](natives) -- [Threading](threading) - -GameMode Framework ------------------ -- [GameMode](gamemode-game-mode) -- [Players](gamemode-players) -- [Dialogs](gamemode-dialogs) -- [TextDraws](gamemode-textdraws) -- [Player-Commands](gamemode-player-commands) -- [Accessing server.cfg](gamemode-accessing-server.cfg) -- [Controllers](gamemode-controllers) -- [Callbacks](gamemode-callbacks) -- [Extensions](gamemode-extensions) diff --git a/docs/core-concepts/entities-components.md b/docs/core-concepts/entities-components.md new file mode 100644 index 0000000..2c921ea --- /dev/null +++ b/docs/core-concepts/entities-components.md @@ -0,0 +1,145 @@ +--- +title: Entities and Components +uid: entities-components +--- + +# Entities and Components + +In SampSharp, an **entity** is a unique object in the game world, such as a player, vehicle, or object. **Components** are data containers that are attached to entities to define their properties or state. Components should not contain logic or behavior; instead, logic is implemented in systems that operate on entities with specific components. An entity only exists in the ECS world when it has at least one component attached. + +Entities and components are the building blocks of the ECS architecture: +- Entities are identified by an `EntityId` (<xref:SampSharp.Entities.EntityId>) +- Components are subclasses of <xref:SampSharp.Entities.Component> +- Systems operate on entities by querying for specific component combinations + +## Creating Entities + +Entities are created implicitly when you add the first component to a new `EntityId`. You can generate a new entity identifier using: + + +```csharp +var entityId = EntityId.NewEntityId(); +``` + +To add a component and thus create the entity, use the <xref:SampSharp.Entities.IEntityManager> interface. For example, with a custom component: + +```csharp +var myComponent = entityManager.AddComponent<MyFirstComponent>(entityId); +``` + +- The entity is created when the first component is added. +- You can add more components to the same entity using the same `entityId`. + +> [!NOTE] +> Built-in components such as <xref:SampSharp.Entities.SAMP.Player>, <xref:SampSharp.Entities.SAMP.Pickup>, and <xref:SampSharp.Entities.SAMP.Vehicle> are managed by SampSharp and should not be manually added to an entity. + +## Creating Custom Components + +To create a custom component, simply inherit from <xref:SampSharp.Entities.Component>: + +```csharp +public class BankAccount : Component +{ + public decimal Balance { get; set; } + + public void Deposit(decimal amount) + { + Balance += amount; + } + + public void Withdraw(decimal amount) + { + if (amount <= Balance) + Balance -= amount; + } +} +``` + +You can then add your custom component to an entity: + +```csharp +var accountComponent = player.AddComponent<BankAccount>(); +accountComponent.Deposit(100); +``` + +## Entity Hierarchy and Nesting + + +Entities can be organized in a parent-child hierarchy. When you add a component to an entity, you can specify a parent entity: + +```csharp +var childId = EntityId.NewEntityId(); +entityManager.AddComponent<BankAccount>(childId, parentId); +``` + +- Destroying a parent entity will recursively destroy all its children and their components. + +### Entity Hierarchy Example + +Below is a diagram showing entities, their nested structure, and attached components: + + +```mermaid +graph TD + A(Root Entity) --> B[Player] + A --> C[BankAccount] + A --> E[Inventory] + A --> D(Child Entity) + D --> F[Vehicle] + D --> I[IgnitionLock] + A --> G(Another Child Entity) + G --> H[QuestStatus] +``` + +## Destroying Entities and Components + +Destroying an entity removes all its components and recursively destroys all child entities. +You can destroy an entity using: + +```csharp +entityManager.Destroy(entityId); +``` + +Or from a component: + +```csharp +component.DestroyEntity(); +``` + +You can also destroy a single component: + +```csharp +component.Destroy(); +``` + +## Working with Components from a Component + +From any <xref:SampSharp.Entities.Component>, you can: +- Get another component on the same entity: `component.GetComponent<OtherComponent>()` +- Add a component to the same entity: `component.AddComponent<OtherComponent>()` +- Get components in children or parent entities: `component.GetComponentInChildren<T>()`, `component.GetComponentInParent<T>()`, etc. + +See <xref:SampSharp.Entities.Component> for all available methods. + +## Provided Components in SampSharp + +Below is a list of the most important components provided by SampSharp: + +| Component | Description | +|-----------|-------------| +| <xref:SampSharp.Entities.SAMP.Actor> | Represents an actor (non-movable NPC) in the world | +| <xref:SampSharp.Entities.SAMP.Class> | Represents a player class | +| <xref:SampSharp.Entities.SAMP.GangZone> | Represents a gang zone | +| <xref:SampSharp.Entities.SAMP.GlobalObject> | Represents an object | +| <xref:SampSharp.Entities.SAMP.Menu> | Represents a menu | +| <xref:SampSharp.Entities.SAMP.Npc> | Represents a non-player character | +| <xref:SampSharp.Entities.SAMP.Pickup> | Represents a pickup item | +| <xref:SampSharp.Entities.SAMP.Player> | Represents a player | +| <xref:SampSharp.Entities.SAMP.PlayerGangZone> | Player-specific gang zone | +| <xref:SampSharp.Entities.SAMP.PlayerObject> | Player-specific object | +| <xref:SampSharp.Entities.SAMP.PlayerPickup> | Player-specific pickup | +| <xref:SampSharp.Entities.SAMP.PlayerTextDraw> | Player-specific textdraw | +| <xref:SampSharp.Entities.SAMP.PlayerTextLabel> | Player-specific text label | +| <xref:SampSharp.Entities.SAMP.TextDraw> | Represents a textdraw | +| <xref:SampSharp.Entities.SAMP.TextLabel> | Represents a text label | +| <xref:SampSharp.Entities.SAMP.Vehicle> | Represents a vehicle | diff --git a/docs/core-concepts/events.md b/docs/core-concepts/events.md new file mode 100644 index 0000000..f02c7e9 --- /dev/null +++ b/docs/core-concepts/events.md @@ -0,0 +1,320 @@ +--- +title: Events +uid: events +--- + +# Events + +Events are how SampSharp systems respond to game world changes. Built-in events like player connect/disconnect, entering vehicles, and damage trigger event handlers in your systems. + +## Handling Events with the [Event] Attribute + +To handle an event, add the `[Event]` attribute to a method in your <xref:systems>. The method name determines which event is handled, unless you specify a custom name. + +Multiple systems can handle the same event—each registered handler will be invoked when the event fires. If the event has a bool return value, handlers work together to produce a final result (see [Event Return Values](#event-return-values) below). + +```csharp +using SampSharp.Entities; +using SampSharp.Entities.SAMP; + +public class PlayerSystem : ISystem +{ + [Event] + public void OnPlayerConnect(Player player) + { + player.SendClientMessage("Welcome to the server!"); + } + + [Event] + public void OnPlayerDisconnect(Player player) + { + Console.WriteLine($"{player.Name} disconnected."); + } +} +``` + +### Custom Event Names + +If your method name doesn't match the event name, use the `Name` parameter: + +```csharp +[Event(Name = "OnPlayerRequestClass")] +public void HandleClassSelection(Player player, Class klass) +{ + player.SendClientMessage($"You selected class: {klass.Id}"); +} +``` + +### Dependency Injection in Event Handlers + +Event handlers can accept services via dependency injection alongside event parameters: + +```csharp +[Event] +public void OnPlayerText(Player player, string message, IWorldService worldService) +{ + // player and message come from the event + // worldService is injected + Console.WriteLine($"{player.Name}: {message}"); +} +``` + +## Built-in Game Events + +SampSharp provides many built-in events for common game world interactions. Here's a comprehensive reference organized by category. Events that return a value are noted with their return type. + +### Server & Initialization +- `OnGameModeInit()` : void — Called when the server starts. +- `OnGameModeExit()` : void — Called when the server exits/shuts down. + +### Player Connection +- `OnIncomingConnection(Player, string ipAddress, int port)` : void — Called before a player connects (can reject connection). +- `OnPlayerConnect(Player)` : void — Called when a player connects. +- `OnPlayerDisconnect(Player, DisconnectReason reason)` : void — Called when a player disconnects. +- `OnPlayerClientInit(Player)` : void — Called after a player's client has fully initialized. + +### Player Classes & Spawning +- `OnPlayerRequestClass(Player, Class)` : void — Called when a player selects a class at class selection. +- `OnPlayerRequestSpawn(Player)` : bool (default: `true`) — Called when a player attempts to spawn (return false to reject). +- `OnPlayerSpawn(Player)` : void — Called when a player spawns. + +### Player Movement & Updates +- `OnPlayerStreamIn(Player, Player forPlayer)` : void — Called when a player streams in for another player. +- `OnPlayerStreamOut(Player, Player forPlayer)` : void — Called when a player streams out for another player. +- `OnPlayerUpdate(Player, DateTime)` : bool (default: `true`) — Called every player update (return false to reject). + +### Player Text & Commands +- `OnPlayerText(Player, string message)` : bool (default: `true`) — Called when a player sends chat (return false to suppress message). +- `OnPlayerCommandText(Player, string text)` : bool (default: `false`) — Called for unhandled chat starting with `/` (return true to handle). + +### Player Interactions +- `OnPlayerClickMap(Player, Vector3 position)` : void — Called when a player clicks the map. +- `OnPlayerClickPlayer(Player, Player clicked, ClickSource source)` : void — Called when a player clicks another player. + +### Checkpoints +- `OnPlayerEnterCheckpoint(Player)` : void — Called when a player enters a checkpoint. +- `OnPlayerLeaveCheckpoint(Player)` : void — Called when a player leaves a checkpoint. +- `OnPlayerEnterRaceCheckpoint(Player)` : void — Called when a player enters a race checkpoint. +- `OnPlayerLeaveRaceCheckpoint(Player)` : void — Called when a player leaves a race checkpoint. + +### Dialogs +- `OnDialogResponse(Player, int dialogId, DialogResponse response, int listItem, string inputText)` : void — Called when a player responds to a dialog. + +### Health & Damage +- `OnPlayerDeath(Player, Player killer, Weapon reason)` : void — Called when a player dies. +- `OnPlayerTakeDamage(Player, Player from, float amount, Weapon weapon, BodyPart part)` : void — Called when a player takes damage. +- `OnPlayerGiveDamage(Player, Player to, float amount, Weapon weapon, BodyPart part)` : void — Called when a player deals damage. + +### Vehicles +- `OnVehicleStreamIn(Vehicle, Player forPlayer)` : void — Called when a vehicle streams in. +- `OnVehicleStreamOut(Vehicle, Player forPlayer)` : void — Called when a vehicle streams out. +- `OnVehicleSpawn(Vehicle)` : void — Called when a vehicle spawns. +- `OnVehicleDeath(Vehicle)` : void — Called when a vehicle is destroyed. +- `OnVehicleDamageStatusUpdate(Vehicle)` : void — Called when vehicle damage updates. +- `OnPlayerEnterVehicle(Player, Vehicle, bool asPassenger)` : void — Called when a player enters a vehicle. +- `OnPlayerExitVehicle(Player, Vehicle)` : void — Called when a player exits a vehicle. +- `OnUnoccupiedVehicleUpdate(Vehicle)` : bool (default: `true`) — Called for unoccupied vehicle updates (return false to reject). +- `OnTrailerUpdate(Vehicle trailer)` : bool (default: `true`) — Called for trailer updates (return false to reject). +- `OnVehicleSirenStateChange(Vehicle)` : bool (default: `true`) — Called when vehicle siren state changes (return false to reject). +- `OnVehiclePaintJob(Player, Vehicle, int paintJob)` : bool (default: `true`) — Called when a player modifies paintjob (return false to reject). +- `OnVehicleMod(Player, Vehicle, int componentId)` : bool (default: `true`) — Called when a player adds a mod (return false to reject). +- `OnVehicleRespray(Player, Vehicle, int color1, int color2)` : bool (default: `true`) — Called when a player resprays (return false to reject). +- `OnEnterExitModShop(Player, bool enter, ModShop modShop)` : void — Called when entering/exiting mod shop. + +### Objects +- `OnObjectMoved(Object)` : void — Called when an object finishes moving. +- `OnPlayerObjectMoved(Player, PlayerObject)` : void — Called when a player object finishes moving. +- `OnObjectSelected(Player, Object, int model, Vector3 position)` : void — Called when a player selects an object. +- `OnPlayerObjectSelected(Player, PlayerObject, int model, Vector3 position)` : void — Called when a player selects their object. +- `OnObjectEdited(Player, Object, int response, Vector3 offset, Vector3 rotation)` : void — Called when an object is edited. +- `OnPlayerObjectEdited(Player, PlayerObject, int response, Vector3 offset, Vector3 rotation)` : void — Called when a player object is edited. +- `OnPlayerAttachedObjectEdited(Player, int index, bool saved, AttachedObjectEditData data)` : void — Called when attached object is edited. + +### Text Draws +- `OnPlayerClickTextDraw(Player, TextDraw)` : void — Called when a player clicks a text draw. +- `OnPlayerClickPlayerTextDraw(Player, PlayerTextDraw)` : void — Called when a player clicks their text draw. +- `OnPlayerCancelTextDrawSelection(Player)` : bool (default: `true`) — Called when canceling text draw selection (return false to reject). +- `OnPlayerCancelPlayerTextDrawSelection(Player)` : bool (default: `true`) — Called when canceling player text draw selection (return false to reject). + +### Menus +- `OnPlayerSelectedMenuRow(Player, Menu, int row)` : void — Called when a player selects a menu row. +- `OnPlayerExitedMenu(Player)` : void — Called when a player closes a menu. + +### Actors +- `OnActorStreamIn(Actor, Player forPlayer)` : void — Called when an actor streams in. +- `OnActorStreamOut(Actor, Player forPlayer)` : void — Called when an actor streams out. +- `OnPlayerGiveDamageActor(Player, Actor, float amount, Weapon weapon, BodyPart part)` : void — Called when a player damages an actor. + +### NPCs +- `OnNPCCreate(NPC)` : void — Called when an NPC is created. +- `OnNPCDestroy(NPC)` : void — Called when an NPC is destroyed. +- `OnNPCSpawn(NPC)` : void — Called when an NPC spawns. +- `OnNPCRespawn(NPC)` : void — Called when an NPC respawns. +- `OnNPCFinishMove(NPC)` : void — Called when an NPC finishes moving. +- `OnNPCDeath(NPC, Player killer, Weapon reason)` : void — Called when an NPC dies. +- `OnNPCWeaponStateChange(NPC, Weapon oldWeapon, Weapon newWeapon)` : void — Called when NPC weapon changes. +- `OnNPCPlaybackStart(NPC, Playback playback)` : void — Called when NPC playback starts. +- `OnNPCPlaybackEnd(NPC, Playback playback)` : void — Called when NPC playback ends. +- `OnNPCFinishNodePoint(NPC, int nodePoint)` : void — Called when NPC reaches a node point. +- `OnNPCFinishNode(NPC, int node)` : void — Called when NPC finishes a node. +- `OnNPCFinishMovePathPoint(NPC, int pathPoint)` : void — Called when NPC reaches a move path point. +- `OnNPCFinishMovePath(NPC, MovePath path)` : void — Called when NPC finishes a move path. +- `OnNPCTakeDamage(NPC, Player from, float amount, Weapon weapon, BodyPart part)` : bool (default: `true`) — Called when NPC takes damage (return false to reject). +- `OnNPCGiveDamage(NPC, Player to, float amount, Weapon weapon, BodyPart part)` : bool (default: `true`) — Called when NPC deals damage (return false to reject). +- `OnNPCShotMissed(NPC, Weapon weapon, Vector3 position)` : bool (default: `true`) — Called when NPC misses a shot (return false to reject). +- `OnNPCShotPlayer(NPC, Player target, Weapon weapon, BodyPart part)` : bool (default: `true`) — Called when NPC shoots a player (return false to reject). + +### Weapon & Shooting +- `OnPlayerShotMissed(Player, Weapon weapon, BulletData bulletData)` : bool (default: `true`) — Called when a player misses a shot (return false to reject). +- `OnPlayerShotPlayer(Player, Player target, Weapon weapon, BulletData bulletData)` : bool (default: `true`) — Called when a player shoots another player (return false to reject). +- `OnPlayerShotVehicle(Player, Vehicle target, Weapon weapon, BulletData bulletData)` : bool (default: `true`) — Called when a player shoots a vehicle (return false to reject). +- `OnPlayerShotObject(Player, Object target, Weapon weapon, BulletData bulletData)` : bool (default: `true`) — Called when a player shoots an object (return false to reject). +- `OnPlayerShotPlayerObject(Player, PlayerObject target, Weapon weapon, BulletData bulletData)` : bool (default: `true`) — Called when a player shoots a player object (return false to reject). + +### Custom Models & Downloads +- `OnPlayerRequestDownload(Player, CustomModelType type, int modelId)` : bool (default: `true`) — Called when a player downloads a custom model (return false to reject). +- `OnPlayerFinishedDownloading(Player)` : void — Called when a player finishes downloading custom models. + +### Console & Admin +- `OnRconLoginAttempt(Player, string password, bool success)` : void — Called when attempting RCON login. +- `OnConsoleCommandListRequest(ConsoleCommandCollection commands)` : void — Called when console command list is requested. + +## Event Return Values + +Some events return `bool` to control behavior. The return value determines what happens next: + +- **`true`** — Event is considered "handled" or "accepted". The server continues with the action (e.g., allows a spawn, propagates a trailer update). +- **`false`** — Event is "not handled" or "rejected". The server may skip the action or skip default behavior (e.g., prevents a spawn, blocks a command). + +If a handler doesn't explicitly return a value (returns `void`), the event uses a sensible default: +- Events that represent "can this happen?" queries default to `true` (allow it). +- Events that represent "did anyone handle this?" queries default to `false` (not handled). + +### Examples + +- **`OnPlayerText`** — Return `false` to suppress the message (it won't propagate to chat). Return `true` to allow the message to propagate normally. +- **`OnPlayerCommandText`** — Return `true` means you handled the command. Return `false` means command was not handled. +- **`OnPlayerRequestSpawn`** — Return `false` to prevent the spawn. Return `true` to allow it. +- **`OnTrailerUpdate`** — Return `true` to propagate the update. Return `false` to skip it. + +### Multiple Handlers + +When multiple systems register handlers for the same event, **all handlers are always called**. For bool-returning events: + +- If a handler returns the default value, it's ignored and the next handler is called. +- If a handler returns a non-default value, it becomes the current result. +- The **last non-default return value** is the final result. +- If all handlers return the default value (or there are no handlers), the default is used. + +## Dispatching Custom Events + +For advanced scenarios, you can dispatch custom events using <xref:SampSharp.Entities.IEventDispatcher>. When dispatching, pass entities as <xref:SampSharp.Entities.EntityId> values, not as components. + +The event dispatcher automatically converts entity IDs to the component types expected by event handlers. If an entity doesn't have the required component, the handler is not called. + +### How Event Handlers Resolve Parameters + +When an event handler is invoked, SampSharp determines how to resolve each parameter based on its type: + +**Event Arguments** (passed from event dispatcher): +- Value types (int, bool, float, etc.) +- Arrays +- Strings +- Components (e.g., `Player`, custom components) +- Classes marked with the `[EventParameter]` attribute + +**Services** (resolved via dependency injection): +- Everything else is treated as a service and resolved from the DI container. + +This allows handlers to combine event data with injected services flexibly. In the example above, the `OnPlayerBan` handler received a component (`Player`), custom event parameter (`PlayerBanRequest`), and an injected service (`ILogger`)—all resolved automatically. + +```csharp +using SampSharp.Entities; +using SampSharp.Entities.SAMP; + +// Define custom event data types with [EventParameter] +[EventParameter] +public class PlayerBanRequest +{ + public string Reason { get; set; } + public DateTime BanTime { get; set; } +} + +public class BanSystem : ISystem +{ + private readonly IEventDispatcher _dispatcher; + + public BanSystem(IEventDispatcher dispatcher) + { + _dispatcher = dispatcher; + } + + public void BanPlayer(EntityId playerEntity, string reason) + { + var banRequest = new PlayerBanRequest + { + Reason = reason, + BanTime = DateTime.UtcNow + }; + // Dispatch custom event with entity and custom data + _dispatcher.Invoke("OnPlayerBan", playerEntity, banRequest); + } +} + +// Handler in another system: +public class LoggingSystem : ISystem +{ + [Event(Name = "OnPlayerBan")] + public void OnPlayerBan( + Player player, // Component from entity + PlayerBanRequest request, // Custom event parameter + ILogger<LoggingSystem> log) // Injected service + { + log.LogWarning($"Player {player.Name} banned at {request.BanTime}: {request.Reason}"); + } +} +``` + +## Event Middleware + +Middleware allows you to intercept and modify event handling behavior. Middleware works like a pipeline where each middleware component can execute code before and after event handlers run, so you can inspect events, modify their context, or apply logic uniformly across many events. + +You can use middleware to log all events, validate data before handlers run, check permissions, or apply other centralized logic across events. Configure middleware in your `Startup` class using the <xref:SampSharp.Entities.IEcsBuilder>: + +```csharp +using SampSharp.Entities; + +public class MyMiddleware +{ + private readonly EventDelegate _next; + + public MyMiddleware(EventDelegate next) + { + _next = next; + } + + public object? Invoke(EventContext context) + { + // Do something before the event handlers + Console.WriteLine($"Event: {context.EventName}"); + + var result = _next(context); + + // Do something after the event handlers + return result; + } +} + +// In your Startup class: +public class Startup : IEcsStartup +{ + public void Configure(IEcsBuilder builder) + { + builder.UseMiddleware<MyMiddleware>("OnPlayerText"); + } + + // ... other methods +} +``` + + diff --git a/docs/core-concepts/index.md b/docs/core-concepts/index.md new file mode 100644 index 0000000..e11ad6c --- /dev/null +++ b/docs/core-concepts/index.md @@ -0,0 +1,100 @@ +--- +title: Entity-Component-System +uid: core-concepts +--- + +# Core Concepts + +## Entity-Component-System (ECS) + +SampSharp is built on the **Entity-Component-System** (ECS) architecture, a powerful design pattern that separates data from logic and provides a flexible, scalable approach to building game modes. This chapter explains the fundamental concepts you need to understand to work effectively with SampSharp. + +### What is ECS? + +The Entity-Component-System is an architectural pattern that organizes game objects and their behavior through three key concepts: + +1. **Entities** - the objects in your game world +2. **Components** - the data that describes those objects +3. **Systems** - the logic that operates on the data + +Rather than using traditional object-oriented inheritance (where a "Player" class inherits from a "Character" class which inherits from a "GameObject"), ECS uses **composition**: you create a base entity and attach components to it to define what it is and what it can do. + +### Entities + +An **entity** is a unique identifier representing something in your game world. It could be a player, a vehicle, a building, an item, or any other object. + +In SampSharp, entities are extremely lightweight—they're essentially just containers. An entity only has meaning when components are attached to it; an entity without components doesn't exist or serve any purpose in the system. + +**Key characteristics:** +- Each entity has a unique ID +- Entities only exist when they have at least one component +- Multiple entities can exist simultaneously +- Entities can be created and destroyed dynamically + +> For more information on entities, see <xref:entities-components>. + +### Components + +A **component** is a container that holds data and functionality related to a specific aspect of an entity. Components are the "nouns" of your system—they describe what properties and capabilities an entity has. + +Unlike traditional object-oriented design where you might create a deep inheritance hierarchy (Player → Character → GameObject), ECS uses composition: you create an entity and attach whatever components it needs. This makes it easy to create complex entities by combining simpler pieces. + +**Key characteristics:** +- Components hold data and related methods +- An entity can have any combination of components +- You can add or remove components from entities dynamically +- Components can be queried to find entities with specific combinations +- Different components can work together to create complex behaviors + +> For more information about components, see <xref:entities-components>. + +### Systems + +A **system** is the logic layer of ECS. Systems read data from components and perform operations based on that data. A system typically operates on entities that have a specific set of components. + +Systems are responsible for implementing all the game logic—they query for entities with the components they care about, then perform operations on that data. + +**Key characteristics:** +- Systems contain all the business logic for a particular behavior +- Systems query for entities with specific component combinations +- Systems operate on data without owning it +- Systems are independent and can run in any order +- Logic is decoupled from data storage + +> For more information about systems, see <xref:systems>. + +### Events + +In SampSharp, **events** are notifications that occur when something happens in the open.mp server (like a player connecting, a player request class, or game mode initialization). Systems can handle these events by implementing methods decorated with the `[Event]` attribute. + +When an event fires, SampSharp automatically calls your handler method and passes the relevant entity components and services as parameters, allowing your system to react to world changes. + +> For more information about events, see <xref:events>. + +### How It Works Together + +Here's how ECS operates in practice with SampSharp: + +**Example - handling a pickup event:** +1. A player picks up an item in the world +2. open.mp fires a pickup event +3. A system receives the event with the `Player` and `Pickup` components +4. The system updates the player's inventory based on the pickup data +5. The system removes the pickup entity + +**Example - handling a vehicle event:** +1. A player exits a vehicle +2. open.mp fires a vehicle exit event +3. A system receives the event with the `Player` and `Vehicle` components +4. The system calculates a fare based on distance traveled and gives money to the player +5. The system logs the ride for statistics + +### Benefits of ECS + +The ECS pattern offers several advantages for SampSharp game mode development: + +- **Flexibility** - SampSharp's domain-specific components map directly to SA-MP/open.mp concepts, making development intuitive +- **Decoupling** - Game logic (systems) is separate from data (components), making code easier to test and modify +- **Maintainability** - Each component handles a distinct aspect of a game entity, keeping concerns separated +- **Composability** - Complex entities are built by combining simpler components +- **Extensibility** - Add new systems or custom components without modifying existing code diff --git a/docs/core-concepts/systems.md b/docs/core-concepts/systems.md new file mode 100644 index 0000000..aa881be --- /dev/null +++ b/docs/core-concepts/systems.md @@ -0,0 +1,105 @@ +--- +title: Systems +uid: systems +--- + +# Systems + +In SampSharp's Entity-Component-System (ECS) architecture, **systems** are classes that contain the logic for your game mode. Systems process entities and their components, respond to events, and can handle player or console commands. They are the main way to organize your server's behavior, keeping your code modular and maintainable. + +For a high-level overview of ECS and systems, see <xref:core-concepts>. + + +## How to Create a System + +A system is any class that implements the <xref:SampSharp.Entities.ISystem> interface. Systems are singletons—they are instantiated once and shared for the lifetime of the server. Within a system, you can: + +- **Handle events:** Respond to built-in or custom events (player connect/disconnect, etc.) using the `[Event]` attribute. See <xref:events> for more details. +- **Define commands:** Implement player and console commands using the `[PlayerCommand]` and `[ConsoleCommand]` attributes. See <xref:commands> for more information. +- **Use timers:** Run recurring tasks with the `[Timer]` attribute. See <xref:timers> for more details. +- **Handle server ticks:** Implement <xref:SampSharp.Entities.ITickingSystem> to run logic every server tick. +- **Use dependency injection:** Access services like <xref:SampSharp.Entities.IEntityManager>, <xref:SampSharp.Entities.SAMP.IWorldService>, or logging through constructor or method parameters. + +> [!WARNING] +> Server ticks via <xref:SampSharp.Entities.ITickingSystem> run every frame and execute very frequently. Do not perform heavy operations or large computations in tick handlers, as this will significantly impact server performance. Use timers or event-driven approaches for non-performance-critical logic. + +### Dependency Injection + +You can inject dependencies in two ways: + +- **Constructor injection:** For singleton or stateless dependencies. +- **Method parameter injection:** For transient or per-request dependencies (better for event/command handlers). + +### Example: A Simple System + +```csharp +using SampSharp.Entities; +using SampSharp.Entities.SAMP; +using SampSharp.Entities.SAMP.Commands; + +public class MyFirstSystem : ISystem +{ + [Timer(1000)] + public void OnTimer() + { + // This method runs every second. + } + + [Event] + public void OnGameModeInit(IWorldService world, IEntityManager entityManager) + { + // Called when the game mode starts. + var vehicle = world.CreateVehicle(VehicleModelType.Landstalker, new Vector3(0, 6, 15), 45, 4, 4); + vehicle.SetNumberPlate("SampSharp"); + } + + [PlayerCommand(Name = "kill")] + public void KillPlayer(Player player) + { + player.Health = 0; + player.SendClientMessage("You have been killed!"); + } +} +``` + +## Registering Systems + +By default, systems in the entry assembly (the assembly with the <xref:SampSharp.Entities.IEcsStartup> implementation) are automatically discovered and loaded—no configuration needed. + +If you need custom control over which systems load, you can disable automatic loading and manually register systems using `AddSystem<T>()`. This is useful when: + +- You want to be selective about which systems load. +- You're loading systems from other assemblies. +- You need fine-grained control over system initialization. + +To disable automatic loading, call `DisableDefaultSystemsLoading()` in your `Startup` class and register systems individually: + +```csharp +using Microsoft.Extensions.DependencyInjection; +using SampSharp.Entities; + +public class Startup : IEcsStartup +{ + public void Initialize(IStartupContext context) + { + context.UseEntities() + .DisableDefaultSystemsLoading(); + } + + public void ConfigureServices(IServiceCollection services) + { + services.AddSystem<MyFirstSystem>(); + } + + public void Configure(IEcsBuilder builder) + { + } +} +``` + +## Best Practices for System Organization + +- Keep systems focused: each system should handle a specific area of game logic. +- Avoid storing per-entity state in systems; use components for entity data. +- Use dependency injection to keep systems decoupled from infrastructure. +- Group related event and command handlers together for clarity. diff --git a/docs/core-concepts/toc.yml b/docs/core-concepts/toc.yml new file mode 100644 index 0000000..504ac70 --- /dev/null +++ b/docs/core-concepts/toc.yml @@ -0,0 +1,5 @@ +items: +- href: index.md +- href: entities-components.md +- href: systems.md +- href: events.md diff --git a/docs/features/commands.md b/docs/features/commands.md new file mode 100644 index 0000000..e7ac522 --- /dev/null +++ b/docs/features/commands.md @@ -0,0 +1,22 @@ +--- +title: Implementing Commands +uid: commands +--- + +# Implementing Commands + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Document command system including: +- Command attribute basics +- Defining command parameters +- Command parsing and validation +- Handling command responses +- Permission-based commands +- Subcommands and command groups +- Error handling in commands +- Examples of common command patterns +- Console commands and player commands +--> diff --git a/docs/features/dialog-menus.md b/docs/features/dialog-menus.md new file mode 100644 index 0000000..6454d1c --- /dev/null +++ b/docs/features/dialog-menus.md @@ -0,0 +1,18 @@ +--- +title: Dialogs and Menus +uid: dialogs-menus +--- + +# Dialogs and Menus + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Explain UI elements including: +- Dialog types (input, list, password, etc.) +- Displaying dialogs to players +- Handling dialog responses +- Creating menu systems +- Examples and patterns +--> diff --git a/docs/features/players.md b/docs/features/players.md new file mode 100644 index 0000000..c88ce5b --- /dev/null +++ b/docs/features/players.md @@ -0,0 +1,19 @@ +--- +title: Working with Players +uid: players +--- + +# Working with Players + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Explain player management including: +- Accessing player entities +- Player properties and data +- Player state management +- Teleporting players +- Player animations and appearance +- Weapons and inventory +--> diff --git a/docs/features/timers.md b/docs/features/timers.md new file mode 100644 index 0000000..9c3b303 --- /dev/null +++ b/docs/features/timers.md @@ -0,0 +1,21 @@ +--- +title: Timers and Scheduling +uid: timers +--- + +# Timers and Scheduling + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Document timer functionality including: +- The TimerService for scheduling tasks +- One-time vs repeating timers +- Timer callbacks and handlers +- Canceling and managing timers +- Delay and interval configuration +- Timer lifecycle management +- Performance considerations for many timers +- Examples of common timer patterns +--> diff --git a/docs/features/toc.yml b/docs/features/toc.yml new file mode 100644 index 0000000..2cb394d --- /dev/null +++ b/docs/features/toc.yml @@ -0,0 +1,6 @@ +items: +- href: commands.md +- href: dialog-menus.md +- href: players.md +- href: timers.md +- href: vehicles.md diff --git a/docs/features/vehicles.md b/docs/features/vehicles.md new file mode 100644 index 0000000..82da5b9 --- /dev/null +++ b/docs/features/vehicles.md @@ -0,0 +1,18 @@ +--- +title: Vehicle Management +uid: vehicles +--- + +# Vehicle Management + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Document vehicle handling including: +- Creating and spawning vehicles +- Vehicle properties and configuration +- Vehicle respawning +- Removing and destroying vehicles +- Vehicle events (entering, exiting, etc.) +--> diff --git a/docs/getting-started.md b/docs/getting-started.md index 717dc6f..9d4e0d5 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,98 +1,108 @@ --- title: Getting Started +uid: getting-started --- -## Introduction -This guide will help you to to get your first SA-MP server up and running with your own SampSharp game mode. In this guide we will asume you are using Windows and will be using Visual Studio to develop your game mode. +# Getting Started with SampSharp for open.mp + +Welcome to SampSharp! This guide will help you create and run your first gamemode using SampSharp v1.x for open.mp. ## Prerequisites -Before we get started, you'll need to install the following things: -- [Visual Studio](https://visualstudio.microsoft.com/downloads/) (2022 or newer, the community edition is free for everyone) -- [SA-MP Windows Server](https://sa-mp.mp/downloads/) (extract it anywhere you like) - -## Installing the SampSharp plugin -Using the following instructions you can install the SampSharp plugin and configure it for running your first game mode. - -- Download the latest `SampSharp-{version}.zip` from the [SampSharp releases page on GitHub](https://github.com/ikkentim/SampSharp/releases/latest) page and extract its contents to your SA-MP server directory -- Download the latest <u>x86 binaries release</u> of the .NET Runtime from the [.NET 6.0 download page](https://dotnet.microsoft.com/en-us/download/dotnet) and extract its contents to a new folder named `runtime` in your SA-MP server directory. -![x86 of .NET Runtime](images/download-dotnet-windows.png) -- Open the `server.cfg` file in your SA-MP server directory with your favorite text editor and update the following values: - - Add the line `plugins SampSharp` - - Change the line starting with `gamemode0` to `gamemode0 empty 1` - - Remove the line starting with `filterscripts` - - Change the value after `rcon_password` to a secure password - After making these changes, the configuration should look like like this: -``` -echo Executing Server Config... -lanmode 0 -rcon_password SuperSecretPassword -maxplayers 50 -port 7777 -hostname SA-MP 0.3 Server -gamemode0 empty 1 -announce 0 -chatlogging 0 -weburl www.sa-mp.com -onfoot_rate 40 -incar_rate 40 -weapon_rate 40 -stream_distance 300.0 -stream_rate 1000 -maxnpc 0 -logtimeformat [%H:%M:%S] -language English -plugins SampSharp +Before you begin, you'll need: + +- [.NET 10 SDK](https://dotnet.microsoft.com/download/dotnet) or later +- open.mp server with SampSharp component (see [Setting Up open.mp Server](#setting-up-openmp-server)) +- A basic understanding of C# and object-oriented programming + +### Choose Your IDE + +# [Visual Studio](#tab/visualstudio) + +Install [Visual Studio](https://visualstudio.microsoft.com/) with the `.NET desktop development` workload: +1. Download and run the Visual Studio installer +2. Select the `.NET desktop development` workload during installation +3. Complete the installation + +> [!NOTE] +> The `.NET desktop development` workload includes the .NET 10 SDK, so you don't need to install it separately. + +# [Visual Studio Code](#tab/vscode) + +Install [Visual Studio Code](https://code.visualstudio.com/) and the required extensions: +- [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) +- [C# DevKit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) + +--- + +## Setting Up open.mp Server + +SampSharp requires a **64-bit version** of open.mp because the .NET runtime runs as x64. + +1. Download the x64 build from the [SampSharp open.mp x64 releases page](https://github.com/SampSharp/openmultiplayer-x64-builds/releases) and extract it anywhere on your system (e.g., `C:\open.mp` or `~/open.mp`). + +2. Download the SampSharp component from the [SampSharp releases page](https://github.com/ikkentim/SampSharp/releases) and extract it into the `components` directory of your open.mp server installation. + +## Creating Your First Project + +Install the SampSharp template: +```bash +dotnet new install SampSharp.Templates ``` -## Creating a game mode project -It is now time to create your first game mode project. To make things easier, we've created a template for getting started with your first game mode. You can download the [SampSharp Templates for Visual Studio](https://marketplace.visualstudio.com/items?itemName=ikkentim.sampsharptempltes) from the Visual Studio marketplace webpage or using the extension manager in Visual Studio. +Create a new project: +```bash +dotnet new sampsharp -n MyFirstGameMode +cd MyFirstGameMode +``` -- Open Visual Studio and create a new project -- In the 'Create a new project' dialog, search for the 'SampSharp Game Mode' project template and click on Next -- Enter a project name, such as 'MyFirstGameMode' and click on Create -![Find SampSharp in the 'Create a new project' dialog](images/devenv-new-project.png) +The template automatically creates: +- A configured `Startup.cs` class with the ECS framework initialized +- A sample `MyFirstSystem.cs` system with example events and commands +- A `.csproj` file with the necessary SampSharp NuGet package references -You have now successfully created your game mode! In order to start your game mode with your server, you need to change some properties in your project. -- Right click your projects in the 'Solution Explorer' and select 'Properties'. -- Under 'Build' -> 'Output', change the 'Base output path' value using the 'Browse'-button to a new folder named `gamemode` in your SA-MP server directory -- Under 'Debug' -> 'General' click on 'Open debug launch profiles UI' - - Create a new 'Executable' profile - - Set 'Executable' to the 'samp-server.exe' in your SA-MP server directory - - Set the 'Working directory' to your SA-MP server directory - - (optional) Remove the default 'project' launch profile - - (optional) Rename your new profile +**Startup.cs** implements `IEcsStartup` to configure the ECS framework, logging, and middleware. +**MyFirstSystem.cs** is an example system showing how to handle events, commands, and access services. For more details on systems, see the <xref:systems> page. -![Creating a launch profile](images/devenv-launch-profiles.png) +## Running Your Gamemode -By clicking the 'Start Debugging' button in Visual Studio, you will now start your game mode in your SA-MP server +### Configure Your IDE -![Start Debugging your project](images/devenv-start-debugging.png) +# [Visual Studio](#tab/visualstudio) -## Choose your framework -SampSharp provides two frameworks for creating your gamemodes, SampSharp.GameMode and SampSharp.Entities. You can choose to build your game mode on top of one of the frameworks. Using the instructions above, you have created a SampSharp.GameMode game mode. +1. Open the project in Visual Studio. +2. Press `F5` or go to **Debug** > **Start Debugging** to launch the project with the debugger attached. -Both frameworks are fully featured and provide tools, types and functions for using all functionality provided by SA-MP. They also provide tools allowing you to easily create player commands. +# [Visual Studio Code](#tab/vscode) -### SampSharp.GameMode -SampSharp.GameMode is the first framework created for SampSharp and has been availble since the early days of SampSharp. +Create a `.vscode/launch.json` file in your project root: +```json +{ + "version": "0.2.0", + "configurations": [ + { + "name": "SampSharp Gamemode", + "type": "dotnet", + "request": "launch", + "projectPath": "${workspaceFolder}/MyFirstGameMode.csproj" + } + ] +} +``` +Update the `projectPath` to match your project's `.csproj` file location. -**Benefits** -- Easy to understand, simple enough for people who are new to C# -- A simple object-oriented types for all SA-MP types such as players, vehicles, objects, etc. +--- -You can create a SampSharp.GameMode game mode using the 'SampSharp Game Mode' project template. +### Launch Steps -### SampSharp.Entities -The SampSharp.Entities framework has been created to solve a number of issues which could make life more difficult with SampSharp.GameMode. +1. **First Launch**: Start the debugger with your launch configuration. The application will prompt you to enter the path to your open.mp server directory. +2. **Enter Path**: Provide the full path to your open.mp installation (e.g., `C:\open.mp` or `/home/user/open.mp`). +3. **Configuration Generated**: A `launchSettings.json` file will be generated with your open.mp path, and the application will close. +4. **Second Launch**: Start the debugger again. The gamemode will now launch directly with your open.mp server, fully configured and ready to debug. -**Benefits** -- Entity-Component-System structure for building your gamemodes: - - Easily associate data with entities (players/vehicles/etc.) without having to create and keep track of association dictionaries - - Easily extend existing entities with custom data using components - - A simple and clear-cut way of organizing your code by responsibility using systems -- Components for all SA-MP types such as players, vehicles, objects, etc. -- Dependency injection +## Next Steps -You can create a SampSharp.Entities game mode using the 'SampSharp ECS Game Mode' project template. \ No newline at end of file +- **Explore the Documentation**: Learn about <xref:core-concepts>, <xref:commands>, and <xref:vehicles> +- **Check Out Examples**: Visit the [SampSharp samples repository](https://github.com/sampsharp/samples) for complete example gamemodes +- **Join the Community**: Have questions? Join us on [Discord](https://discord.gg/gwcHpqp) where you can get help and discuss development with other SampSharp developers diff --git a/docs/index.md b/docs/index.md index 82cf272..b80fbcc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,127 +1,3 @@ --- -layout: home - -hero: - name: ".NET SA-MP" - text: "Raise your SA-MP game modes to a whole new level with the power of .NET" - image: - src: /sampsharp.png - alt: SampSharp logo - actions: - - theme: brand - text: Get Started - link: /getting-started - - theme: alt - text: View Documentation - link: /introduction ---- - -```csharp -class GameMode : BaseMode -{ - protected override void OnPlayerConnected(BasePlayer player, EventArgs e) - { - base.OnPlayerConnected(player, e); - - player.SendClientMessage($"Welcome {player.Name}, to a SampSharp powered server!"); - } -} -``` - -<div class="features-grid"> - -<div class="feature"> -<div class="feature-icon">📝</div> - -### Modern Language - -SampSharp allow you to write you game mode in C#: an Object-Oriented language. - -</div> - -<div class="feature"> -<div class="feature-icon">⚡</div> - -### High Performance - -Make good use of the high performance .NET Core has to offer. - -</div> - -<div class="feature"> -<div class="feature-icon">📦</div> - -### Thousands of Packages - -Unleash the power of thousands of available NuGet Packages. - -</div> - -<div class="feature"> -<div class="feature-icon">🖥️</div> - -### Any platform - -SampSharp can run on both Windows and Linux. - -</div> - -<div class="feature"> -<div class="feature-icon">🐳</div> - -### Containerized - -SampSharp can easily run in a Docker container. - -</div> - -<div class="feature"> -<div class="feature-icon">🔒</div> - -### Thread-Safe - -SampSharp is 100% thread-safe! - -</div> - -</div> - -<style scoped> -.features-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 2rem; - margin: 2rem 0; -} - -.feature { - padding: 1.5rem; - border-radius: 8px; - background: var(--vp-c-bg-soft); - transition: all 0.3s; -} - -.feature:hover { - background: var(--vp-code-block-bg); - transform: translateY(-2px); -} - -.feature-icon { - font-size: 2rem; -} - -.feature h3 { - margin: 0.5rem 0; -} - -.feature p { - margin: 0; - color: var(--vp-c-text-2); -} - -@media (max-width: 768px) { - .features-grid { - grid-template-columns: 1fr; - } -} -</style> +redirect_url: getting-started.html +--- \ No newline at end of file diff --git a/docs/legacy/configure-legacy-sampsharp.md b/docs/legacy/configure-legacy-sampsharp.md new file mode 100644 index 0000000..5c290bd --- /dev/null +++ b/docs/legacy/configure-legacy-sampsharp.md @@ -0,0 +1,99 @@ +--- +title: Configuring and Debugging Legacy SampSharp +uid: legacy-configure-legacy-sampsharp +--- + +# Configuring and Debugging Legacy SampSharp + +## Overview +This guide explains how to configure and debug legacy SampSharp (v0.x) for SA-MP servers. It covers setting up the plugin, .NET runtime, and Visual Studio for starting and debugging your game mode. These instructions are for legacy SampSharp only. + +## Prerequisites +You will need: +- [Visual Studio](https://visualstudio.microsoft.com/downloads/) (2022 or newer, Community edition is free) +- [SA-MP Windows Server](https://sa-mp.mp/downloads/) (extract anywhere) + +## Installing SampSharp Plugin and .NET Runtime +1. Download the latest `SampSharp-{version}.zip` from the [SampSharp releases page](https://github.com/ikkentim/SampSharp/releases/latest) and extract to your SA-MP server directory. +2. Download the latest **x86 binaries release** of the .NET Runtime from the [.NET 6.0 download page](https://dotnet.microsoft.com/en-us/download/dotnet) and extract to a new folder named `runtime` in your SA-MP server directory. + ![x86 of .NET Runtime](images/download-dotnet-windows.png) +3. Open `server.cfg` in your SA-MP server directory and update: + - Add: `plugins SampSharp` + - Set: `gamemode0 empty 1` + - Remove: any `filterscripts` line + - Set a secure `rcon_password` + Example configuration: + +- Download the latest `SampSharp-{version}.zip` from the [SampSharp releases page on GitHub](https://github.com/ikkentim/SampSharp/releases/latest) page and extract its contents to your SA-MP server directory +- Download the latest <u>x86 binaries release</u> of the .NET Runtime from the [.NET 6.0 download page](https://dotnet.microsoft.com/en-us/download/dotnet) and extract its contents to a new folder named `runtime` in your SA-MP server directory. +![x86 of .NET Runtime](images/download-dotnet-windows.png) +- Open the `server.cfg` file in your SA-MP server directory with your favorite text editor and update the following values: + - Add the line `plugins SampSharp` + - Change the line starting with `gamemode0` to `gamemode0 empty 1` + - Remove the line starting with `filterscripts` + - Change the value after `rcon_password` to a secure password + After making these changes, the configuration should look like like this: + +``` +echo Executing Server Config... +lanmode 0 +rcon_password SuperSecretPassword +maxplayers 50 +port 7777 +hostname SA-MP 0.3 Server +gamemode0 empty 1 +announce 0 +chatlogging 0 +weburl www.sa-mp.com +onfoot_rate 40 +incar_rate 40 +weapon_rate 40 +stream_distance 300.0 +stream_rate 1000 +maxnpc 0 +logtimeformat [%H:%M:%S] +language English +plugins SampSharp +``` + +## Setting Up Visual Studio for Debugging +You can use Visual Studio to build and debug your legacy SampSharp game mode: + +1. Open Visual Studio and create a new project (using your preferred SampSharp template or existing project). +2. In Solution Explorer, right-click your project and select **Properties**. +3. Under **Build → Output**, set the **Base output path** to a new folder named `gamemode` inside your SA-MP server directory. +4. Under **Debug → General**, open the **Debug launch profiles UI**: + - Create a new **Executable** profile + - Set **Executable** to `samp-server.exe` in your SA-MP server directory + - Set **Working directory** to your SA-MP server directory + - (Optional) Remove the default project launch profile + - (Optional) Rename your new profile + + ![Creating a launch profile](images/devenv-launch-profiles.png) + +5. Click **Start Debugging** in Visual Studio to launch your SA-MP server with your SampSharp game mode attached. + + ![Start Debugging your project](images/devenv-start-debugging.png) + +- Open Visual Studio and create a new project +- In the 'Create a new project' dialog, search for the 'SampSharp Game Mode' project template and click on Next +- Enter a project name, such as 'MyFirstGameMode' and click on Create +![Find SampSharp in the 'Create a new project' dialog](images/devenv-new-project.png) + +You have now successfully created your game mode! In order to start your game mode with your server, you need to change some properties in your project. +- Right click your projects in the 'Solution Explorer' and select 'Properties'. +- Under 'Build' -> 'Output', change the 'Base output path' value using the 'Browse'-button to a new folder named `gamemode` in your SA-MP server directory +- Under 'Debug' -> 'General' click on 'Open debug launch profiles UI' + - Create a new 'Executable' profile + - Set 'Executable' to the 'samp-server.exe' in your SA-MP server directory + - Set the 'Working directory' to your SA-MP server directory + - (optional) Remove the default 'project' launch profile + - (optional) Rename your new profile + + +![Creating a launch profile](images/devenv-launch-profiles.png) + +By clicking the 'Start Debugging' button in Visual Studio, you will now start your game mode in your SA-MP server + +![Start Debugging your project](images/devenv-start-debugging.png) + diff --git a/docs/game-mode-builder.md b/docs/legacy/game-mode-builder.md similarity index 98% rename from docs/game-mode-builder.md rename to docs/legacy/game-mode-builder.md index 192172d..1c8fa46 100644 --- a/docs/game-mode-builder.md +++ b/docs/legacy/game-mode-builder.md @@ -1,8 +1,9 @@ --- title: GameModeBuilder +uid: legacy-game-mode-builder --- -## Introduction +# GameModeBuilder The `GameModeBuilder` can be used to configure how your game mode is launched. Generally, you'll be using the `GameModeBuilder` from the entry-point of your assembly. diff --git a/docs/gamemode-accessing-server.cfg.md b/docs/legacy/gamemode-accessing-server.cfg.md similarity index 92% rename from docs/gamemode-accessing-server.cfg.md rename to docs/legacy/gamemode-accessing-server.cfg.md index 7b04f1b..5cc283e 100644 --- a/docs/gamemode-accessing-server.cfg.md +++ b/docs/legacy/gamemode-accessing-server.cfg.md @@ -1,9 +1,10 @@ --- title: Accessing the server.cfg configuration file +uid: legacy-gamemode-accessing-server-cfg --- -Introduction ------------- +# Accessing the server.cfg configuration file + SampSharp provides some functions to access the server.cfg file and read its values. Reading diff --git a/docs/gamemode-callbacks.md b/docs/legacy/gamemode-callbacks.md similarity index 97% rename from docs/gamemode-callbacks.md rename to docs/legacy/gamemode-callbacks.md index 1f10a8c..3d3840a 100644 --- a/docs/gamemode-callbacks.md +++ b/docs/legacy/gamemode-callbacks.md @@ -1,9 +1,10 @@ --- title: Callbacks +uid: legacy-gamemode-callbacks --- -Introduction ------------- +# Callbacks + SampSharp provides an easy-to-use system for catching callbacks. When a callback is called, SampSharp automatically checks for a method with the same name within the game mode and every loaded extension. **Notice!** Callbacks provided by SA-MP are all handled by the framework by default. This documentation can be used for handling custom callbacks and callbacks provided by various plugins. diff --git a/docs/gamemode-controllers.md b/docs/legacy/gamemode-controllers.md similarity index 98% rename from docs/gamemode-controllers.md rename to docs/legacy/gamemode-controllers.md index 8acd4ed..b4c1131 100644 --- a/docs/gamemode-controllers.md +++ b/docs/legacy/gamemode-controllers.md @@ -1,9 +1,10 @@ --- title: Controllers +uid: legacy-gamemode-controllers --- -Introduction ------------- +# Controllers + Controllers distribute events between instances and manage the living instances. For example, if the `BaseMode.PlayerEnteredVehicle` event is called, the `BasePlayerController` will trigger the `BasePlayer.EnteredVehicle` event. If a player disconnected, the `BasePlayerController` will destroy the instance of the disconnected player. Creating Controllers diff --git a/docs/gamemode-dialogs.md b/docs/legacy/gamemode-dialogs.md similarity index 99% rename from docs/gamemode-dialogs.md rename to docs/legacy/gamemode-dialogs.md index 0a61ca5..4062601 100644 --- a/docs/gamemode-dialogs.md +++ b/docs/legacy/gamemode-dialogs.md @@ -1,9 +1,10 @@ --- title: Dialogs +uid: legacy-gamemode-dialogs --- -Introduction ------------- +# Dialogs + SampSharp supports all of the dialog styles from SA:MP, implemented in an object-oriented manner. The available dialog classes are: diff --git a/docs/gamemode-extensions.md b/docs/legacy/gamemode-extensions.md similarity index 98% rename from docs/gamemode-extensions.md rename to docs/legacy/gamemode-extensions.md index 7482cae..82ffdd7 100644 --- a/docs/gamemode-extensions.md +++ b/docs/legacy/gamemode-extensions.md @@ -1,8 +1,9 @@ --- title: Extensions +uid: legacy-gamemode-extensions --- -## Introduction +# Extensions Extensions are .NET Assemblies (separate from game modes) which provide additional functionality to the framework, for example, by wrapping around the natives and callbacks of a plugin. diff --git a/docs/gamemode-game-mode.md b/docs/legacy/gamemode-game-mode.md similarity index 96% rename from docs/gamemode-game-mode.md rename to docs/legacy/gamemode-game-mode.md index f758969..f0fee50 100644 --- a/docs/gamemode-game-mode.md +++ b/docs/legacy/gamemode-game-mode.md @@ -1,9 +1,10 @@ --- title: GameMode +uid: legacy-gamemode-game-mode --- -Introduction ------------- +# GameMode + Your game mode class is your main SampSharp class. Every SA-MP callback is turned into a C# event by SampSharp and can be found within your game mode class. Functions which are normally run from within your `OnGameModeInit` diff --git a/docs/gamemode-player-commands.md b/docs/legacy/gamemode-player-commands.md similarity index 99% rename from docs/gamemode-player-commands.md rename to docs/legacy/gamemode-player-commands.md index 1dc0f24..ac8a9c5 100644 --- a/docs/gamemode-player-commands.md +++ b/docs/legacy/gamemode-player-commands.md @@ -1,9 +1,10 @@ --- title: Player Commands +uid: legacy-gamemode-player-commands --- -Introduction ------------- +# Player Commands + SampSharp provides an easy-to-use commands system. A command can be created by registering a class to the `CommandManager` service or by decorating a method with the `Command` attribute. Decorating Methods diff --git a/docs/gamemode-players.md b/docs/legacy/gamemode-players.md similarity index 98% rename from docs/gamemode-players.md rename to docs/legacy/gamemode-players.md index 28dd979..e16f1b7 100644 --- a/docs/gamemode-players.md +++ b/docs/legacy/gamemode-players.md @@ -1,9 +1,10 @@ --- title: Players +uid: legacy-gamemode-players --- -Introduction ------------- +# Players + The `BasePlayer` class represents a SA-MP player. This class contains the methods, properties and events related to players. diff --git a/docs/gamemode-textdraws.md b/docs/legacy/gamemode-textdraws.md similarity index 99% rename from docs/gamemode-textdraws.md rename to docs/legacy/gamemode-textdraws.md index a87b4e5..f7ed039 100644 --- a/docs/gamemode-textdraws.md +++ b/docs/legacy/gamemode-textdraws.md @@ -1,9 +1,10 @@ --- title: TextDraws +uid: legacy-gamemode-textdraws --- -Introduction ------------- +# TextDraws + SampSharp supports both SA:MP textdraws type: global textdraws and player textdraws. | SampSharp class | Description | diff --git a/docs/images/TXD_up.png b/docs/legacy/images/TXD_up.png similarity index 100% rename from docs/images/TXD_up.png rename to docs/legacy/images/TXD_up.png diff --git a/docs/images/Textdraw_font_styles.png b/docs/legacy/images/Textdraw_font_styles.png similarity index 100% rename from docs/images/Textdraw_font_styles.png rename to docs/legacy/images/Textdraw_font_styles.png diff --git a/docs/images/devenv-launch-profiles.png b/docs/legacy/images/devenv-launch-profiles.png similarity index 100% rename from docs/images/devenv-launch-profiles.png rename to docs/legacy/images/devenv-launch-profiles.png diff --git a/docs/images/devenv-new-project.png b/docs/legacy/images/devenv-new-project.png similarity index 100% rename from docs/images/devenv-new-project.png rename to docs/legacy/images/devenv-new-project.png diff --git a/docs/images/devenv-start-debugging.png b/docs/legacy/images/devenv-start-debugging.png similarity index 100% rename from docs/images/devenv-start-debugging.png rename to docs/legacy/images/devenv-start-debugging.png diff --git a/docs/images/download-dotnet-windows.png b/docs/legacy/images/download-dotnet-windows.png similarity index 100% rename from docs/images/download-dotnet-windows.png rename to docs/legacy/images/download-dotnet-windows.png diff --git a/docs/introduction.md b/docs/legacy/index.md similarity index 74% rename from docs/introduction.md rename to docs/legacy/index.md index 5fc8a12..06129fb 100644 --- a/docs/introduction.md +++ b/docs/legacy/index.md @@ -1,15 +1,27 @@ --- -title: Introduction +title: SampSharp Legacy (v0.x) +uid: legacy-docs --- -SampSharp is a framework for writing game modes for SA-MP using C# and the .NET runtime. This means you can make use of everything [.NET](https://dot.net) has to offer, including [thousands of NuGet packages](https://nuget.org). +# SampSharp Legacy (v0.x) -SampSharp consists of a few parts: -- A plugin which hosts the .NET Runtime and provides the an API interface which SampSharp's .NET libraries consumes -- SampSharp.Core: A .NET library which provides a clean .NET API for using SA-MP native functions and hooking into SA-MP callbacks -- Two variants of frameworks for writing a game mode with .NET: SampSharp.GameMode and SampSharp.Entities +> [!IMPORTANT] +> These are the legacy documentation pages for SampSharp **v0.x** (for SA-MP servers). This version is no longer actively developed and only receives critical bug fixes and security patches. +> +> **We strongly recommend using the new SampSharp for open.mp (v1.x) for all new projects.** +> +> The new version offers modern .NET support, active development, and many improvements. If you are starting a new project or planning to migrate, please refer to the <xref:getting-started> and <xref:migration-guide> for SampSharp v1.x. +> +> If you are maintaining an existing SA-MP server, you may continue using these legacy docs. + +--- -See [Getting Started](getting-started) for information about how to start developing your first SampSharp game mode. +SampSharp v0.x is a framework for writing game modes for SA-MP using C# and the .NET runtime. This means you can make use of everything [.NET](https://dot.net) has to offer, including [thousands of NuGet packages](https://nuget.org). + +SampSharp v0.x consists of a few parts: +- A plugin which hosts the .NET Runtime and provides an API interface which SampSharp's .NET libraries consume +- SampSharp.Core: A .NET library which provides a clean .NET API for using SA-MP native functions and hooking into SA-MP callbacks +- Two variants of frameworks for writing a game mode with .NET: SampSharp.GameMode and SampSharp.Entities ## Frameworks SampSharp provides two frameworks for developing game modes. Though you can make any game mode you want with either framework, they differ vastly and how you structure you code and how you will interact with the different entities within SA-MP. diff --git a/docs/natives.md b/docs/legacy/natives.md similarity index 99% rename from docs/natives.md rename to docs/legacy/natives.md index 2c38192..e870981 100644 --- a/docs/natives.md +++ b/docs/legacy/natives.md @@ -1,8 +1,10 @@ --- title: Natives +uid: legacy-natives --- -## Introduction +# Natives + Though SampSharp provides access to nearly all available SA-MP natives through various wrapper types, there are still situations where you might want to call a native which SampSharp does not provide a wrapper for. In these cases you can write your own wrapper for the native function. Writing wrappers is trivial, all you need to do is create a class which contains the signatures of the natives you want to write the wrapper for. If you come across a SA-MP native which is not available in SampSharp, please [raise an issue in the SampSharp repository](https://github.com/ikkentim/SampSharp/issues) so we can take a look at it. Please note we don't provide wrappers for natives which provide functionality which can be performed within .NET, such as string or time operations. diff --git a/docs/production.md b/docs/legacy/production.md similarity index 97% rename from docs/production.md rename to docs/legacy/production.md index 39a51c0..247b129 100644 --- a/docs/production.md +++ b/docs/legacy/production.md @@ -1,8 +1,9 @@ --- title: Running a Server in Production +uid: legacy-production --- -## Introduction +# Running a Server in Production When you want to run your game mode on a samp-server you'll need to publish your dotnet project and download/extract the .NET Runtime and SampSharp plugin into your server directory. diff --git a/docs/threading.md b/docs/legacy/threading.md similarity index 98% rename from docs/threading.md rename to docs/legacy/threading.md index 656981d..e965316 100644 --- a/docs/threading.md +++ b/docs/legacy/threading.md @@ -1,9 +1,10 @@ --- title: Threading +uid: legacy-threading --- -Introduction ----- +# Threading + SampSharp allows you to use [asynchronous programming](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/) using C#s async-await. SA-MP only allows calls to natives on the main thread. SampSharp will make sure that all calls are sent on the main thread. If a call to a SA-MP native is made on a different thread, SampSharp will wait for the next SA-MP server tick and call the native from that tick. There are a few concepts you need to know about before you start depending heavily on asynchronous programming. Callbacks diff --git a/docs/legacy/toc.yml b/docs/legacy/toc.yml new file mode 100644 index 0000000..132bf78 --- /dev/null +++ b/docs/legacy/toc.yml @@ -0,0 +1,24 @@ +items: +- name: SampSharp Legacy + href: index.md +- href: configure-legacy-sampsharp.md +- name: Basics + items: + - href: production.md + - href: troubleshooting.md + - href: game-mode-builder.md +- name: Advanced + items: + - href: natives.md + - href: threading.md +- name: GameMode Framework + items: + - href: gamemode-game-mode.md + - href: gamemode-players.md + - href: gamemode-dialogs.md + - href: gamemode-textdraws.md + - href: gamemode-player-commands.md + - href: gamemode-accessing-server.cfg.md + - href: gamemode-controllers.md + - href: gamemode-callbacks.md + - href: gamemode-extensions.md diff --git a/docs/troubleshooting.md b/docs/legacy/troubleshooting.md similarity index 94% rename from docs/troubleshooting.md rename to docs/legacy/troubleshooting.md index d48e474..0d60a7f 100644 --- a/docs/troubleshooting.md +++ b/docs/legacy/troubleshooting.md @@ -1,7 +1,10 @@ --- title: Troubleshooting +uid: legacy-troubleshooting --- +# Troubleshooting + Running on Linux ---------------- diff --git a/docs/public/sampsharp.png b/docs/public/sampsharp.png deleted file mode 100644 index 19bc74d..0000000 Binary files a/docs/public/sampsharp.png and /dev/null differ diff --git a/docs/reference/advanced-topics.md b/docs/reference/advanced-topics.md new file mode 100644 index 0000000..052e438 --- /dev/null +++ b/docs/reference/advanced-topics.md @@ -0,0 +1,21 @@ +--- +title: Advanced Topics +uid: advanced-topics +--- + +# Advanced Topics + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Cover advanced development patterns including: +- Custom middleware +- Event pipeline architecture +- Contributing to SampSharp +- Writing wrappers for other components +- Using the SampSharp.OpenMp.Core open.mp API +- Async +- ITickingSystem +--> + diff --git a/docs/reference/examples.md b/docs/reference/examples.md new file mode 100644 index 0000000..946c50a --- /dev/null +++ b/docs/reference/examples.md @@ -0,0 +1,16 @@ +--- +title: Examples and Tutorials +uid: examples +--- + +# Examples and Tutorials + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Provide practical examples including: +- Complete hello world game mode +- Basic deathmatch game mode +- Admin panel implementation +--> diff --git a/docs/reference/toc.yml b/docs/reference/toc.yml new file mode 100644 index 0000000..5620eb4 --- /dev/null +++ b/docs/reference/toc.yml @@ -0,0 +1,3 @@ +items: +- href: advanced-topics.md +- href: examples.md diff --git a/docs/support/migration-guide.md b/docs/support/migration-guide.md new file mode 100644 index 0000000..143cafd --- /dev/null +++ b/docs/support/migration-guide.md @@ -0,0 +1,14 @@ +--- +title: Migrating from SA-MP to open.mp +uid: migration-guide +--- + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: +- SampSharp.GameMode has no easy migration path +- SampSharp.Entities should generally have the same API as the new SampSharp.OpenMp.Entities +- New startup/entry configuration +--> \ No newline at end of file diff --git a/docs/support/toc.yml b/docs/support/toc.yml new file mode 100644 index 0000000..cc95b6e --- /dev/null +++ b/docs/support/toc.yml @@ -0,0 +1,3 @@ +items: +- href: troubleshooting.md +- href: migration-guide.md diff --git a/docs/support/troubleshooting.md b/docs/support/troubleshooting.md new file mode 100644 index 0000000..4169327 --- /dev/null +++ b/docs/support/troubleshooting.md @@ -0,0 +1,19 @@ +--- +title: Troubleshooting and FAQ +uid: troubleshooting +--- + +# Troubleshooting and FAQ + +> [!NOTE] +> This article is coming soon! Check back later, or feel free to open an issue if you have questions. + +<!-- +TODO: Document common issues and solutions including: +- Common error messages and fixes +- Frequently asked questions +- Best practices to avoid common mistakes +- Known limitations +- Getting help and support channels +- Version compatibility issues +--> diff --git a/docs/toc.yml b/docs/toc.yml new file mode 100644 index 0000000..d3d542c --- /dev/null +++ b/docs/toc.yml @@ -0,0 +1,12 @@ +items: +- href: getting-started.md +- href: core-concepts/toc.yml + name: Core Concepts +- name: Features + href: features/toc.yml +- name: Reference + href: reference/toc.yml +- name: Support + href: support/toc.yml +- name: Legacy + href: legacy/toc.yml \ No newline at end of file diff --git a/index.md b/index.md new file mode 100644 index 0000000..0bb0e0f --- /dev/null +++ b/index.md @@ -0,0 +1,156 @@ +--- +title: SampSharp +_disableContribution: true +_disableAffix: true +--- + +<style> + .page-container { + max-width: 900px; + margin: 0 auto; + padding: 0 20px; + } + + .features-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 20px; + margin: 30px 0; + } + + @media (max-width: 640px) { + .features-grid { + grid-template-columns: 1fr; + } + } + + .feature-box { + border-radius: 12px; + padding: 24px; + transition: all 0.3s ease; + border: 1px solid var(--bs-border-color, #e0e0e0); + background-color: var(--bs-body-bg, #ffffff); + color: var(--bs-body-color, #333333); + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + } + + @media (prefers-color-scheme: dark) { + .feature-box { + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); + } + } + + .feature-box:hover { + transform: translateY(-4px); + box-shadow: 0 8px 24px rgba(0, 120, 212, 0.15); + border-color: #0078d4; + background: linear-gradient(135deg, + rgba(0, 120, 212, 0.03) 0%, + rgba(80, 230, 255, 0.03) 100% + ); + } + + @media (prefers-color-scheme: dark) { + .feature-box:hover { + box-shadow: 0 8px 24px rgba(0, 120, 212, 0.25); + } + } + + .feature-box-title { + color: #0078d4; + margin-top: 0; + margin-bottom: 12px; + font-size: 18px; + display: block; + font-weight: 600; + } + + .feature-box p { + margin: 0; + color: inherit; + line-height: 1.5; + font-size: 14px; + opacity: 0.9; + } + + .emoji { + font-size: 24px; + margin-right: 8px; + } +</style> + +<div class="page-container"> + +# Welcome to SampSharp + +Build powerful open.mp game modes with modern C# and a proven Entity-Component-System architecture. + +## What is SampSharp? + +SampSharp is a framework that lets you write open.mp game modes in **C#** instead of Pawn. Powered by the .NET runtime, it brings modern programming practices, strong typing, and access to the entire NuGet ecosystem to SA-MP/open.mp development. + +The new **SampSharp v1.x** (for open.mp) features an **Entity-Component-System (ECS)** architecture that makes your code more modular, testable, and maintainable compared to traditional callback-based approaches. + +## Why Choose SampSharp? + +<div class="features-grid"> + <div class="feature-box"> + <span class="feature-box-title"><span class="emoji">🎯</span> ECS Architecture</span> + <p>Build scalable systems with clear separation of concerns using the Entity-Component-System pattern</p> + </div> + <div class="feature-box"> + <span class="feature-box-title"><span class="emoji">🔷</span> Modern C#</span> + <p>Write type-safe, expressive code with the latest C# language features and LINQ</p> + </div> + <div class="feature-box"> + <span class="feature-box-title"><span class="emoji">⚡</span> High Performance</span> + <p>.NET's performance and JIT compilation deliver efficient game mode execution</p> + </div> + <div class="feature-box"> + <span class="feature-box-title"><span class="emoji">📦</span> NuGet Ecosystem</span> + <p>Use thousands of mature, reliable libraries for logging, JSON, async operations, and more</p> + </div> + <div class="feature-box"> + <span class="feature-box-title"><span class="emoji">🖥️</span> Multi-Platform</span> + <p>Run seamlessly on Windows and Linux servers</p> + </div> + <div class="feature-box"> + <span class="feature-box-title"><span class="emoji"></span> Rich Tooling</span> + <p>Get IntelliSense, debugging, and refactoring support from Visual Studio and VS Code. Deploy easily with Docker for consistent environments</p> + </div> +</div> + +```csharp +class PlayerSystem : ISystem +{ + [Event] + public void OnPlayerConnect(Player player) + { + player.SendClientMessage($"Welcome {player.Name}! You're the {player.Id}th player."); + Console.WriteLine($"{player.Name} connected to the server."); + } + + [Event] + public void OnPlayerDisconnect(Player player) + { + Console.WriteLine($"{player.Name} disconnected from the server."); + } +} +``` + +--- + +## Getting Started + +Ready to build? Check out the resources below: + +- **[Documentation](~/docs/index.md)** — Learn the framework concepts and architecture +- **[Sample Projects](https://github.com/SampSharp/samples)** — Real-world examples to learn from + +--- + +## Community & Support + +Have questions? Join us on [Discord](https://discord.gg/gwcHpqp) or visit the [GitHub repository](https://github.com/ikkentim/SampSharp). + +</div> diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 6d68c0f..0000000 --- a/package-lock.json +++ /dev/null @@ -1,2515 +0,0 @@ -{ - "name": "sampsharp-website-expl", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "sampsharp-website-expl", - "version": "1.0.0", - "license": "ISC", - "devDependencies": { - "vitepress": "1.6.4", - "vue": "3.5.30" - } - }, - "node_modules/@algolia/abtesting": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.15.2.tgz", - "integrity": "sha512-rF7vRVE61E0QORw8e2NNdnttcl3jmFMWS9B4hhdga12COe+lMa26bQLfcBn/Nbp9/AF/8gXdaRCPsVns3CnjsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/autocomplete-core": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.17.7.tgz", - "integrity": "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", - "@algolia/autocomplete-shared": "1.17.7" - } - }, - "node_modules/@algolia/autocomplete-plugin-algolia-insights": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.17.7.tgz", - "integrity": "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.7" - }, - "peerDependencies": { - "search-insights": ">= 1 < 3" - } - }, - "node_modules/@algolia/autocomplete-preset-algolia": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.17.7.tgz", - "integrity": "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/autocomplete-shared": "1.17.7" - }, - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/autocomplete-shared": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.17.7.tgz", - "integrity": "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@algolia/client-search": ">= 4.9.1 < 6", - "algoliasearch": ">= 4.9.1 < 6" - } - }, - "node_modules/@algolia/client-abtesting": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.49.2.tgz", - "integrity": "sha512-XyvKCm0RRmovMI/ChaAVjTwpZhXdbgt3iZofK914HeEHLqD1MUFFVLz7M0+Ou7F56UkHXwRbpHwb9xBDNopprQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-analytics": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.49.2.tgz", - "integrity": "sha512-jq/3qvtmj3NijZlhq7A1B0Cl41GfaBpjJxcwukGsYds6aMSCWrEAJ9pUqw/C9B3hAmILYKl7Ljz3N9SFvekD3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-common": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.49.2.tgz", - "integrity": "sha512-bn0biLequn3epobCfjUqCxlIlurLr4RHu7RaE4trgN+RDcUq6HCVC3/yqq1hwbNYpVtulnTOJzcaxYlSr1fnuw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-insights": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.49.2.tgz", - "integrity": "sha512-z14wfFs1T3eeYbCArC8pvntAWsPo9f6hnUGoj8IoRUJTwgJiiySECkm8bmmV47/x0oGHfsVn3kBdjMX0yq0sNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-personalization": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.49.2.tgz", - "integrity": "sha512-GpRf7yuuAX93+Qt0JGEJZwgtL0MFdjFO9n7dn8s2pA9mTjzl0Sc5+uTk1VPbIAuf7xhCP9Mve+URGb6J+EYxgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-query-suggestions": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.49.2.tgz", - "integrity": "sha512-HZwApmNkp0DiAjZcLYdQLddcG4Agb88OkojiAHGgcm5DVXobT5uSZ9lmyrbw/tmQBJwgu2CNw4zTyXoIB7YbPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/client-search": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.49.2.tgz", - "integrity": "sha512-y1IOpG6OSmTpGg/CT0YBb/EAhR2nsC18QWp9Jy8HO9iGySpcwaTvs5kHa17daP3BMTwWyaX9/1tDTDQshZzXdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/ingestion": { - "version": "1.49.2", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.49.2.tgz", - "integrity": "sha512-YYJRjaZ2bqk923HxE4um7j/Cm3/xoSkF2HC2ZweOF8cXL3sqnlndSUYmCaxHFjNPWLaSHk2IfssX6J/tdKTULw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/monitoring": { - "version": "1.49.2", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.49.2.tgz", - "integrity": "sha512-9WgH+Dha39EQQyGKCHlGYnxW/7W19DIrEbCEbnzwAMpGAv1yTWCHMPXHxYa+LcL3eCp2V/5idD1zHNlIKmHRHg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/recommend": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.49.2.tgz", - "integrity": "sha512-K7Gp5u+JtVYgaVpBxF5rGiM+Ia8SsMdcAJMTDV93rwh00DKNllC19o1g+PwrDjDvyXNrnTEbofzbTs2GLfFyKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-browser-xhr": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.49.2.tgz", - "integrity": "sha512-3UhYCcWX6fbtN8ABcxZlhaQEwXFh3CsFtARyyadQShHMPe3mJV9Wel4FpJTa+seugRkbezFz0tt6aPTZSYTBuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-fetch": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.49.2.tgz", - "integrity": "sha512-G94VKSGbsr+WjsDDOBe5QDQ82QYgxvpxRGJfCHZBnYKYsy/jv9qGIDb93biza+LJWizQBUtDj7bZzp3QZyzhPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@algolia/requester-node-http": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.49.2.tgz", - "integrity": "sha512-UuihBGHafG/ENsrcTGAn5rsOffrCIRuHMOsD85fZGLEY92ate+BMTUqxz60dv5zerh8ZumN4bRm8eW2z9L11jA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/client-common": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@docsearch/css": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz", - "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@docsearch/js": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz", - "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@docsearch/react": "3.8.2", - "preact": "^10.0.0" - } - }, - "node_modules/@docsearch/react": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz", - "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==", - "dev": true, - "license": "MIT", - "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" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "search-insights": { - "optional": true - } - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@iconify-json/simple-icons": { - "version": "1.2.74", - "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.74.tgz", - "integrity": "sha512-yqaohfY6jnYjTVpuTkaBQHrWbdUrQyWXhau0r/0EZiNWYXPX/P8WWwl1DoLH5CbvDjjcWQw5J0zADhgCUklOqA==", - "dev": true, - "license": "CC0-1.0", - "dependencies": { - "@iconify/types": "*" - } - }, - "node_modules/@iconify/types": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@shikijs/core": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz", - "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==", - "dev": true, - "license": "MIT", - "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" - } - }, - "node_modules/@shikijs/engine-javascript": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz", - "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2", - "oniguruma-to-es": "^3.1.0" - } - }, - "node_modules/@shikijs/engine-oniguruma": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz", - "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0", - "@shikijs/vscode-textmate": "^10.0.2" - } - }, - "node_modules/@shikijs/langs": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz", - "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/themes": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz", - "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/transformers": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz", - "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/core": "2.5.0", - "@shikijs/types": "2.5.0" - } - }, - "node_modules/@shikijs/types": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz", - "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@shikijs/vscode-textmate": "^10.0.2", - "@types/hast": "^3.0.4" - } - }, - "node_modules/@shikijs/vscode-textmate": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", - "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/hast": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/markdown-it": { - "version": "14.1.2", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", - "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/linkify-it": "^5", - "@types/mdurl": "^2" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.21", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz", - "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@vitejs/plugin-vue": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", - "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0 || ^6.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.30.tgz", - "integrity": "sha512-s3DfdZkcu/qExZ+td75015ljzHc6vE+30cFMGRPROYjqkroYI5NV2X1yAMX9UeyBNWB9MxCfPcsjpLS11nzkkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@vue/shared": "3.5.30", - "entities": "^7.0.1", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.30.tgz", - "integrity": "sha512-eCFYESUEVYHhiMuK4SQTldO3RYxyMR/UQL4KdGD1Yrkfdx4m/HYuZ9jSfPdA+nWJY34VWndiYdW/wZXyiPEB9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-core": "3.5.30", - "@vue/shared": "3.5.30" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.30.tgz", - "integrity": "sha512-LqmFPDn89dtU9vI3wHJnwaV6GfTRD87AjWpTWpyrdVOObVtjIuSeZr181z5C4PmVx/V3j2p+0f7edFKGRMpQ5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@vue/compiler-core": "3.5.30", - "@vue/compiler-dom": "3.5.30", - "@vue/compiler-ssr": "3.5.30", - "@vue/shared": "3.5.30", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.21", - "postcss": "^8.5.8", - "source-map-js": "^1.2.1" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.30.tgz", - "integrity": "sha512-NsYK6OMTnx109PSL2IAyf62JP6EUdk4Dmj6AkWcJGBvN0dQoMYtVekAmdqgTtWQgEJo+Okstbf/1p7qZr5H+bA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.30", - "@vue/shared": "3.5.30" - } - }, - "node_modules/@vue/devtools-api": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz", - "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^7.7.9" - } - }, - "node_modules/@vue/devtools-kit": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz", - "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==", - "dev": true, - "license": "MIT", - "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" - } - }, - "node_modules/@vue/devtools-shared": { - "version": "7.7.9", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz", - "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "rfdc": "^1.4.1" - } - }, - "node_modules/@vue/reactivity": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.30.tgz", - "integrity": "sha512-179YNgKATuwj9gB+66snskRDOitDiuOZqkYia7mHKJaidOMo/WJxHKF8DuGc4V4XbYTJANlfEKb0yxTQotnx4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.30" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.30.tgz", - "integrity": "sha512-e0Z+8PQsUTdwV8TtEsLzUM7SzC7lQwYKePydb7K2ZnmS6jjND+WJXkmmfh/swYzRyfP1EY3fpdesyYoymCzYfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.30", - "@vue/shared": "3.5.30" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.30.tgz", - "integrity": "sha512-2UIGakjU4WSQ0T4iwDEW0W7vQj6n7AFn7taqZ9Cvm0Q/RA2FFOziLESrDL4GmtI1wV3jXg5nMoJSYO66egDUBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.30", - "@vue/runtime-core": "3.5.30", - "@vue/shared": "3.5.30", - "csstype": "^3.2.3" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.30.tgz", - "integrity": "sha512-v+R34icapydRwbZRD0sXwtHqrQJv38JuMB4JxbOxd8NEpGLny7cncMp53W9UH/zo4j8eDHjQ1dEJXwzFQknjtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-ssr": "3.5.30", - "@vue/shared": "3.5.30" - }, - "peerDependencies": { - "vue": "3.5.30" - } - }, - "node_modules/@vue/shared": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.30.tgz", - "integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@vueuse/core": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-12.8.2.tgz", - "integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/web-bluetooth": "^0.0.21", - "@vueuse/metadata": "12.8.2", - "@vueuse/shared": "12.8.2", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/integrations": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-12.8.2.tgz", - "integrity": "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vueuse/core": "12.8.2", - "@vueuse/shared": "12.8.2", - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "async-validator": "^4", - "axios": "^1", - "change-case": "^5", - "drauu": "^0.4", - "focus-trap": "^7", - "fuse.js": "^7", - "idb-keyval": "^6", - "jwt-decode": "^4", - "nprogress": "^0.2", - "qrcode": "^1.5", - "sortablejs": "^1", - "universal-cookie": "^7" - }, - "peerDependenciesMeta": { - "async-validator": { - "optional": true - }, - "axios": { - "optional": true - }, - "change-case": { - "optional": true - }, - "drauu": { - "optional": true - }, - "focus-trap": { - "optional": true - }, - "fuse.js": { - "optional": true - }, - "idb-keyval": { - "optional": true - }, - "jwt-decode": { - "optional": true - }, - "nprogress": { - "optional": true - }, - "qrcode": { - "optional": true - }, - "sortablejs": { - "optional": true - }, - "universal-cookie": { - "optional": true - } - } - }, - "node_modules/@vueuse/metadata": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-12.8.2.tgz", - "integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared": { - "version": "12.8.2", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-12.8.2.tgz", - "integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==", - "dev": true, - "license": "MIT", - "dependencies": { - "vue": "^3.5.13" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/algoliasearch": { - "version": "5.49.2", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.49.2.tgz", - "integrity": "sha512-1K0wtDaRONwfhL4h8bbJ9qTjmY6rhGgRvvagXkMBsAOMNr+3Q2SffHECh9DIuNVrMA1JwA0zCwhyepgBZVakng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@algolia/abtesting": "1.15.2", - "@algolia/client-abtesting": "5.49.2", - "@algolia/client-analytics": "5.49.2", - "@algolia/client-common": "5.49.2", - "@algolia/client-insights": "5.49.2", - "@algolia/client-personalization": "5.49.2", - "@algolia/client-query-suggestions": "5.49.2", - "@algolia/client-search": "5.49.2", - "@algolia/ingestion": "1.49.2", - "@algolia/monitoring": "1.49.2", - "@algolia/recommend": "5.49.2", - "@algolia/requester-browser-xhr": "5.49.2", - "@algolia/requester-fetch": "5.49.2", - "@algolia/requester-node-http": "5.49.2" - }, - "engines": { - "node": ">= 14.0.0" - } - }, - "node_modules/birpc": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", - "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/copy-anything": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz", - "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-what": "^5.2.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/emoji-regex-xs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", - "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", - "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "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" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/focus-trap": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.8.0.tgz", - "integrity": "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tabbable": "^6.4.0" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/hast-util-to-html": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", - "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", - "dev": true, - "license": "MIT", - "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" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/hast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/html-void-elements": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-what": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz", - "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/mark.js": { - "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/mdast-util-to-hast": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", - "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", - "dev": true, - "license": "MIT", - "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" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "dev": true, - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/minisearch": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/minisearch/-/minisearch-7.2.0.tgz", - "integrity": "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg==", - "dev": true, - "license": "MIT" - }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/oniguruma-to-es": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-3.1.1.tgz", - "integrity": "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex-xs": "^1.0.0", - "regex": "^6.0.1", - "regex-recursion": "^6.0.2" - } - }, - "node_modules/perfect-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", - "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/preact": { - "version": "10.29.0", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.0.tgz", - "integrity": "sha512-wSAGyk2bYR1c7t3SZ3jHcM6xy0lcBcDel6lODcs9ME6Th++Dx2KU+6D3HD8wMMKGA8Wpw7OMd3/4RGzYRpzwRg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/preact" - } - }, - "node_modules/property-information": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", - "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-recursion": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", - "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "regex-utilities": "^2.3.0" - } - }, - "node_modules/regex-utilities": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", - "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", - "dev": true, - "license": "MIT" - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.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" - } - }, - "node_modules/search-insights": { - "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/shiki": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-2.5.0.tgz", - "integrity": "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ==", - "dev": true, - "license": "MIT", - "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" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/speakingurl": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", - "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stringify-entities": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", - "dev": true, - "license": "MIT", - "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/superjson": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", - "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "copy-anything": "^4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tabbable": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.4.0.tgz", - "integrity": "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==", - "dev": true, - "license": "MIT" - }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-position": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vitepress": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.6.4.tgz", - "integrity": "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg==", - "dev": true, - "license": "MIT", - "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" - }, - "bin": { - "vitepress": "bin/vitepress.js" - }, - "peerDependencies": { - "markdown-it-mathjax3": "^4", - "postcss": "^8" - }, - "peerDependenciesMeta": { - "markdown-it-mathjax3": { - "optional": true - }, - "postcss": { - "optional": true - } - } - }, - "node_modules/vue": { - "version": "3.5.30", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.30.tgz", - "integrity": "sha512-hTHLc6VNZyzzEH/l7PFGjpcTvUgiaPK5mdLkbjrTeWSRcEfxFrv56g/XckIYlE9ckuobsdwqd5mk2g1sBkMewg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.30", - "@vue/compiler-sfc": "3.5.30", - "@vue/runtime-dom": "3.5.30", - "@vue/server-renderer": "3.5.30", - "@vue/shared": "3.5.30" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index cb3f845..0000000 --- a/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "type": "module", - "name": "sampsharp-website-expl", - "version": "1.0.0", - "description": "", - "main": "index.js", - "directories": { - "doc": "docs" - }, - "scripts": { - "docs:dev": "vitepress dev docs", - "docs:build": "vitepress build docs", - "docs:preview": "vitepress preview docs" - }, - "keywords": [], - "author": "", - "license": "ISC", - "devDependencies": { - "vitepress": "1.6.4", - "vue": "3.5.30" - } -} diff --git a/sampsharp-src b/sampsharp-src new file mode 160000 index 0000000..0173895 --- /dev/null +++ b/sampsharp-src @@ -0,0 +1 @@ +Subproject commit 01738950d72f3d87293478b7b3e66c29f3397294 diff --git a/template/public/main.css b/template/public/main.css new file mode 100644 index 0000000..7e9cc3e --- /dev/null +++ b/template/public/main.css @@ -0,0 +1,3 @@ +#logo { + height: 50px; +} \ No newline at end of file diff --git a/template/public/main.js b/template/public/main.js new file mode 100644 index 0000000..1c149f3 --- /dev/null +++ b/template/public/main.js @@ -0,0 +1,14 @@ +export default { + iconLinks: [ + { + icon: "github", + href: "https://github.com/ikkentim/sampsharp", + title: "GitHub", + }, + { + icon: "discord", + href: "https://discord.com/invite/gwcHpqp", + title: "Discord", + }, + ], +}; diff --git a/toc.yml b/toc.yml new file mode 100644 index 0000000..c53e2ac --- /dev/null +++ b/toc.yml @@ -0,0 +1,6 @@ +- name: Documentation + href: docs/ +- name: API + href: api/ +- name: Download + href: https://github.com/ikkentim/SampSharp/releases \ No newline at end of file