commit 05c300435cc6064041dd30105abd53ce6db5924f Author: MengStack Dev Date: Fri Oct 2 23:55:36 2026 +0800 Initial commit: MengStack official website diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7194045 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules/ +.vitepress/dist/ +.vitepress/cache/ +*.local +.DS_Store +Thumbs.db diff --git a/.vitepress/config.ts b/.vitepress/config.ts new file mode 100644 index 0000000..da8f442 --- /dev/null +++ b/.vitepress/config.ts @@ -0,0 +1,172 @@ +import { defineConfig } from 'vitepress' + +const seoPages: Record = { + '/': { + title: 'MengStack - 企业级Go语言微服务开发框架 | 开源模块化开发底座', + description: 'MengStack是软盟SoftUnis开源的企业级Go语言微服务开发框架,基于Gin+GORM+uber-go/fx构建,内置三层隔离架构、多租户支持、JWT认证、API文档、Docker部署等能力,开箱即用,帮助开发者快速搭建企业级后端服务。', + keywords: 'Go微服务框架,Go企业级开发框架,MengStack,开源Go框架,Go模块化开发', + }, + '/guide/what-is-mengstack': { + title: '什么是MengStack | 架构设计与核心特性介绍 - MengStack官方文档', + description: 'MengStack入门指南,详细介绍框架设计理念、三层隔离 Kernel/App/Modules 架构、四层模块模式、核心特性清单、适用场景与完整技术栈选型,帮助开发者快速了解MengStack框架。', + keywords: 'MengStack教程,MengStack架构,Go框架架构设计,DDD四层架构,Go微服务入门', + }, + '/guide/getting-started': { + title: '快速开始 | 5分钟搭建MengStack项目环境 - MengStack官方文档', + description: 'MengStack快速开始教程,包含环境要求、项目克隆、依赖安装、配置修改、服务启动完整步骤,帮助开发者5分钟跑通第一个MengStack项目,快速体验框架能力。', + keywords: 'MengStack快速开始,MengStack安装,Go项目搭建,Go框架入门教程', + }, + '/guide/project-structure': { + title: '项目结构说明 | MengStack目录规范详解 - MengStack官方文档', + description: '详细介绍MengStack标准项目目录结构,各目录职责划分、模块组织规范、依赖注入配置方式,帮助开发者遵循统一规范开发,降低团队协作成本。', + keywords: 'MengStack项目结构,Go项目目录规范,Go项目架构,模块化开发规范', + }, + '/api/overview': { + title: 'API接口概览 | 统一响应格式与错误码说明 - MengStack官方文档', + description: 'MengStack API接口参考文档,包含接口基础信息、统一响应格式规范、HTTP状态码与错误码说明、JWT认证方式说明、完整接口列表,以及在线Swagger UI调试入口。', + keywords: 'MengStack API,Go接口文档,RESTful API规范,JWT认证接口,Swagger接口文档', + }, + '/changelog': { + title: '更新日志 | 版本迭代记录与路线图 - MengStack开源框架', + description: 'MengStack各版本更新记录,包含v0.1.0首发版本技术栈说明、功能特性清单,以及后续版本路线图规划,跟进MengStack框架最新功能动态。', + keywords: 'MengStack更新日志,MengStack版本,Go框架更新,开源项目路线图', + }, + '/demo': { + title: '在线演示 | 免费体验MengStack接口服务 - MengStack官方', + description: 'MengStack官方在线演示环境,提供公开API服务地址、Swagger UI在线调试入口、健康检查地址,附快速体验步骤指引,无需本地部署即可直接体验框架接口能力。', + keywords: 'MengStack在线演示,Go框架体验,Swagger在线调试,API接口测试', + }, + '/community': { + title: '开发者社区 | 交流渠道与贡献指南 - MengStack开源社区', + description: 'MengStack开源开发者社区,提供代码仓库地址、问题反馈渠道、功能建议入口,以及Bug报告、代码提交、代码规范等贡献指引,欢迎所有开发者参与MengStack共建。', + keywords: 'MengStack社区,Go开源社区,Go开发者交流,开源项目贡献', + }, +} + +function getPagePath(relativePath: string) { + let p = '/' + relativePath.replace(/\.md$/, '').replace(/\/index$/, '') + if (p === '/index') p = '/' + return p +} + +function getSeo(pagePath: string) { + return seoPages[pagePath] || seoPages['/'] +} + +export default defineConfig({ + title: 'MengStack', + titleTemplate: ':title', + description: 'MengStack - 企业级 Go 语言微服务开发框架', + lang: 'zh-CN', + + head: [ + ['link', { rel: 'icon', href: '/favicon.png' }], + ['meta', { property: 'og:image', content: '/og-image.png' }], + ['meta', { name: 'theme-color', content: '#C8963E' }], + ], + + transformHead({ pageData }) { + const path = getPagePath(pageData.relativePath) + const seo = getSeo(path) + const url = `https://mengstack.softunis.com${path === '/' ? '/' : path + '.html'}` + const head: [string, Record][] = [ + ['meta', { name: 'description', content: seo.description }], + ['meta', { name: 'keywords', content: seo.keywords }], + ['link', { rel: 'canonical', href: url }], + ['meta', { property: 'og:title', content: seo.title }], + ['meta', { property: 'og:description', content: seo.description }], + ['meta', { property: 'og:url', content: url }], + ] + return head + }, + + themeConfig: { + logo: { + light: '/logo-light.png', + dark: '/logo-dark.png', + alt: 'MengStack 企业级Go语言微服务开发框架', + }, + siteTitle: 'MengStack', + + nav: [ + { text: '首页', link: '/' }, + { text: '指南', link: '/guide/what-is-mengstack' }, + { text: 'API 参考', link: '/api/overview' }, + { text: '更新日志', link: '/changelog' }, + { text: '在线演示', link: '/demo' }, + { text: '社区', link: '/community' }, + ], + + sidebar: { + '/guide/': [ + { + text: '入门', + items: [ + { text: '什么是 MengStack', link: '/guide/what-is-mengstack' }, + { text: '快速开始', link: '/guide/getting-started' }, + { text: '项目结构', link: '/guide/project-structure' }, + ], + }, + { + text: '架构设计', + items: [ + { text: '三层隔离架构', link: '/guide/architecture' }, + { text: '模块四层模式', link: '/guide/module-pattern' }, + { text: '依赖注入', link: '/guide/dependency-injection' }, + ], + }, + { + text: '核心功能', + items: [ + { text: '认证与授权', link: '/guide/auth' }, + { text: '多租户系统', link: '/guide/multi-tenancy' }, + { text: '配置管理', link: '/guide/configuration' }, + ], + }, + { + text: '部署', + items: [ + { text: 'Docker 部署', link: '/guide/docker-deploy' }, + { text: 'CI/CD 流水线', link: '/guide/cicd' }, + ], + }, + ], + '/api/': [ + { + text: 'API 参考', + items: [ + { text: '概览', link: '/api/overview' }, + { text: '认证接口', link: '/api/auth' }, + { text: '系统接口', link: '/api/system' }, + ], + }, + ], + }, + + socialLinks: [ + { icon: 'github', link: 'https://gitea.softunis.com/mengstack' }, + ], + + footer: { + message: 'Released under the MIT License.', + copyright: `Copyright © 2026 软盟 SoftUnis
粤ICP备2023054965号  |  粤公网安备 44030502010466号`, + }, + + search: { + provider: 'local', + }, + + outline: { + label: '页面导航', + }, + + docFooter: { + prev: '上一页', + next: '下一页', + }, + + lastUpdated: { + text: '最后更新', + }, + }, +}) diff --git a/.vitepress/theme/Home.vue b/.vitepress/theme/Home.vue new file mode 100644 index 0000000..388baf3 --- /dev/null +++ b/.vitepress/theme/Home.vue @@ -0,0 +1,796 @@ + + + + + diff --git a/.vitepress/theme/Layout.vue b/.vitepress/theme/Layout.vue new file mode 100644 index 0000000..eba373c --- /dev/null +++ b/.vitepress/theme/Layout.vue @@ -0,0 +1,27 @@ + + + diff --git a/.vitepress/theme/custom.css b/.vitepress/theme/custom.css new file mode 100644 index 0000000..e2ea0ca --- /dev/null +++ b/.vitepress/theme/custom.css @@ -0,0 +1,554 @@ +/* ======================================== + MengStack Brand Theme — Gold & Bronze + ======================================== */ + +:root { + /* Brand palette */ + --ms-gold: #C8963E; + --ms-gold-light: #E0B86A; + --ms-gold-dark: #A07830; + --ms-bronze: #B87333; + --ms-bronze-dark: #8B5A2B; + --ms-cream: #FDF8EF; + --ms-cream-dark: #F5EDD8; + + /* Override VitePress brand colors */ + --vp-c-brand-1: var(--ms-gold); + --vp-c-brand-2: var(--ms-gold-dark); + --vp-c-brand-3: var(--ms-bronze); + --vp-c-brand-soft: rgba(200, 150, 62, 0.14); + --vp-c-brand-soft-2: rgba(200, 150, 62, 0.25); +} + +/* ============ NAV BAR ============ */ +.VPNav { + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); +} + +.VPNavBar { + border-bottom: 1px solid rgba(200, 150, 62, 0.1) !important; + background: rgba(255, 255, 255, 0.85) !important; +} + +.dark .VPNavBar { + background: rgba(27, 27, 30, 0.88) !important; + border-bottom-color: rgba(200, 150, 62, 0.12) !important; +} + +.VPNavBarTitle a.title { + font-weight: 700; +} + +.VPNavBarTitle a.title span { + background: linear-gradient(135deg, var(--ms-gold-dark), var(--ms-gold-light)); + -webkit-background-clip: text; + background-clip: text; + color: transparent !important; +} + +.VPNavBar .VPNavBarMenuLink, +.VPNavBar .VPNavBarMenuGroup .title { + font-weight: 500; + transition: color 0.25s; +} + +.VPNavBar .VPNavBarMenuLink:hover, +.VPNavBar .VPNavBarMenuGroup .title:hover { + color: var(--ms-gold) !important; +} + +.VPNavBar .VPNavBarMenuLink.active { + color: var(--ms-gold) !important; +} + +.VPNavBar .VPNavBarMenuLink.active::after { + background: var(--ms-gold) !important; +} + +/* Social icon */ +.VPNavBar .VPSocialLink:hover { + color: var(--ms-gold) !important; + transform: scale(1.1); +} + +.VPNavBar .VPSocialLink { + transition: color 0.25s, transform 0.25s; +} + +/* ============ HERO SECTION ============ */ +.VPHero { + padding-top: 48px; + padding-bottom: 40px; + position: relative; + overflow: hidden; +} + +.VPHero::before { + content: ''; + position: absolute; + top: -40%; + left: -20%; + width: 140%; + height: 180%; + background: radial-gradient(ellipse at 30% 20%, rgba(200, 150, 62, 0.06) 0%, transparent 60%), + radial-gradient(ellipse at 70% 80%, rgba(184, 115, 51, 0.04) 0%, transparent 50%); + pointer-events: none; + z-index: 0; +} + +.dark .VPHero::before { + background: radial-gradient(ellipse at 30% 20%, rgba(200, 150, 62, 0.08) 0%, transparent 60%), + radial-gradient(ellipse at 70% 80%, rgba(184, 115, 51, 0.05) 0%, transparent 50%); +} + +.VPHero .main { + position: relative; + z-index: 1; +} + +/* Hide empty image column, make content full-width */ +.VPHero .image { + display: none !important; +} + +.VPHero .container { + grid-template-columns: 1fr !important; + gap: 0 !important; + max-width: 100% !important; + width: 100% !important; + flex-grow: 1 !important; +} + +.VPHero .content { + max-width: 100% !important; + flex: 1 1 100% !important; +} + +/* Hero name — premium gold gradient text */ +.VPHero .heading { + margin-bottom: 8px; +} + +.VPHero .heading .name { + font-size: 4.2rem !important; + line-height: 1.1 !important; + letter-spacing: -0.03em; + font-weight: 800; + background: linear-gradient(135deg, #B8862D 0%, #D4A84B 25%, #F0D078 50%, #D4A84B 75%, #A07020 100%); + -webkit-background-clip: text !important; + background-clip: text !important; + color: transparent !important; + text-shadow: none; + position: relative; + display: inline-block; +} + +/* Decorative accent line under the name */ +.VPHero .heading .name::after { + content: ''; + position: absolute; + bottom: -6px; + left: 0; + width: 80px; + height: 3px; + background: linear-gradient(90deg, var(--ms-gold), var(--ms-gold-light), transparent); + border-radius: 2px; +} + +.VPHero .text { + font-size: 1.6rem !important; + line-height: 1.4 !important; + font-weight: 600; + margin-top: 20px; +} + +.dark .VPHero .text { + color: rgba(255, 255, 255, 0.88) !important; +} + +.VPHero .tagline { + font-size: 1.1rem !important; + color: var(--ms-gold-dark) !important; + font-weight: 400; + letter-spacing: 0.03em; + margin-top: 12px; +} + +.dark .VPHero .tagline { + color: var(--ms-gold-light) !important; +} + +/* Hero buttons */ +.VPHero .actions .action a.VPButton.brand { + background: linear-gradient(135deg, var(--ms-gold-dark), var(--ms-gold)) !important; + border: none !important; + color: #fff !important; + font-weight: 600; + border-radius: 10px !important; + padding: 0 28px !important; + height: 44px !important; + line-height: 44px !important; + font-size: 0.95rem !important; + box-shadow: 0 4px 14px rgba(200, 150, 62, 0.3); + transition: all 0.3s ease; +} + +.VPHero .actions .action a.VPButton.brand:hover { + box-shadow: 0 6px 20px rgba(200, 150, 62, 0.45); + transform: translateY(-2px); +} + +.VPHero .actions .action a.VPButton.alt { + border: 1.5px solid var(--ms-gold) !important; + color: var(--ms-gold-dark) !important; + border-radius: 10px !important; + padding: 0 28px !important; + height: 44px !important; + line-height: 42px !important; + font-size: 0.95rem !important; + font-weight: 600; + background: transparent !important; + transition: all 0.3s ease; +} + +.dark .VPHero .actions .action a.VPButton.alt { + color: var(--ms-gold-light) !important; + border-color: var(--ms-gold-light) !important; +} + +.VPHero .actions .action a.VPButton.alt:hover { + background: rgba(200, 150, 62, 0.08) !important; + transform: translateY(-2px); +} + +/* ============ FEATURES SECTION ============ */ +.VPFeatures { + padding: 48px 0 56px !important; +} + +.VPFeatures .VPFeature .box { + border: 1px solid rgba(200, 150, 62, 0.12) !important; + border-radius: 14px !important; + padding: 28px 24px 24px !important; + background: rgba(255, 255, 255, 0.7) !important; + backdrop-filter: blur(6px); + -webkit-backdrop-filter: blur(6px); + transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1); + position: relative; + overflow: hidden; +} + +.dark .VPFeatures .VPFeature .box { + background: rgba(40, 40, 44, 0.6) !important; + border-color: rgba(200, 150, 62, 0.1) !important; +} + +.VPFeatures .VPFeature .box::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, var(--ms-gold-dark), var(--ms-gold-light), var(--ms-bronze)); + opacity: 0; + transition: opacity 0.35s; +} + +.VPFeatures .VPFeature:hover .box { + border-color: rgba(200, 150, 62, 0.3) !important; + box-shadow: 0 8px 30px rgba(200, 150, 62, 0.1), 0 2px 8px rgba(0, 0, 0, 0.04); + transform: translateY(-4px); +} + +.dark .VPFeatures .VPFeature:hover .box { + border-color: rgba(200, 150, 62, 0.25) !important; + box-shadow: 0 8px 30px rgba(200, 150, 62, 0.08), 0 2px 8px rgba(0, 0, 0, 0.2); +} + +.VPFeatures .VPFeature:hover .box::before { + opacity: 1; +} + +/* Feature icon */ +.VPFeatures .VPFeature .icon { + width: 52px !important; + height: 52px !important; + display: flex; + align-items: center; + justify-content: center; + font-size: 1.6rem; + background: linear-gradient(135deg, rgba(200, 150, 62, 0.08), rgba(184, 115, 51, 0.05)) !important; + border: 1px solid rgba(200, 150, 62, 0.12); + border-radius: 12px !important; + margin-bottom: 4px; +} + +.dark .VPFeatures .VPFeature .icon { + background: linear-gradient(135deg, rgba(200, 150, 62, 0.12), rgba(184, 115, 51, 0.08)) !important; + border-color: rgba(200, 150, 62, 0.15); +} + +/* Feature title */ +.VPFeatures .VPFeature .title { + font-size: 1.05rem !important; + font-weight: 700 !important; + color: var(--ms-bronze-dark) !important; + letter-spacing: 0.01em; +} + +.dark .VPFeatures .VPFeature .title { + color: var(--ms-gold-light) !important; +} + +/* Feature details — prevent truncation */ +.VPFeatures .details { + display: -webkit-box; + -webkit-line-clamp: 4; + -webkit-box-orient: vertical; + overflow: hidden; + line-height: 1.65; + font-size: 0.88rem !important; + color: var(--vp-c-text-2) !important; +} + +/* Feature link arrow */ +.VPFeatures .VPFeature .link-text { + color: var(--ms-gold) !important; + font-weight: 600; +} + +/* ============ ABOUT SECTION ============ */ +.VPDoc:has(.content-container) .main .content .content-body { + max-width: none; +} + +.VPHome .VPHomeContent { + max-width: 1152px; + margin: 0 auto; + padding: 0 24px; +} + +/* Style the "关于 MengStack" section */ +.VPHome .vp-doc h2 { + font-size: 1.8rem; + font-weight: 700; + text-align: center; + margin: 48px 0 24px; + background: linear-gradient(135deg, var(--ms-gold-dark), var(--ms-bronze)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + position: relative; +} + +.VPHome .vp-doc h2::after { + content: ''; + display: block; + width: 60px; + height: 3px; + background: linear-gradient(90deg, var(--ms-gold), var(--ms-bronze)); + margin: 12px auto 0; + border-radius: 2px; +} + +.VPHome .vp-doc p { + font-size: 1.05rem; + line-height: 1.85; + color: var(--vp-c-text-1); + max-width: 720px; + margin: 0 auto 16px; + text-align: center; +} + +/* ============ FOOTER ============ */ +.VPFooter { + border-top: 1px solid rgba(200, 150, 62, 0.1) !important; + background: rgba(250, 247, 240, 0.6) !important; + padding: 28px 0 !important; +} + +.dark .VPFooter { + background: rgba(20, 20, 22, 0.8) !important; + border-top-color: rgba(200, 150, 62, 0.08) !important; +} + +.VPFooter .message { + color: var(--ms-gold-dark) !important; + font-weight: 500; +} + +.dark .VPFooter .message { + color: var(--ms-gold-light) !important; +} + +.VPFooter a { + color: var(--vp-c-text-2); + text-decoration: none; + transition: color 0.25s; +} + +.VPFooter a:hover { + color: var(--ms-gold) !important; + text-decoration: none; +} + +.footer-extra { + margin-top: 8px; + font-size: 12px; + color: var(--vp-c-text-2); +} + +.footer-extra a { + color: var(--vp-c-text-2); + text-decoration: none; + transition: color 0.25s; +} + +.footer-extra a:hover { + color: var(--ms-gold); + text-decoration: underline; +} + +/* ============ DOC PAGES ============ */ +/* Sidebar active item */ +.VPSidebarItem.is-active > .item .link .link-text { + color: var(--ms-gold) !important; + font-weight: 600; +} + +.VPSidebarItem.is-active > .item .link { + background: rgba(200, 150, 62, 0.06) !important; + border-left-color: var(--ms-gold) !important; +} + +/* Sidebar hover */ +.VPSidebarItem .item .link:hover { + background: rgba(200, 150, 62, 0.04) !important; +} + +/* Inline code */ +.vp-doc code { + background: rgba(200, 150, 62, 0.08) !important; + color: var(--ms-bronze-dark) !important; + border: 1px solid rgba(200, 150, 62, 0.1); + border-radius: 5px; + padding: 2px 6px; + font-size: 0.88em; +} + +.dark .vp-doc code { + background: rgba(200, 150, 62, 0.1) !important; + color: var(--ms-gold-light) !important; + border-color: rgba(200, 150, 62, 0.12); +} + +/* Blockquote / custom containers */ +.vp-doc blockquote { + border-left: 3px solid var(--ms-gold) !important; + background: rgba(200, 150, 62, 0.04); + padding: 12px 16px; + border-radius: 0 8px 8px 0; + color: var(--vp-c-text-2); +} + +/* Links in content */ +.vp-doc a { + color: var(--ms-gold) !important; + font-weight: 500; + text-decoration: none; + border-bottom: 1px solid transparent; + transition: border-color 0.25s; +} + +.vp-doc a:hover { + border-bottom-color: var(--ms-gold); +} + +/* Headings in doc pages */ +.vp-doc h1, .vp-doc h2, .vp-doc h3, .vp-doc h4 { + color: var(--ms-bronze-dark); + font-weight: 700; +} + +.dark .vp-doc h1, .dark .vp-doc h2, .dark .vp-doc h3, .dark .vp-doc h4 { + color: var(--ms-gold-light); +} + +.vp-doc h2 { + border-bottom: 1px solid rgba(200, 150, 62, 0.15) !important; +} + +/* Table styling */ +.vp-doc table { + border-collapse: collapse; + width: 100%; +} + +.vp-doc table th { + background: rgba(200, 150, 62, 0.06) !important; + color: var(--ms-bronze-dark); + font-weight: 600; +} + +.dark .vp-doc table th { + background: rgba(200, 150, 62, 0.08) !important; + color: var(--ms-gold-light); +} + +.vp-doc table tr { + border-bottom: 1px solid rgba(200, 150, 62, 0.08); +} + +/* ============ SEARCH ============ */ +.VPLocalSearchBox .filter { + background: rgba(200, 150, 62, 0.08) !important; + border-color: rgba(200, 150, 62, 0.15) !important; + color: var(--ms-gold-dark); +} + +/* ============ SCROLLBAR ============ */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: rgba(200, 150, 62, 0.2); + border-radius: 4px; +} + +::-webkit-scrollbar-thumb:hover { + background: rgba(200, 150, 62, 0.35); +} + +/* ============ SELECTION ============ */ +::selection { + background: rgba(200, 150, 62, 0.2); + color: inherit; +} + +/* ============ TRANSITIONS ============ */ +.VPNavBar, .VPFeatures .VPFeature, .VPHero .actions a, .VPFooter { + transition-property: background, border-color, box-shadow, transform; + transition-duration: 0.3s; + transition-timing-function: ease; +} + +/* ============ RESPONSIVE ============ */ +@media (max-width: 768px) { + .VPHero .heading .name { + font-size: 2.8rem !important; + } + .VPHero .text { + font-size: 1.3rem !important; + } + .VPFeatures .VPFeature .box { + padding: 22px 18px 18px !important; + } +} diff --git a/.vitepress/theme/index.js b/.vitepress/theme/index.js new file mode 100644 index 0000000..42fe9a9 --- /dev/null +++ b/.vitepress/theme/index.js @@ -0,0 +1,4 @@ +import DefaultTheme from 'vitepress/theme' +import './custom.css' + +export default DefaultTheme diff --git a/api/auth.md b/api/auth.md new file mode 100644 index 0000000..094c382 --- /dev/null +++ b/api/auth.md @@ -0,0 +1,181 @@ +# 认证接口 + +## 用户注册 + +注册新用户并返回 JWT 令牌。 + +**`POST /api/v1/auth/register`** + +### 请求体 + +```json +{ + "email": "user@example.com", + "username": "johndoe", + "nickname": "John Doe", + "password": "securepass123" +} +``` + +| 字段 | 类型 | 必填 | 约束 | +|------|------|------|------| +| `email` | string | 是 | 有效邮箱格式 | +| `username` | string | 是 | 3-64 字符 | +| `nickname` | string | 否 | - | +| `password` | string | 是 | 8-128 字符 | + +### 响应 + +```json +{ + "code": 0, + "message": "success", + "data": { + "access_token": "eyJhbGciOiJIUzI1NiIs...", + "refresh_token": "eyJhbGciOiJIUzI1NiIs...", + "expires_in": 7200 + }, + "trace_id": "req-abc-123" +} +``` + +### 错误 + +| 状态码 | 说明 | +|--------|------| +| 400 | 参数校验失败 | +| 409 | 邮箱或用户名已存在 | + +--- + +## 用户登录 + +使用邮箱和密码登录。 + +**`POST /api/v1/auth/login`** + +### 请求体 + +```json +{ + "email": "user@example.com", + "password": "securepass123" +} +``` + +| 字段 | 类型 | 必填 | +|------|------|------| +| `email` | string | 是 | +| `password` | string | 是 | + +### 响应 + +同注册接口,返回 TokenPair。 + +### 错误 + +| 状态码 | 说明 | +|--------|------| +| 400 | 参数校验失败 | +| 401 | 邮箱或密码错误 | + +--- + +## 刷新令牌 + +使用 refresh_token 获取新的令牌对。 + +**`POST /api/v1/auth/refresh`** + +### 请求体 + +```json +{ + "refresh_token": "eyJhbGciOiJIUzI1NiIs..." +} +``` + +### 响应 + +同注册接口,返回新的 TokenPair。 + +### 错误 + +| 状态码 | 说明 | +|--------|------| +| 400 | 参数校验失败 | +| 401 | Refresh Token 无效或过期 | + +--- + +## 修改密码 + +修改当前用户密码,需要认证。 + +**`POST /api/v1/password`** + +### 请求头 + +``` +Authorization: Bearer +X-Tenant-ID: +``` + +### 请求体 + +```json +{ + "old_password": "oldpass123", + "new_password": "newpass456" +} +``` + +| 字段 | 类型 | 必填 | 约束 | +|------|------|------|------| +| `old_password` | string | 是 | - | +| `new_password` | string | 是 | 8-128 字符 | + +### 响应 + +```json +{ + "code": 0, + "message": "success", + "data": null, + "trace_id": "req-abc-123" +} +``` + +--- + +## 获取当前用户 + +获取当前认证用户的个人资料。 + +**`GET /api/v1/profile`** + +### 请求头 + +``` +Authorization: Bearer +X-Tenant-ID: +``` + +### 响应 + +```json +{ + "code": 0, + "message": "success", + "data": { + "id": 1, + "email": "user@example.com", + "username": "johndoe", + "nickname": "John Doe", + "avatar": "", + "status": 1, + "tenant_id": "tenant-001" + }, + "trace_id": "req-abc-123" +} +``` diff --git a/api/overview.md b/api/overview.md new file mode 100644 index 0000000..e51c820 --- /dev/null +++ b/api/overview.md @@ -0,0 +1,73 @@ +--- +title: API接口概览 | 统一响应格式与错误码说明 - MengStack官方文档 +--- + +# API 概览 + +MengStack API 基于 RESTful 设计,所有接口统一前缀 `/api/v1`。 + +## 基础信息 + +| 项目 | 值 | +|------|------| +| Base URL | `http://localhost:2222/api/v1` | +| 数据格式 | JSON | +| 认证方式 | Bearer Token (JWT) | +| API 文档 | `http://localhost:2222/swagger/index.html` | + +## 统一响应格式 + +所有接口返回统一格式: + +```json +{ + "code": 0, + "message": "success", + "data": {}, + "trace_id": "req-abc-123" +} +``` + +| 字段 | 类型 | 说明 | +|------|------|------| +| `code` | int | 状态码,0 表示成功 | +| `message` | string | 状态描述 | +| `data` | any | 响应数据 | +| `trace_id` | string | 请求追踪 ID | + +## 错误码 + +| HTTP 状态码 | 说明 | +|------------|------| +| 200 | 成功 | +| 400 | 请求参数错误 | +| 401 | 未认证或 Token 过期 | +| 403 | 无权限 | +| 404 | 资源不存在 | +| 409 | 资源冲突(如邮箱已注册) | +| 500 | 服务器内部错误 | + +## 认证 + +需要认证的接口,在请求头中携带: + +``` +Authorization: Bearer +X-Tenant-ID: +``` + +## 接口列表 + +| 模块 | 端点 | 说明 | +|------|------|------| +| 认证 | `POST /auth/register` | 用户注册,详见[认证接口](/api/auth) | +| 认证 | `POST /auth/login` | 用户登录,详见[认证接口](/api/auth) | +| 认证 | `POST /auth/refresh` | 刷新令牌,详见[认证接口](/api/auth) | +| 认证 | `POST /password` | 修改密码,详见[认证接口](/api/auth) | +| 认证 | `GET /profile` | 获取当前用户,详见[认证接口](/api/auth) | +| 系统 | `GET /health` | 健康检查,详见[系统接口](/api/system) | +| 系统 | `GET /ping` | 连通性测试,详见[系统接口](/api/system) | + +## Swagger UI + +启动服务后访问 `http://localhost:2222/swagger/index.html` 查看交互式 API 文档。 diff --git a/api/system.md b/api/system.md new file mode 100644 index 0000000..b9226df --- /dev/null +++ b/api/system.md @@ -0,0 +1,66 @@ +# 系统接口 + +## 健康检查 + +检查 PostgreSQL 和 Redis 连接状态。 + +**`GET /health`** + +无需认证。 + +### 响应 + +```json +{ + "status": "ok", + "database": "connected", + "redis": "connected", + "timestamp": 1727856000, + "version": "0.1.0", + "trace_id": "req-abc-123" +} +``` + +### 状态说明 + +| 字段 | 可能值 | +|------|--------| +| `status` | `ok` / `degraded` / `down` | +| `database` | `connected` / `disconnected` | +| `redis` | `connected` / `disconnected` | + +--- + +## 连通性测试 + +返回 pong,用于验证认证和多租户中间件是否正常工作。 + +**`GET /api/v1/ping`** + +需要认证和租户头。 + +### 请求头 + +``` +Authorization: Bearer +X-Tenant-ID: +``` + +### 响应 + +```json +{ + "code": 0, + "message": "success", + "data": { + "message": "pong" + }, + "trace_id": "req-abc-123" +} +``` + +### 用途 + +- 验证 Token 是否有效 +- 验证多租户中间件是否正常 +- 客户端心跳检测 diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..06bbd55 --- /dev/null +++ b/changelog.md @@ -0,0 +1,81 @@ +--- +title: 更新日志 | 版本迭代记录与路线图 - MengStack开源框架 +--- + +# 更新日志 + +## v0.1.0 (2026-10-02) + +**初始版本** — 项目骨架 + 认证模块 + +### 新增 + +- **三层隔离架构**:Kernel / App / Modules 层间依赖方向单一 +- **模块四层模式**:Domain / Application / Infrastructure / Interfaces +- **依赖注入**:基于 uber-go/fx 的自动依赖解析和生命周期管理 +- **配置管理**:Viper 分层配置,支持 YAML + 环境变量覆盖 +- **结构化日志**:Zap 结构化输出,请求级 trace_id +- **多租户支持**:基于 X-Tenant-ID 的租户隔离中间件 +- **认证模块**: + - 用户注册(邮箱 + 用户名 + 密码) + - 用户登录(邮箱 + 密码) + - JWT 双 Token 机制(Access + Refresh) + - Token 刷新 + - 密码修改 + - 用户资料查询 +- **统一响应格式**:`{code, message, data, trace_id}` +- **Swagger API 文档**:swaggo 注解驱动,自动生成 Swagger UI +- **Docker Compose**:PostgreSQL + Redis + 应用一键启动 +- **健康检查**:PostgreSQL + Redis 连接状态检测 +- **CORS 中间件**:跨域请求支持 +- **请求追踪**:每个请求自动分配 trace_id + +### 技术栈 + +| 组件 | 版本 | +|------|------| +| Go | 1.23 | +| Gin | 1.10 | +| GORM | 1.25 | +| PostgreSQL | 14+ | +| Redis | 7+ | +| uber-go/fx | 1.23 | +| Zap | 1.27 | +| Viper | 1.19 | +| golang-jwt | 5.2 | + +--- + +## 路线图 + +### v0.2.0 — RBAC 权限模型 + +- Role / Permission 数据模型 +- 用户角色分配 +- RBAC 中间件 +- 权限校验装饰器 + +### v0.3.0 — 组织管理 + 审计日志 + +- 组织 CRUD +- 用户-组织关系 +- 操作审计日志 + +### v0.4.0 — 配置管理增强 + +- 运行时配置 API +- 全局默认 + 租户覆盖 +- 配置变更历史 + +### v0.5.0 — 用户示例模块 + +- 完整用户 CRUD +- 单元测试 + 集成测试 +- 示例代码 + +### v1.0.0 — 正式发布 + +- 完整测试覆盖 +- 安全审计 +- 性能基准测试 +- 生产部署文档 diff --git a/community.md b/community.md new file mode 100644 index 0000000..e858bc4 --- /dev/null +++ b/community.md @@ -0,0 +1,56 @@ +--- +title: 开发者社区 | 交流渠道与贡献指南 - MengStack开源社区 +--- + +# 社区 + +MengStack 正在积极建设中,欢迎参与! + +## 交流渠道 + +| 渠道 | 链接 | +|------|------| +| Gitea 仓库 | [mengstackgit.softunis.com/mengstack](https://mengstackgit.softunis.com/mengstack) | +| 问题反馈 | [Gitea Issues](https://mengstackgit.softunis.com/mengstack/issues) | +| 功能建议 | [Gitea Issues](https://mengstackgit.softunis.com/mengstack/issues/new) | + +## 参与贡献 + +### 报告 Bug + +1. 在 Gitea 上创建 Issue +2. 描述复现步骤 +3. 附上错误日志 +4. 标注环境信息(Go 版本、OS、数据库版本) + +### 提交代码 + +1. Fork 仓库 +2. 创建功能分支:`git checkout -b feature/my-feature` +3. 提交变更:`git commit -am 'Add my feature'` +4. 推送分支:`git push origin feature/my-feature` +5. 创建 Pull Request + +### 代码规范 + +- 遵循项目三层隔离架构 +- 新模块遵循四层模式(Domain / Application / Infrastructure / Interfaces) +- 所有公开函数添加 swaggo 注解 +- 提交前运行 `make lint` 和 `make test` + +## 问答社区(即将上线) + +我们正在筹备在线问答社区,届时将提供: + +- 技术问答 +- 最佳实践分享 +- 版本发布公告 +- 开发者交流 + +敬请期待! + +## 关于软盟 + +MengStack 由 [软盟 SoftUnis](https://www.softunis.com) 团队开发和维护。 + +软盟专注于企业级解决方案,致力于开源生态建设。 diff --git a/demo.md b/demo.md new file mode 100644 index 0000000..21d0930 --- /dev/null +++ b/demo.md @@ -0,0 +1,69 @@ +--- +title: 在线演示 | 免费体验MengStack接口服务 - MengStack官方 +--- + +# 在线演示 + +## 演示地址 + +| 服务 | 地址 | +|------|------| +| API 服务 | `https://mengstackdemo.softunis.com` | +| Swagger UI | `https://mengstackdemo.softunis.com/swagger/index.html` | +| 健康检查 | `https://mengstackdemo.softunis.com/health` | + +::: warning 注意 +演示数据会定期重置,请勿存储重要数据。 +::: + +## 快速体验 + +### 1. 注册账号 + +```bash +curl -X POST https://mengstackdemo.softunis.com/api/v1/auth/register \ + -H "Content-Type: application/json" \ + -d '{ + "email": "demo@example.com", + "username": "demo_user", + "nickname": "Demo User", + "password": "demo12345" + }' +``` + +### 2. 登录获取 Token + +```bash +curl -X POST https://mengstackdemo.softunis.com/api/v1/auth/login \ + -H "Content-Type: application/json" \ + -d '{ + "email": "demo@example.com", + "password": "demo12345" + }' +``` + +### 3. 访问受保护接口 + +```bash +curl https://mengstackdemo.softunis.com/api/v1/profile \ + -H "Authorization: Bearer " \ + -H "X-Tenant-ID: demo-tenant" +``` + +## Swagger UI 交互 + +打开 [Swagger UI](https://mengstackdemo.softunis.com/swagger/index.html),可以: + +- 浏览所有 API 端点 +- 在线发送请求测试 +- 查看请求/响应模型 +- 下载 OpenAPI 规范文件 + +### 使用步骤 + +1. 打开 Swagger UI +2. 点击 `/auth/register` 端点 +3. 点击 "Try it out" +4. 填写请求参数 +5. 点击 "Execute" +6. 查看响应结果 diff --git a/guide/architecture.md b/guide/architecture.md new file mode 100644 index 0000000..01ee88b --- /dev/null +++ b/guide/architecture.md @@ -0,0 +1,73 @@ +# 三层隔离架构 + +MengStack 采用三层隔离架构,从外到内依次为:**Kernel → App → Modules**。 + +## 架构总览 + +``` +┌─────────────────────────────────────────────────┐ +│ Modules │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ Auth │ │ Org │ │ User │ ... │ +│ └────┬────┘ └────┬────┘ └────┬────┘ │ +│ │ │ │ │ +├───────┼───────────┼───────────┼──────────────────┤ +│ └───────────┼───────────┘ │ +│ │ │ +│ App │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ Database │ │ Cache │ │Middleware│ ... │ +│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ +│ │ │ │ │ +├───────┼────────────┼────────────┼────────────────┤ +│ └────────────┼────────────┘ │ +│ │ │ +│ Kernel │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ Response │ │ Error │ │ Paginator│ ... │ +│ └──────────┘ └──────────┘ └──────────┘ │ +│ │ +└──────────────────────────────────────────────────┘ +``` + +## 依赖规则 + +**只能从上到下依赖,禁止反向依赖。** + +| 层 | 可以依赖 | 禁止依赖 | +|---|---|---| +| Modules | App, Kernel | 其他 Modules | +| App | Kernel | Modules | +| Kernel | 标准库 | App, Modules | + +## Kernel 层 + +零业务语义的基础组件。判断标准:**这个组件是否知道"用户"、"租户"、"订单"等业务概念?** 如果知道,它就不属于 Kernel。 + +Kernel 提供的都是纯粹的技术工具: + +- 统一响应格式 +- 通用错误类型 +- 分页工具 +- 字符串/时间工具 + +## App 层 + +应用基础设施,负责连接外部世界: + +- 数据库连接(GORM + PostgreSQL) +- 缓存连接(Redis) +- 全局中间件 +- 健康检查 + +App 层可以引用 Kernel,但不知道任何业务模块的存在。 + +## Modules 层 + +业务模块,每个模块独立自包含。模块间不能直接引用,只能通过接口或事件通信。 + +## 为什么这样分? + +1. **Kernel 可复用**:换一个项目,Kernel 可以直接搬过去 +2. **App 可替换**:换数据库、换缓存,只改 App 层 +3. **Modules 可删除**:删除一个业务模块,不影响其他模块和基础设施 diff --git a/guide/auth.md b/guide/auth.md new file mode 100644 index 0000000..832231b --- /dev/null +++ b/guide/auth.md @@ -0,0 +1,107 @@ +# 认证与授权 + +MengStack 内置完整的认证授权系统,基于 JWT 双 Token 机制。 + +## 认证流程 + +``` +┌────────┐ POST /auth/register ┌────────┐ +│ Client │ ──────────────────────────→ │ Server │ +│ │ ←────────────────────────── │ │ +│ │ { access_token, refresh } │ │ +│ │ │ │ +│ │ POST /auth/login │ │ +│ │ ──────────────────────────→ │ │ +│ │ ←────────────────────────── │ │ +│ │ { access_token, refresh } │ │ +│ │ │ │ +│ │ GET /api/v1/profile │ │ +│ │ Authorization: Bearer xxx │ │ +│ │ ──────────────────────────→ │ │ +│ │ ←────────────────────────── │ │ +│ │ { user data } │ │ +│ │ │ │ +│ │ POST /auth/refresh │ │ +│ │ { refresh_token } │ │ +│ │ ──────────────────────────→ │ │ +│ │ ←────────────────────────── │ │ +│ │ { new token pair } │ │ +└────────┘ └────────┘ +``` + +## API 端点 + +| 端点 | 方法 | 说明 | 认证 | +|------|------|------|------| +| `/api/v1/auth/register` | POST | 用户注册 | 无 | +| `/api/v1/auth/login` | POST | 用户登录 | 无 | +| `/api/v1/auth/refresh` | POST | 刷新令牌 | 无 | +| `/api/v1/password` | POST | 修改密码 | Bearer | +| `/api/v1/profile` | GET | 获取当前用户 | Bearer | + +## 注册 + +```bash +curl -X POST http://localhost:2222/api/v1/auth/register \ + -H "Content-Type: application/json" \ + -d '{ + "email": "user@example.com", + "username": "johndoe", + "nickname": "John Doe", + "password": "securepass123" + }' +``` + +响应: + +```json +{ + "code": 0, + "message": "success", + "data": { + "access_token": "eyJhbGciOiJIUzI1NiIs...", + "refresh_token": "eyJhbGciOiJIUzI1NiIs...", + "expires_in": 7200 + }, + "trace_id": "abc-123-def" +} +``` + +## 登录 + +```bash +curl -X POST http://localhost:2222/api/v1/auth/login \ + -H "Content-Type: application/json" \ + -d '{ + "email": "user@example.com", + "password": "securepass123" + }' +``` + +## 使用 Access Token + +在请求头中携带 `Authorization: Bearer `: + +```bash +curl http://localhost:2222/api/v1/profile \ + -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." +``` + +## 刷新 Token + +Access Token 过期后,使用 Refresh Token 获取新的令牌对: + +```bash +curl -X POST http://localhost:2222/api/v1/auth/refresh \ + -H "Content-Type: application/json" \ + -d '{ + "refresh_token": "eyJhbGciOiJIUzI1NiIs..." + }' +``` + +## 安全特性 + +- **密码哈希**:使用 bcrypt 加密存储,永不明文 +- **双 Token**:Access Token 短期有效(2h),Refresh Token 长期有效(7d) +- **Token 轮换**:每次刷新都生成全新的令牌对 +- **验证约束**:用户名 3-64 字符,密码 8-128 字符,邮箱格式校验 diff --git a/guide/cicd.md b/guide/cicd.md new file mode 100644 index 0000000..545c5a1 --- /dev/null +++ b/guide/cicd.md @@ -0,0 +1,53 @@ +# CI/CD 流水线 + +MengStack 使用 Gitea Actions 实现持续集成和部署。 + +## 流水线概览 + +``` +代码推送 → 代码检查 → 构建 → 测试 → Docker 镜像 → 部署 +``` + +## Gitea Actions 配置 + +仓库地址:`https://mengstackgit.softunis.com/mengstack` + +### 流水线阶段 + +| 阶段 | 说明 | +|------|------| +| Lint | 代码风格检查 | +| Build | 编译 Go 二进制 | +| Test | 运行单元测试和集成测试 | +| Docker | 构建 Docker 镜像 | +| Deploy | 部署到目标服务器 | + +## 本地验证 + +在推送代码前,本地运行检查: + +```bash +# 代码检查 +make lint + +# 运行测试 +make test + +# 构建 +make build +``` + +## 部署策略 + +当前采用单服务器部署: + +1. 代码推送到 Gitea 仓库 +2. CI 流水线自动触发 +3. 通过 SSH 部署到目标服务器 +4. Docker Compose 重启服务 + +## 后续规划 + +- **多环境支持**:dev / staging / production 环境隔离 +- **蓝绿部署**:零停机更新 +- **自动回滚**:部署失败自动回退 diff --git a/guide/configuration.md b/guide/configuration.md new file mode 100644 index 0000000..6a4caac --- /dev/null +++ b/guide/configuration.md @@ -0,0 +1,102 @@ +# 配置管理 + +MengStack 使用 [Viper](https://github.com/spf13/viper) 进行配置管理,支持多来源、分层配置。 + +## 配置优先级 + +从高到低: + +1. 环境变量(`MENGSTACK_` 前缀) +2. `.env` 文件 +3. `configs/config.yaml` +4. 默认值 + +## 配置文件 + +### `configs/config.yaml` + +```yaml +server: + port: 2222 + mode: debug # debug / release / test + +database: + host: localhost + port: 5432 + name: mengstack + user: postgres + password: "" + sslmode: disable + +redis: + host: localhost + port: 6379 + password: "" + db: 0 + +jwt: + secret: "change-me-in-production" + access_ttl: 7200 # 2 hours + refresh_ttl: 604800 # 7 days + +log: + level: debug # debug / info / warn / error + format: console # console / json +``` + +### 环境变量覆盖 + +所有配置项都可以通过环境变量覆盖,规则: + +- 前缀 `MENGSTACK_` +- 大写 +- 用 `_` 连接层级 + +```bash +# 等价于 server.port: 3000 +export MENGSTACK_SERVER_PORT=3000 + +# 等价于 database.host: db.example.com +export MENGSTACK_DB_HOST=db.example.com + +# 等价于 jwt.secret: my-secret +export MENGSTACK_JWT_SECRET=my-secret +``` + +## 代码中使用 + +```go +type Config struct { + Server ServerConfig + Database DatabaseConfig + Redis RedisConfig + JWT JWTConfig + Log LogConfig +} + +func Load() (*Config, error) { + v := viper.New() + v.SetConfigFile("configs/config.yaml") + v.SetEnvPrefix("MENGSTACK") + v.AutomaticEnv() + v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) + + if err := v.ReadInConfig(); err != nil { + return nil, err + } + + var cfg Config + if err := v.Unmarshal(&cfg); err != nil { + return nil, err + } + + return &cfg, nil +} +``` + +## 最佳实践 + +1. **不要硬编码**:所有可变配置走 Viper +2. **生产环境用环境变量**:敏感信息(密码、密钥)不写入代码仓库 +3. **提供合理默认值**:开发环境零配置即可启动 +4. **使用 `.env.example`**:提供配置模板,方便新人上手 diff --git a/guide/dependency-injection.md b/guide/dependency-injection.md new file mode 100644 index 0000000..8cbb19e --- /dev/null +++ b/guide/dependency-injection.md @@ -0,0 +1,111 @@ +# 依赖注入 + +MengStack 使用 [uber-go/fx](https://github.com/uber-go/fx) 进行依赖注入,自动管理组件的生命周期和依赖关系。 + +## 为什么用依赖注入? + +没有 DI 框架时,组装应用需要手动 wiring: + +```go +// 手动 wiring — 容易遗漏,难以维护 +db := database.New(cfg.DB) +rdb := cache.New(cfg.Redis) +repo := infrastructure.NewUserRepo(db) +svc := application.NewService(repo, rdb, cfg.JWT) +handler := interfaces.NewHandler(svc) +``` + +使用 fx 后,依赖关系由框架自动解析: + +```go +// fx 自动解析依赖 +fx.Provide( + database.New, + cache.New, + application.NewService, + interfaces.NewHandler, +) +``` + +## fx.Module 组织 + +每个模块通过 `fx.Module` 声明自己的依赖: + +```go +// internal/modules/auth/interfaces/module.go +var Module = fx.Module("auth", + fx.Provide( + infrastructure.NewUserRepository, + infrastructure.NewTokenRepository, + application.NewService, + NewHandler, + NewAuthMiddleware, + SetupRoutes, + ), +) +``` + +主应用组装所有模块: + +```go +// internal/app/app.go +func NewApp() *fx.App { + return fx.New( + fx.Provide(config.Load, logger.New), + database.Module, + cache.Module, + authinterfaces.Module, + Module, + ) +} +``` + +## 生命周期管理 + +fx 自动管理组件的启动和停止顺序: + +```go +func newServer(lc fx.Lifecycle, engine *gin.Engine) *http.Server { + srv := &http.Server{Addr: ":2222", Handler: engine} + + lc.Append(fx.Hook{ + OnStart: func(ctx context.Context) error { + go srv.ListenAndServe() + return nil + }, + OnStop: func(ctx context.Context) error { + return srv.Shutdown(ctx) + }, + }) + + return srv +} +``` + +fx 会确保: +- **OnStart** 按依赖顺序执行(先数据库,后应用) +- **OnStop** 按逆序执行(先应用,后数据库) + +## 参数注入 + +通过函数参数声明依赖,fx 自动注入: + +```go +func newEngine( + cfg *config.Config, // fx 自动提供 + log *zap.Logger, // fx 自动提供 + db *gorm.DB, // fx 自动提供 + rdb *redis.Client, // fx 自动提供 + authHandler *Handler, // fx 自动提供 + authMW gin.HandlerFunc, // fx 自动提供 +) *gin.Engine { + // ... +} +``` + +## 最佳实践 + +1. **构造函数注入**:通过 `fx.Provide` 注册构造函数 +2. **接口传递**:尽量传递接口而非具体实现 +3. **模块隔离**:每个业务模块声明自己的 `fx.Module` +4. **避免全局状态**:所有依赖通过注入获取 diff --git a/guide/docker-deploy.md b/guide/docker-deploy.md new file mode 100644 index 0000000..2c47728 --- /dev/null +++ b/guide/docker-deploy.md @@ -0,0 +1,72 @@ +# Docker 部署 + +MengStack 提供开箱即用的 Docker Compose 配置,一键启动完整开发/生产环境。 + +## 快速启动 + +```bash +# 启动所有服务(后台运行) +docker-compose up -d + +# 查看服务状态 +docker-compose ps + +# 查看日志 +docker-compose logs -f app +``` + +## 服务组成 + +```yaml +services: + app: # MengStack 应用(端口 2222) + postgres: # PostgreSQL 数据库(端口 5432) + redis: # Redis 缓存(端口 6379) +``` + +## 常用命令 + +```bash +# 启动 +docker-compose up -d + +# 停止 +docker-compose down + +# 重新构建并启动 +docker-compose up -d --build + +# 查看应用日志 +docker-compose logs -f app + +# 进入应用容器 +docker-compose exec app sh + +# 进入数据库 +docker-compose exec postgres psql -U postgres -d mengstack +``` + +## 数据持久化 + +PostgreSQL 和 Redis 数据通过 Docker Volume 持久化: + +```yaml +volumes: + postgres_data: + redis_data: +``` + +清除数据重新开始: + +```bash +docker-compose down -v +docker-compose up -d +``` + +## 生产部署建议 + +1. **修改默认密码**:`docker-compose.yml` 中的数据库密码 +2. **设置 release 模式**:`MENGSTACK_SERVER_MODE=release` +3. **配置 HTTPS**:在反向代理(Nginx/Caddy)层处理 +4. **限制端口暴露**:数据库和 Redis 不对外暴露 +5. **定期备份**:PostgreSQL 数据定时备份 diff --git a/guide/getting-started.md b/guide/getting-started.md new file mode 100644 index 0000000..e6a72f9 --- /dev/null +++ b/guide/getting-started.md @@ -0,0 +1,111 @@ +--- +title: 快速开始 | 5分钟搭建MengStack项目环境 - MengStack官方文档 +--- + +# 快速开始 + +## 环境要求 + +- Go 1.23+ +- PostgreSQL 14+ +- Redis 7+ +- Docker & Docker Compose(可选) + +## 使用 Docker Compose 启动(推荐) + +最简单的方式是使用 Docker Compose 一键启动所有服务: + +```bash +# 克隆项目 +git clone https://gitea.softunis.com/mengstack/mengstack.git +cd mengstack + +# 启动所有服务 +docker-compose up -d + +# 查看日志 +docker-compose logs -f app +``` + +服务启动后: + +- API 服务:`http://localhost:2222` +- Swagger UI:`http://localhost:2222/swagger/index.html` +- 健康检查:`http://localhost:2222/health` + +## 本地开发 + +### 1. 安装依赖 + +```bash +# 下载 Go 模块 +go mod download + +# 确保 PostgreSQL 和 Redis 已启动 +``` + +### 2. 配置环境变量 + +复制 `.env.example` 为 `.env` 并修改: + +```bash +cp .env.example .env +``` + +关键配置项: + +```env +MENGSTACK_SERVER_PORT=2222 + +# PostgreSQL +MENGSTACK_DB_HOST=localhost +MENGSTACK_DB_PORT=5432 +MENGSTACK_DB_NAME=mengstack +MENGSTACK_DB_USER=postgres +MENGSTACK_DB_PASSWORD=your_password + +# Redis +MENGSTACK_REDIS_HOST=localhost +MENGSTACK_REDIS_PORT=6379 + +# JWT +MENGSTACK_JWT_SECRET=your_jwt_secret_key +``` + +### 3. 启动服务 + +```bash +# 直接运行 +go run cmd/server/main.go + +# 或使用 Makefile +make run +``` + +### 4. 验证 + +```bash +# 健康检查 +curl http://localhost:2222/health + +# 注册新用户 +curl -X POST http://localhost:2222/api/v1/auth/register \ + -H "Content-Type: application/json" \ + -d '{ + "email": "admin@example.com", + "username": "admin", + "password": "password123" + }' +``` + +## 项目命令 + +| 命令 | 说明 | +|------|------| +| `make run` | 启动开发服务 | +| `make build` | 编译二进制文件 | +| `make test` | 运行测试 | +| `make swagger` | 重新生成 API 文档 | +| `make lint` | 代码检查 | +| `make docker-up` | Docker 启动所有服务 | +| `make docker-down` | Docker 停止所有服务 | diff --git a/guide/module-pattern.md b/guide/module-pattern.md new file mode 100644 index 0000000..964d8b4 --- /dev/null +++ b/guide/module-pattern.md @@ -0,0 +1,112 @@ +# 模块四层模式 + +每个业务模块内部采用四层结构:**Domain → Application → Infrastructure → Interfaces**。 + +## 四层结构 + +``` +┌─────────────────────────────────────┐ +│ Interfaces │ ← HTTP Handler, 路由注册 +├─────────────────────────────────────┤ +│ Application │ ← 业务逻辑编排 +├─────────────────────────────────────┤ +│ Infrastructure │ ← GORM Model, Redis 实现 +├─────────────────────────────────────┤ +│ Domain │ ← 实体, 值对象, 接口定义 +└─────────────────────────────────────┘ +``` + +## 依赖方向 + +**从上到下依赖,Domain 在最底层,不依赖任何外部包。** + +| 层 | 职责 | 可以依赖 | 禁止依赖 | +|---|---|---|---| +| Interfaces | HTTP 入口 | Application, Domain | Infrastructure | +| Application | 业务编排 | Domain | Infrastructure, Interfaces | +| Infrastructure | 数据持久化 | Domain | Application, Interfaces | +| Domain | 业务核心 | 标准库 | 所有外部包 | + +## Domain 层 + +定义业务的核心概念和契约: + +```go +// domain/entity.go +type User struct { + ID uint + Email string + Username string + Password string + TenantID string +} + +// domain/repository.go — 定义接口,不定义实现 +type UserRepository interface { + Create(ctx context.Context, user *User) error + FindByEmail(ctx context.Context, email string) (*User, error) +} +``` + +Domain 层**零外部依赖**,只使用 Go 标准库。这使得业务逻辑可以独立于框架和数据库进行单元测试。 + +## Application 层 + +编排业务流程,调用 Domain 层定义的接口: + +```go +// application/service.go +type Service struct { + repo domain.UserRepository + hasher domain.PasswordHasher + jwt domain.TokenManager +} + +func (s *Service) Register(ctx context.Context, req domain.RegisterRequest) (*domain.TokenPair, error) { + // 1. 验证邮箱唯一性 + // 2. 密码哈希 + // 3. 创建用户 + // 4. 生成 JWT + // 5. 返回 Token +} +``` + +Application 层不知道数据是怎么存的(GORM?Redis?),它只依赖 Domain 层定义的接口。 + +## Infrastructure 层 + +提供 Domain 层接口的具体实现: + +```go +// infrastructure/repository.go +type GormUserRepository struct { + db *gorm.DB +} + +func (r *GormUserRepository) Create(ctx context.Context, user *domain.User) error { + // GORM 实现 +} +``` + +Infrastructure 层实现 Domain 层定义的接口,但 Domain 层不知道 Infrastructure 的存在。 + +## Interfaces 层 + +HTTP 入口,负责请求解析和响应: + +```go +// interfaces/handler.go +func (h *Handler) Register(c *gin.Context) { + var req domain.RegisterRequest + c.ShouldBindJSON(&req) + tokens, err := h.svc.Register(c.Request.Context(), req) + response.Success(c, tokens) +} +``` + +## 好处 + +1. **可测试**:Domain 层可以脱离数据库进行单元测试 +2. **可替换**:换数据库只需写新的 Infrastructure 实现 +3. **边界清晰**:每层职责明确,新人容易理解 +4. **防止腐败**:Gin 的 `c *gin.Context` 不会渗透到业务逻辑中 diff --git a/guide/multi-tenancy.md b/guide/multi-tenancy.md new file mode 100644 index 0000000..1cd74a7 --- /dev/null +++ b/guide/multi-tenancy.md @@ -0,0 +1,58 @@ +# 多租户系统 + +MengStack 内置多租户支持,通过 `X-Tenant-ID` 请求头实现租户隔离。 + +## 工作原理 + +``` +┌─────────┐ ┌─────────┐ +│ Tenant A │──X-Tenant-ID: A──→│ │──WHERE tenant_id='A'──→ DB +├─────────┤ │ MengStack │ +│ Tenant B │──X-Tenant-ID: B──→│ Server │──WHERE tenant_id='B'──→ DB +├─────────┤ │ │ +│ Tenant C │──X-Tenant-ID: C──→│ │──WHERE tenant_id='C'──→ DB +└─────────┘ └─────────┘ +``` + +每个请求必须携带 `X-Tenant-ID` 头,中间件自动提取并注入到上下文中。 + +## 使用方式 + +### 请求示例 + +```bash +curl http://localhost:2222/api/v1/profile \ + -H "Authorization: Bearer " \ + -H "X-Tenant-ID: tenant-001" +``` + +### 中间件处理 + +认证中间件自动验证: + +1. 解析 JWT Token 获取用户信息 +2. 验证 `X-Tenant-ID` 头是否存在 +3. 将 `user_id` 和 `tenant_id` 注入到 Gin Context +4. 下游 Handler 可直接使用 `c.GetUint("user_id")` 和 `c.GetString("tenant_id")` + +### 数据层隔离 + +Repository 层自动添加租户过滤: + +```go +func (r *GormUserRepository) FindByTenant(ctx context.Context, tenantID string) ([]*domain.User, error) { + var users []*domain.User + err := r.db.Where("tenant_id = ?", tenantID).Find(&users).Error + return users, err +} +``` + +## 租户注册 + +租户管理是独立模块(M4 里程碑),当前版本通过手动在数据库创建租户记录。 + +## 安全考虑 + +- 中间件强制校验 `X-Tenant-ID`,缺失则返回 401 +- 数据查询自动过滤,防止跨租户数据泄露 +- JWT Token 中包含租户信息,服务端二次验证 diff --git a/guide/project-structure.md b/guide/project-structure.md new file mode 100644 index 0000000..1ca0b34 --- /dev/null +++ b/guide/project-structure.md @@ -0,0 +1,75 @@ +--- +title: 项目结构说明 | MengStack目录规范详解 - MengStack官方文档 +--- + +# 项目结构 + +``` +mengstack/ +├── cmd/ +│ └── server/ +│ └── main.go # 应用入口,Swagger 注解 +├── configs/ +│ └── config.yaml # 默认配置文件 +├── docs/ # Swagger 自动生成文档 +│ ├── docs.go +│ ├── swagger.json +│ └── swagger.yaml +├── internal/ +│ ├── kernel/ # 第一层:零业务语义基础组件 +│ │ └── response/ # 统一响应格式 +│ ├── app/ # 第二层:应用基础设施 +│ │ ├── cache/ # Redis 缓存模块 +│ │ ├── database/ # PostgreSQL 数据库模块 +│ │ ├── health/ # 健康检查 +│ │ ├── middleware/ # 全局中间件(CORS、请求ID、日志) +│ │ └── app.go # fx 容器组装 +│ ├── config/ # 配置加载(Viper) +│ ├── logger/ # 日志初始化(Zap) +│ └── modules/ # 第三层:业务模块 +│ └── auth/ # 认证模块 +│ ├── domain/ # 领域层:实体、值对象、接口定义 +│ ├── application/ # 应用层:业务逻辑编排 +│ ├── infrastructure/ # 基础设施层:GORM/Redis 实现 +│ └── interfaces/ # 接口层:HTTP Handler + 路由 +├── migrations/ # 数据库迁移文件 +├── test/ # 集成测试 +├── docker-compose.yml # Docker 编排 +├── Makefile # 构建命令 +├── AGENTS.md # AI 辅助开发指南 +└── go.mod # Go 模块定义 +``` + +## 目录职责 + +### `cmd/server/` + +应用入口,仅负责组装和启动。包含 Swagger 全局注解。 + +### `internal/kernel/` + +**零业务语义**的基础组件。不包含任何业务概念,只提供通用工具: + +- `response/` — 统一响应格式 `{code, message, data, trace_id}` +- 后续可扩展:`paginator/`、`errors/` 等 + +### `internal/app/` + +应用基础设施,连接 kernel 和外部世界: + +- `database/` — GORM + PostgreSQL 初始化和生命周期 +- `cache/` — Redis 客户端初始化和生命周期 +- `middleware/` — 请求 ID、请求日志、CORS +- `health/` — 健康检查端点 + +### `internal/modules/` + +业务模块目录,每个模块独立自包含,遵循四层模式。 + +### `configs/` + +默认配置文件,运行时可通过环境变量覆盖。 + +### `migrations/` + +数据库迁移文件,使用 golang-migrate 管理。 diff --git a/guide/what-is-mengstack.md b/guide/what-is-mengstack.md new file mode 100644 index 0000000..e27c7f0 --- /dev/null +++ b/guide/what-is-mengstack.md @@ -0,0 +1,68 @@ +--- +title: 什么是MengStack | 架构设计与核心特性介绍 - MengStack官方文档 +--- + +# 什么是 MengStack + +MengStack 是一个基于 Go 语言的企业级微服务开发框架,采用模块化架构设计,提供多租户、认证授权、配置管理等开箱即用的基础能力。作为面向云原生与 AI 时代的一站式全栈开发底座,MengStack 整合主流开源技术能力,帮助开发者快速搭建企业级后端服务。 + +## 设计理念 + +### 为什么选择 Go? + +Go 语言以其简洁的语法、高效的并发模型和快速的编译速度,成为构建现代后端服务的理想选择。MengStack 充分利用 Go 的生态和特性: + +- **高性能**:Go 的 goroutine 和 channel 提供轻量级并发 +- **强类型**:编译期发现错误,减少运行时意外 +- **标准库丰富**:net/http、encoding/json 等开箱即用 +- **生态成熟**:Gin、GORM、Zap 等优秀第三方库 + +### 为什么模块化? + +传统的分层架构(Controller → Service → Repository)在项目规模增长后容易出现: + +- 模块间边界模糊,耦合严重 +- 删除一个功能需要改动多个层 +- 难以独立测试和替换 + +MengStack 的[三层隔离架构](/guide/architecture)让每个业务模块都是自包含的,模块间通过明确的接口通信。每个模块遵循[四层模式](/guide/module-pattern)(Domain / Application / Infrastructure / Interfaces),确保依赖方向单一。 + +## 核心特性 + +| 特性 | 说明 | +|------|------| +| 三层隔离 | Kernel / App / Modules 层间依赖方向单一,详见[架构设计](/guide/architecture) | +| 四层模块 | Domain / Application / Infrastructure / Interfaces,详见[模块模式](/guide/module-pattern) | +| 多租户 | 基于 Header 的租户隔离,数据自动过滤,详见[多租户系统](/guide/multi-tenancy) | +| JWT 认证 | Access Token + Refresh Token 双令牌机制,详见[认证与授权](/guide/auth) | +| 依赖注入 | uber-go/fx 自动管理组件生命周期,详见[依赖注入](/guide/dependency-injection) | +| API 文档 | swaggo 注解驱动,自动生成 Swagger UI | +| 配置管理 | Viper 分层配置,支持环境变量覆盖,详见[配置管理](/guide/configuration) | +| 结构化日志 | Zap 结构化输出,请求级 trace_id | +| Docker 部署 | 开箱即用的 docker-compose,详见[Docker 部署](/guide/docker-deploy) | + +## 适用场景 + +- **SaaS 平台**:[多租户隔离](/guide/multi-tenancy)开箱即用 +- **中后台系统**:[认证](/guide/auth)、权限、审计日志完备 +- **微服务集群**:模块化设计便于拆分和独立部署 +- **开源项目**:清晰的架构便于社区贡献 + +## 技术栈 + +| 组件 | 选型 | 用途 | +|------|------|------| +| Web 框架 | Gin | HTTP 路由和中间件 | +| ORM | GORM | 数据库操作 | +| 数据库 | PostgreSQL | 主数据存储 | +| 缓存 | Redis | 缓存和会话管理 | +| 认证 | golang-jwt | JWT 令牌生成和验证 | +| DI | uber-go/fx | 依赖注入 | +| 配置 | Viper | 配置加载和管理 | +| 日志 | Zap | 结构化日志 | +| API 文档 | swaggo | Swagger 文档生成 | +| 容器化 | Docker Compose | 开发和部署环境 | + +## 快速开始 + +准备好开始使用 MengStack?查看[快速开始指南](/guide/getting-started),5 分钟即可跑通第一个项目。也可以访问[在线演示](/demo)直接体验 API 接口能力。 diff --git a/index.md b/index.md new file mode 100644 index 0000000..67ef038 --- /dev/null +++ b/index.md @@ -0,0 +1,52 @@ +--- +title: MengStack - 企业级Go语言微服务开发框架 | 开源模块化开发底座 +layout: home + +hero: + name: MengStack + text: 企业级 Go 语言微服务开发框架 + tagline: 面向云原生与 AI 时代的一站式全栈开发底座 + actions: + - theme: brand + text: 快速开始 + link: /guide/getting-started + - theme: alt + text: 在线演示 + link: /demo + - theme: alt + text: GitHub + link: https://gitea.softunis.com/mengstack + +features: + - icon: 🧩 + title: 全栈组件化集成 + details: 内置前端模板、API 网关、分布式缓存、消息队列、定时任务等模块,生产验证,开箱即用 + link: /guide/what-is-mengstack + - icon: ⚡ + title: 零侵入依赖注入 + details: 兼容 Wire 编译时注入与 uber-go/fx 运行时管理,按需切换,兼顾性能与便捷 + link: /guide/dependency-injection + - icon: 🤖 + title: AI 原生开发支持 + details: 内置大模型调用、Agent 内存管理、向量数据库集成,快速落地智能业务场景 + - icon: 🇳 + title: 全链路国产化适配 + details: 兼容国产操作系统、数据库、中间件,满足政企金融等保合规要求 + - icon: 📚 + title: 极低学习门槛 + details: 统一代码规范与完善中文文档,新成员接入周期缩短 70% 以上 + link: /guide/getting-started + - icon: 📊 + title: 生产级可观测 + details: 内置链路追踪、指标监控、日志聚合,无需额外搭建监控体系 + - icon: 🔓 + title: 完全开源开放 + details: 核心代码 MIT 协议开源,无商业限制,社区持续迭代,可自由定制扩展 + link: /community +--- + +## 关于 MengStack + +MengStack 是面向云原生与 AI 时代的一站式全栈开发底座,整合主流开源技术能力,为开发者提供开箱即用的组件化开发体验,大幅降低中大型项目的架构搭建成本,让团队专注于核心业务逻辑落地,无需重复造轮子。 + +我们坚持全栈开源、无厂商锁定的设计理念,覆盖从前端交互、后端服务、数据治理到 AI 能力集成的全链路开发场景,适配国产化软硬件生态,为企业级项目提供稳定、高效、可扩展的技术支撑。 diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..317307c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2565 @@ +{ + "name": "website", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "website", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "vitepress": "^1.6.4", + "vue": "^3.5.43" + } + }, + "node_modules/@algolia/abtesting": { + "version": "1.25.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.25.0.tgz", + "integrity": "sha512-rSTin9Uta23uaewYVQEp8XI9T3iA/zrg0/1G2vhf8oFFDxFL5vybnZ5IQwsVAg4JpKxPX4/WYNKdcfWrZymk7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "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.59.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.59.0.tgz", + "integrity": "sha512-bm2XN0hCSMYwStSsCBT0/PUB2BDxoyR1Lnub3c392HMEy9bi8PUSW8vR6zltVEKWG2t4PQFWMD5C07bmJxGgPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.59.0.tgz", + "integrity": "sha512-XOFPOTa69WuqHR6c5tMgnUUwwqQgNSzMpxmhrgA9KmxRf8WIqEa0cokHJvohk5CYb7CZx0xeSL6Bk2IUJ7Lv7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.59.0.tgz", + "integrity": "sha512-PC8ipLOYFKRTfIUY1J3FJxS6ryzWziaXmIX9/sNMoUR8L+XhF7hX2QAeUI87YVl5zujvlYTSOb+HAIqKXDjyHQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.59.0.tgz", + "integrity": "sha512-yFNcCMM5fHiyoR0HuxMrzy+VjDcmhFUZTm2IJ2DHwGsVH3B5SEob4zTmeEZ3j/AZqNnmrJOCKl/tJnBg7+84bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.59.0.tgz", + "integrity": "sha512-GYja6HkDt2VrQhWmB2cLx3Z5fDwI9no7q+xwCWcFrTPm5CLH9QZvK0XLO9co1FcNIDxxkMaP3AXM39/XcecEOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.59.0.tgz", + "integrity": "sha512-Wofg7bMpWh8N5qDDZs0wy6whc+KMmdNsxgrIGp9Ug2s1Bka0uq7AjyckdxReKPHLA0Q1qH8X/SNh0wn2t2X2Lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.59.0.tgz", + "integrity": "sha512-fHnALZfbEnODczGk14Y/1YBRApp6UEpZUTexGcMUPzY7RDc7q4HN2Y6jh0KUG8Jo9B+q+wOoQEc3ziR0ErbuFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/ingestion": { + "version": "1.59.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.59.0.tgz", + "integrity": "sha512-Fa38s1mHgoaLCT117sfJ6P78rtxUt93CYxBYpq1VOIcslaF+cH+1h5uikAPsKfxLnsuEDZHiBiaI6eNPTsQMRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.59.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.59.0.tgz", + "integrity": "sha512-NyNsRSqM2tF1MX7ZGw/j4rduoEJiQ5wfvbSo/CFVdEzYCjyxbGFRPOZyS/GETJG9rk1TdHOq8NZqKqk/u1fm4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.59.0.tgz", + "integrity": "sha512-nXBK2uygWtvbCOffMWqqfjjcEtp9enDKY5/2Pw/Hhw8VVaOyK2ThbGK04bNX/Le+qoK1VHYkodWGVTKfw0Otkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.59.0.tgz", + "integrity": "sha512-yb+4afX/zja8QwX0KmV4/ae2kyYkRknsE79CRusYS2U5D8qwn2wq0cn1x12f3tm3F3+5FgmDdbuGdQTuCLSKMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.59.0.tgz", + "integrity": "sha512-Lp52TmpA1QtNmdHzs505Xwf4tgII7RAapkDSF9AAtWIBETcGaTIaXci4Rd9nS6SdaWK1BWTSqAPp5wzh6UN3Ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.59.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.59.0.tgz", + "integrity": "sha512-YYHLEs5rC6oRTFwT7bJaKBR9NSFzikeVHGAT1ffATmUQzR8XqyhHXjoieAUoR7fBU6I5cfy1FVeh5GoRgriuzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.59.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz", + "integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "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.98", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.98.tgz", + "integrity": "sha512-35CEBG1H/3nsohVgJaRWtOZ/P5syRTL++ZXTISdQSC76o1mAFXngFoSm9EOnnBiDApKPu8WN/DY+z69yCycL9A==", + "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.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.63.6.tgz", + "integrity": "sha512-G6xF9OVRWsbHadMfoPNUDwW/Jt70QYG+ZDUvtYCFxjf3SPhqVAO0u9ShXZ7Cf5silVoRWyN4bDjCEKnJkXkw0w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.63.6.tgz", + "integrity": "sha512-Us/kTH5e2anr1CQvO8MEq4eeCVcIXI3Ag7OFxDI30n2OW7Q7xWuxo8ItbYq28PG2Sm1NWmZzG9+SqVEaj25SFA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.63.6.tgz", + "integrity": "sha512-fwaSNrSHp9PJuEh4bKtd0mYC+G3FeVDjSTmsSiSlIYu7TFCpxrfB6lk7Ao8cIbswFyklPB1ZDUV8LkLBM15VWw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.63.6.tgz", + "integrity": "sha512-QR2tx26gCeGh4eAGnUasfnJuRc+d7Vc0Jo1/fYtKGuiKqCuhbVpbNEvqgYGBwGDZGyS04jj+zdHi9W8uvb1Sdw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.63.6.tgz", + "integrity": "sha512-7E1wRJEW8r7WlqmCy58ugndWHrzoEV/pRt2x0D9el7Inra62+Cw00lYW9XhW6iUCtFjhNw49McsSCIzJ/nG8uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.63.6.tgz", + "integrity": "sha512-13KJeF+vDswMzEHmMIouCVcEQdov3CzAA3ZhM8QFmBJV/FZ/VMZI49UHDvPXTK+wokk86kYPmQ9Qb3xGGJbZoQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.63.6.tgz", + "integrity": "sha512-hV+W1r8HM84PER4If94QuzrrD0DNk4CxobNhVUiz9ZiiWHDzJss4Jra2AYGH1a7GOTzjS1sIyZ35yYEhw/aq+g==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.63.6.tgz", + "integrity": "sha512-5dWs/GENZufRph8PEfl0TrNH/R3DHJA+VxF/dqlfV2oUZfxRtN3qmFXg2DZj8DYM8d+Vd3dgZtuVmoBE/nb2YQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.63.6.tgz", + "integrity": "sha512-inQYLPVIUvYk+s7zpxQldqwrajUNs+t4TJjPGzsdPTvsT8gsQXVcW/sQFolHZ3YSWVk0nMMwU7TtRi0Ow+QMuw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.63.6.tgz", + "integrity": "sha512-sH+0MV1HmDC1q7+bQnlN9ywKBmHqkA2EdD/hHYrrz654ybc+vNC1FRNyzuYKicMQVtZZ4X2jz0osJYmsOtnj4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.63.6.tgz", + "integrity": "sha512-mCECvRr6HGekdBc6dvHzUWubqEti4JyOqlNePrOzl4Wimk26iW5Zy9rld2mQbC9id1NYjfF8nHLFq5fr3CuOKQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.63.6.tgz", + "integrity": "sha512-bb9rdoCPwM4DEsbOP3CJgFnvhSJ3XKCUYyUhxnlSs/XGT0DknpOYgLCPbK8VUzwl+cZGzFQm0KbBYRaSGZC2YQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.63.6.tgz", + "integrity": "sha512-aIJRoGCHev45JSu7JMzVrMzu1NX3nQrXx1Vb/6y4AblxW7JpCMpk4e8C6lHzvSElxi3UEcMdFJldsuWQjV1ddA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.63.6.tgz", + "integrity": "sha512-LvjnulezHjiaM5Ga9MPCDLTVddjvcrJhZc6vEz9fxeFRGPJsPAX9HuTuPTUQ3l8d+nYpZB/xWzUpuKJlLQm3VQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.63.6.tgz", + "integrity": "sha512-YmhSBeYZwJ937s8tKpYAhms48N+tj7e+oFkbkVVxfMRdAiynK2AxqRapJXB4utyXxc/iYTkMfPRQ+7ZP0IO78w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.63.6.tgz", + "integrity": "sha512-9+YukhzqTvJvzfDXJJzkURK9TDY01nofNH3pyHGuucGC4xPvBVtIfCAqJjkjnmBEGJYNXB8sBc2EDt7xDgGenw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.63.6.tgz", + "integrity": "sha512-9G5AtEkpN/A89BILHHEL9aYRYTuFjwa8PUQqoEg8SDrwOZBKpwYqNlQCBNI5QPwGrf7qFlb6LNFilo8FCSA3Wg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.63.6.tgz", + "integrity": "sha512-Ezx2E5D6Siz805j41x91JiGbzuCm8i2U98U37SQ7ytY737+wsJq+P9nPL6UmqDww491zO7MTivYOTrtmTTeCSw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.63.6.tgz", + "integrity": "sha512-8EZ1Q3PB7yUjvR4MbFAnCBF1wF0XRe5QQqbtlJXP7ZX5C8iYlSQJugUhj9oS0gbUP4jp9qGhaIgFnV9Nvod86Q==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.63.6.tgz", + "integrity": "sha512-3JI27TALItfZ/qaxXKdbRXfV6WepUoUa3IN07FE+1xxoRdl3JIyrp5PiDF0vOHsPgEiOFkF8s3B3BRymQkdwGA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.63.6.tgz", + "integrity": "sha512-BNOGeNFNRZDT7Hfc7b9JbTZFXkpAXeXl/CZWtxdd5CNfBaor/0RkJjg+q+E2gwVIvGqqp/NclThKFGrhuScVhw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.63.6.tgz", + "integrity": "sha512-D3eEyLSIim5WF5fHbwnx+ryk0delN7fJyBrDTO3wVCCNBZ/cA8aCGwLS3SiuK+vRI4E7dqikAlStGuR20dBMuw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.63.6.tgz", + "integrity": "sha512-xwbs9g8zLbHzj1poG1uh27xtubsu27Gk2nuN6kvvGDybjiTfwMksQAnF+phlvI5oeXkJWWDc6kg1t3XpgUYvrg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.63.6.tgz", + "integrity": "sha512-Tr6rhRNnFthvXr45zWVZQ5P8jZ5UwZnXNc7Qnu80cP/VVYtSioOPmvv7wP6UMgRfkBCJr2Pm60ua0YBDSJjgnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.63.6", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.63.6.tgz", + "integrity": "sha512-0RAxO1pS/6lY1mSoD2Apm+6aPyfUlm+OWKgncIdj/eVN9I+pDY3lKgD7xsUNFei1u7MZQETGOo6m8POXMDp53A==", + "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.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/hast": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "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.2.0", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.2.0.tgz", + "integrity": "sha512-NoQ2yGlLWj4wpxMs+TYmRKk3thDrQ97agr7sFqfLsAlvoS8SNQuTrlObhFqG9iugdTtgOE9jpJ6FNM4ZGsa5xQ==", + "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.4.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", + "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", + "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.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.43.tgz", + "integrity": "sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@vue/shared": "3.5.43", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.43.tgz", + "integrity": "sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.43", + "@vue/shared": "3.5.43" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.43.tgz", + "integrity": "sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.8", + "@vue/compiler-core": "3.5.43", + "@vue/compiler-dom": "3.5.43", + "@vue/compiler-ssr": "3.5.43", + "@vue/shared": "3.5.43", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.28", + "source-map-js": "^1.2.1" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.43.tgz", + "integrity": "sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.43", + "@vue/shared": "3.5.43" + } + }, + "node_modules/@vue/devtools-api": { + "version": "7.7.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.10.tgz", + "integrity": "sha512-KxtEpUOOpFz/qOGRrAwA36QF7DqIA+FXgCYit9mk9wjbaZt0sXOFz81ElOZtKA4HbWHUdwNjZHBFsFFyp5BZiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.7.10" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.7.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.10.tgz", + "integrity": "sha512-3WNi2Kq4tbpVbmhml7RiphmAt0279oh3fKNeWMQIrltfX8Q91b4i5PL8DtyNKdwmcsGrV4fg+erwWOmD05CLIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.7.10", + "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.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.10.tgz", + "integrity": "sha512-wOPslzB8vTvpxwdaOcR2qAbwmuSP0L+rhpoC6Cf56V3Jip+HWb7PQQXOUPgBNQARpXsbQX/+mvi8kKucmBGRwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.43.tgz", + "integrity": "sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.43" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.43.tgz", + "integrity": "sha512-hU6U6VnVhBGQDpvlnnDlIB8ZGJBiOcgk2lh/0InltHiz3D8oSkluvuvY+do1G2H3+udeKFsmaBlgVYP7gXQzEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.43", + "@vue/shared": "3.5.43" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.43.tgz", + "integrity": "sha512-Bb2Jc0YjjJdMt1SJmb9b2L/IWd3I8lIT9x9eS/xvvP9CiVgna0ffua74xKRmt4/uSJ+0r4iN8ex1jrqkhQGWQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.43", + "@vue/runtime-core": "3.5.43", + "@vue/shared": "3.5.43", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.43.tgz", + "integrity": "sha512-l2Ygjv9NehV94PSBxNWsAHC0j/eIIKbn92mBuWXAPGLnn6HfJ6MH5ubsd+Nk0YoZ5FRuxWI1P2VSoh+dbPQhCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.43", + "@vue/runtime-dom": "3.5.43", + "@vue/shared": "3.5.43" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.43", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.43.tgz", + "integrity": "sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==", + "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.59.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.59.0.tgz", + "integrity": "sha512-wUXzaeI7B526W4y1gFg3lcxgDZ67XSgRJIiellYWOas/pLpO7rOtxm9Gr2E/C8aiSDXIgx1q5TdSsvK67Uakqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.25.0", + "@algolia/client-abtesting": "5.59.0", + "@algolia/client-analytics": "5.59.0", + "@algolia/client-common": "5.59.0", + "@algolia/client-insights": "5.59.0", + "@algolia/client-personalization": "5.59.0", + "@algolia/client-query-suggestions": "5.59.0", + "@algolia/client-search": "5.59.0", + "@algolia/ingestion": "1.59.0", + "@algolia/monitoring": "1.59.0", + "@algolia/recommend": "5.59.0", + "@algolia/requester-browser-xhr": "5.59.0", + "@algolia/requester-fetch": "5.59.0", + "@algolia/requester-node-http": "5.59.0" + }, + "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.1.5", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.1.5.tgz", + "integrity": "sha512-vePst2VLTSqPglW7Q98VwFpGiGpOHTyXIo81MO5VyLecA5zMbZw/P/V1vmwD1jksa2iJpn/YkDrJ3XhTfzUyhQ==", + "dev": true, + "license": "MIT", + "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/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.3", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", + "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", + "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.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "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.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "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.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/preact": { + "version": "10.29.8", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.8.tgz", + "integrity": "sha512-ej2aVZ+vZ8WO7tvlQWRM9N63A0KzF9q4mWJfDUHgYaIofWY9hu74QdnQrjoPMmZi2/nZ5gN0bJCQF49xQqx09Q==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "peerDependencies": { + "preact-render-to-string": ">=5" + }, + "peerDependenciesMeta": { + "preact-render-to-string": { + "optional": true + } + } + }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "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.63.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.63.6.tgz", + "integrity": "sha512-w4+GKyTBqshj84F1GF3s2zxAPFZPEmNkCbQtqilsYS7GsksmX6VoV7UggfZg8sUHCCOkBe7UtQp6fZwbH311FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@rollup/rollup-android-arm-eabi": "4.63.6", + "@rollup/rollup-android-arm64": "4.63.6", + "@rollup/rollup-darwin-arm64": "4.63.6", + "@rollup/rollup-darwin-x64": "4.63.6", + "@rollup/rollup-freebsd-arm64": "4.63.6", + "@rollup/rollup-freebsd-x64": "4.63.6", + "@rollup/rollup-linux-arm-gnueabihf": "4.63.6", + "@rollup/rollup-linux-arm-musleabihf": "4.63.6", + "@rollup/rollup-linux-arm64-gnu": "4.63.6", + "@rollup/rollup-linux-arm64-musl": "4.63.6", + "@rollup/rollup-linux-loong64-gnu": "4.63.6", + "@rollup/rollup-linux-loong64-musl": "4.63.6", + "@rollup/rollup-linux-ppc64-gnu": "4.63.6", + "@rollup/rollup-linux-ppc64-musl": "4.63.6", + "@rollup/rollup-linux-riscv64-gnu": "4.63.6", + "@rollup/rollup-linux-riscv64-musl": "4.63.6", + "@rollup/rollup-linux-s390x-gnu": "4.63.6", + "@rollup/rollup-linux-x64-gnu": "4.63.6", + "@rollup/rollup-linux-x64-musl": "4.63.6", + "@rollup/rollup-openbsd-x64": "4.63.6", + "@rollup/rollup-openharmony-arm64": "4.63.6", + "@rollup/rollup-win32-arm64-msvc": "4.63.6", + "@rollup/rollup-win32-ia32-msvc": "4.63.6", + "@rollup/rollup-win32-x64-gnu": "4.63.6", + "@rollup/rollup-win32-x64-msvc": "4.63.6", + "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.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "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.5.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.5.0.tgz", + "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==", + "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.43", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.43.tgz", + "integrity": "sha512-o5qZoksdnjIKvW1srZ3ab7pcDNYAerBjRe54D0LBLfRdCYFrSgBHVXokMas35czQc0//lmx4/tuY4ZNQ+Rf2Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.43", + "@vue/compiler-sfc": "3.5.43", + "@vue/runtime-dom": "3.5.43", + "@vue/server-renderer": "3.5.43", + "@vue/shared": "3.5.43" + }, + "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 new file mode 100644 index 0000000..ea05dac --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "mengstack-website", + "version": "0.1.0", + "description": "MengStack 官方网站", + "scripts": { + "dev": "vitepress dev", + "build": "vitepress build", + "preview": "vitepress preview" + }, + "keywords": ["mengstack", "golang", "framework"], + "author": "SoftUnis", + "license": "MIT", + "type": "module", + "devDependencies": { + "vitepress": "^1.6.4", + "vue": "^3.5.43" + } +} diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000..937c515 Binary files /dev/null and b/public/favicon.png differ diff --git a/public/logo-dark.png b/public/logo-dark.png new file mode 100644 index 0000000..0c33fa3 Binary files /dev/null and b/public/logo-dark.png differ diff --git a/public/logo-hero.png b/public/logo-hero.png new file mode 100644 index 0000000..1455745 Binary files /dev/null and b/public/logo-hero.png differ diff --git a/public/logo-light.png b/public/logo-light.png new file mode 100644 index 0000000..937c515 Binary files /dev/null and b/public/logo-light.png differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..379f868 Binary files /dev/null and b/public/logo.png differ diff --git a/public/og-image.png b/public/og-image.png new file mode 100644 index 0000000..e76ccdd Binary files /dev/null and b/public/og-image.png differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..c463d03 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / +Disallow: /404.html +Sitemap: https://mengstack.softunis.com/sitemap.xml diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000..5cb6158 --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1,111 @@ + + + + https://mengstack.softunis.com/ + 2026-10-02 + weekly + 1.0 + + + https://mengstack.softunis.com/guide/what-is-mengstack.html + 2026-10-02 + monthly + 0.9 + + + https://mengstack.softunis.com/guide/getting-started.html + 2026-10-02 + monthly + 0.9 + + + https://mengstack.softunis.com/guide/project-structure.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/architecture.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/module-pattern.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/dependency-injection.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/auth.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/multi-tenancy.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/configuration.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/docker-deploy.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/guide/cicd.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/api/overview.html + 2026-10-02 + monthly + 0.9 + + + https://mengstack.softunis.com/api/auth.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/api/system.html + 2026-10-02 + monthly + 0.8 + + + https://mengstack.softunis.com/changelog.html + 2026-10-02 + weekly + 0.8 + + + https://mengstack.softunis.com/demo.html + 2026-10-02 + monthly + 0.7 + + + https://mengstack.softunis.com/community.html + 2026-10-02 + monthly + 0.7 + +