commit fe63dacae2cd038cf388290cd9cff4d751e2b291 Author: 技小云 Date: Wed Nov 4 11:08:47 2026 +0800 feat: 开源项目门户站首版(iotLCM / 秀杰 DTU / XiuAdmin 三项目,注册表驱动) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..51ccdbb --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +node_modules +.vitepress/cache +.vitepress/dist +.vitepress/.temp +dist +*.log diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..5e4086a --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmmirror.com/ diff --git a/.vitepress/config.mts b/.vitepress/config.mts new file mode 100644 index 0000000..c654dff --- /dev/null +++ b/.vitepress/config.mts @@ -0,0 +1,74 @@ +import { defineConfig } from 'vitepress' +import { projects } from '../data/projects' + +/** + * 门户站构建配置 + * + * SITE_BASE 由构建参数注入: + * - /www/ 过渡形态:挂在已有网关的 /www/ 路径下(没有独立域名时用) + * - / 独立域名形态:站点独占域名根路径 + * 两者内容完全同源,只有资源前缀与路由前缀不同,所以用构建参数而不是改代码。 + */ +const SITE_BASE = process.env.SITE_BASE ?? '/www/' + +/** 代码仓组织(雪羊科技企业仓) */ +const ORG_URL = process.env.ORG_URL ?? 'https://gitee.com/snowgoat' + +/** 各项目的文档站地址(按项目 id 覆盖) */ +const DOCS_URL: Record = { + iotlcm: 'http://open.5iot.com:5051/docs/', +} + +export default defineConfig({ + srcDir: './pages', + base: SITE_BASE, + title: '雪羊科技开源', + description: '雪羊科技开源项目门户:物联网卡管理、DTU 设备管理、中后台开发框架', + lang: 'zh-CN', + cleanUrls: true, + lastUpdated: false, + head: [ + ['link', { rel: 'icon', type: 'image/svg+xml', href: `${SITE_BASE}favicon.svg` }], + ], + themeConfig: { + nav: [ + { text: '首页', link: '/' }, + { text: '项目', link: '/projects/' }, + { text: '关于', link: '/about' }, + ], + sidebar: { + '/projects/': [ + { + text: '项目', + collapsed: false, + items: projects.map((p) => ({ text: p.name, link: p.page })), + }, + ], + '/guide/': [ + { + text: '门户', + collapsed: false, + items: [{ text: '门户部署', link: '/guide/portal-deploy' }], + }, + ], + }, + socialLinks: [ + { icon: 'github', link: ORG_URL }, + ], + footer: { + message: '雪羊科技开源 · Apache-2.0', + copyright: 'Copyright © 雪羊科技', + }, + search: { + provider: 'local', + }, + outline: { + level: [2, 3], + label: '本页目录', + }, + docFooter: { + prev: '上一页', + next: '下一页', + }, + }, +}) diff --git a/.vitepress/theme/components/ProjectCard.vue b/.vitepress/theme/components/ProjectCard.vue new file mode 100644 index 0000000..a3744cc --- /dev/null +++ b/.vitepress/theme/components/ProjectCard.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/.vitepress/theme/components/ProjectList.vue b/.vitepress/theme/components/ProjectList.vue new file mode 100644 index 0000000..a39caf6 --- /dev/null +++ b/.vitepress/theme/components/ProjectList.vue @@ -0,0 +1,19 @@ + + + + + diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts new file mode 100644 index 0000000..b27d346 --- /dev/null +++ b/.vitepress/theme/index.ts @@ -0,0 +1,11 @@ +import DefaultTheme from 'vitepress/theme' +import type { Theme } from 'vitepress' + +import ProjectList from './components/ProjectList.vue' + +export default { + extends: DefaultTheme, + enhanceApp({ app }) { + app.component('ProjectList', ProjectList) + }, +} satisfies Theme diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e2088a6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +# 开源项目门户(VitePress)构建镜像 +# +# 构建参数: +# SITE_BASE —— 站点资源前缀,同时决定容器内 nginx 的形态: +# /www/ 过渡形态:挂在已有网关的 /www/ 路径下(没有独立域名时用) +# / 独立域名形态:站点独占域名根路径 +# +# 前缀与 nginx 形态必须配套:VitePress 产物里的资源引用是绝对路径 +# (assets/xxx),base=/www/ 时只能由带 alias 的 location 提供服务; +# base=/ 时只能由根路径 location 提供服务。混用会出现「页面 200 但 JS/CSS 全 404」。 +# +# 用法(仓库根目录): +# docker build -t snowgoat-open-portal:dev --build-arg SITE_BASE=/www/ . +FROM node:22-alpine AS builder + +ARG SITE_BASE=/www/ + +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ + && apk add --no-cache git + +WORKDIR /app + +COPY package*.json .npmrc ./ +RUN npm ci + +COPY . . +RUN SITE_BASE=${SITE_BASE} npm run build + +FROM nginx:1.27-alpine + +ARG SITE_BASE=/www/ + +COPY --from=builder /app/.vitepress/dist /usr/share/nginx/html +COPY docker/nginx.root.conf /etc/nginx/conf.d/default.conf +COPY docker/nginx.prefix.conf /tmp/nginx.prefix.conf +RUN set -eu; \ + base="${SITE_BASE%/}"; \ + if [ "$base" = "" ]; then \ + echo "门户形态:独立域名(根路径)"; \ + else \ + sed -e "s|__SITE_BASE__|${SITE_BASE}|g" -e "s|__SITE_BASE_NO_SLASH__|${base}|g" \ + /tmp/nginx.prefix.conf > /etc/nginx/conf.d/default.conf; \ + echo "门户形态:子路径 ${SITE_BASE}"; \ + fi + +EXPOSE 80 diff --git a/README.md b/README.md new file mode 100644 index 0000000..ded9ab4 --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# 雪羊科技开源项目门户 + +开源项目门户站源码。当前收录 **iotLCM**(物联网卡全生命周期管理平台)、**秀杰 DTU 管理平台**、**XiuAdmin**(中后台开发框架)。 + +- 站点框架:VitePress 1.6(与 iotLCM 的文档站同构) +- 产物:纯静态文件 +- 许可:Apache-2.0 + +## 目录 + +```text +. +├── data/projects.ts # 项目注册表 —— 门户唯一项目清单来源 +├── pages/ +│ ├── index.md # 门户首页 +│ ├── projects/index.md # 全部项目 +│ ├── projects//index.md # 各项目详情页 +│ ├── guide/portal-deploy.md # 门户自身的构建与部署 +│ └── about.md # 关于、许可、贡献说明 +├── .vitepress/theme/components/ # 项目卡片与列表组件 +├── scripts/check-registry.mjs # 注册表与详情页一致性校验 +├── deploy/docker-compose.yml # 容器部署编排 +└── Dockerfile # 多阶段构建镜像 +``` + +## 新增一个项目 + +两步,不需要改动站点其它部分: + +1. 在 `data/projects.ts` 里加一条记录(名称、定位、说明、代码仓、许可证、技术栈、状态、详情页路径、子页面) +2. 写 `pages/projects//index.md` 详情页 + +首页卡片、项目列表页、侧边栏都会自动带上新项目。 + +构建前会自动校验注册表与详情页目录是否一一对应,不一致直接报错: + +```bash +npm run check +``` + +## 本地开发 + +```bash +npm ci +npm run dev # http://127.0.0.1:5173 +``` + +## 构建 + +```bash +npm run build # 产物在 .vitepress/dist/ +``` + +## 部署 + +```bash +docker compose -f deploy/docker-compose.yml up -d --build +``` + +默认发布在宿主机 `127.0.0.1:8020`。站点资源前缀由 `SITE_BASE` 决定: + +| 形态 | 参数 | 访问方式 | +| --- | --- | --- | +| 子路径(过渡,无独立域名) | `/www/`(默认) | 由已有网关转发 `/www/` 到本容器 | +| 独立域名 | `/` | 域名根路径 | + +```bash +SITE_BASE=/ docker compose -f deploy/docker-compose.yml up -d --build +``` + +详见 [门户部署](pages/guide/portal-deploy.md)。 diff --git a/data/projects.ts b/data/projects.ts new file mode 100644 index 0000000..591d52d --- /dev/null +++ b/data/projects.ts @@ -0,0 +1,88 @@ +/** + * 开源项目注册表 —— 门户的唯一项目清单来源。 + * + * 新增一个项目只需两步: + * 1) 在这里加一条记录 + * 2) 写 pages/projects//index.md 详情页,并在 sections 里登记它的子页面 + * 首页卡片、项目列表、侧边栏、导航都会自动带上,不需要改任何其它文件。 + * 校验:npm run check(构建前自动执行,详情页与注册表不一致会直接报错) + */ + +export type ProjectStatus = '已发布' | '公测中' | '开发中' + +export interface ProjectSection { + text: string + link: string +} + +export interface Project { + /** 目录名与 URL 片段,一经发布不再改动(改名会断链) */ + id: string + name: string + /** 一句话定位,展示在卡片标题下 */ + tagline: string + /** 两三句说明,展示在卡片正文 */ + summary: string + /** 开源代码仓 */ + repo: string + /** 许可证标识 */ + license: string + /** 技术栈标签 */ + tech: string[] + status: ProjectStatus + /** 门户内的详情页路径 */ + page: string + /** 详情页下的子页面(快速开始、部署、教程等) */ + sections: ProjectSection[] +} + +export const projects: Project[] = [ + { + id: 'iotlcm', + name: 'iotLCM', + tagline: '物联网卡全生命周期管理平台', + summary: + '卡片从运营商渠道入库 → 划拨给代理商 → 激活 / 续费 / 停机 → 流量与状态同步 → 销户,一个平台覆盖 SIM 卡管理全程。内置中国移动 OneLink、中国电信 5G CMP、中国联通 10646 协议适配,并支持以共享 Token 模式接入多家三方渠道商。', + repo: 'https://gitee.com/snowgoat/iotlcm', + license: 'Apache-2.0', + tech: ['GoFrame v2', 'Vue 3', 'MySQL', 'RabbitMQ', 'TDengine', 'Docker Compose'], + status: '已发布', + page: '/projects/iotlcm/', + sections: [ + { text: '快速开始', link: '/projects/iotlcm/guide/quickstart' }, + { text: '部署与运维', link: '/projects/iotlcm/guide/deploy' }, + { text: '教程视频', link: '/projects/iotlcm/guide/tutorial' }, + ], + }, + { + id: 'xiu-dtu', + name: '秀杰 DTU 管理平台', + tagline: 'DTU 设备全生命周期管理平台', + summary: + '面向 DTU(数据传输单元)设备,覆盖设备生产、出厂、代理商划拨、终端客户绑定、配置下发、固件 OTA 升级、指令下发与运行监控的完整闭环,HTTP / TCP 双通道接入。', + repo: 'https://gitee.com/snowgoat/xiu-dtu', + license: 'Apache-2.0', + tech: ['GoFrame v2', 'Vue 3 + Vben Admin', 'MySQL', 'Redis', 'asynq', 'VitePress'], + status: '已发布', + page: '/projects/xiu-dtu/', + sections: [], + }, + { + id: 'xiu-admin', + name: 'XiuAdmin', + tagline: 'GoFrame + Vue3 的全栖中后台框架', + summary: + '高生产率、可扩展、应用化 / 模块化 / 插件化的中后台开发框架。租户、用户、部门、菜单、角色、代码生成、定时任务、消息队列、通知公告等 22 项内置功能开箱可用。', + repo: 'https://gitee.com/snowgoat/xiu-admin', + license: 'Apache-2.0', + tech: ['GoFrame v2', 'Vue 3 + Vben Admin', 'Ant Design Vue', 'asynq'], + status: '已发布', + page: '/projects/xiu-admin/', + sections: [], + }, +] + +/** 按 id 取项目,找不到返回 undefined */ +export function projectById(id: string): Project | undefined { + return projects.find((p) => p.id === id) +} diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..9ec36c4 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,35 @@ +# 门户部署 + +## 启动 + +```bash +docker compose -f deploy/docker-compose.yml up -d --build +``` + +默认发布在宿主机 `127.0.0.1:8020`(用 `PORTAL_PORT` 改端口)。 + +## 两种形态 + +构建参数 `SITE_BASE` 决定站点资源前缀,同时决定容器内 nginx 的形态: + +| 形态 | 参数 | 访问方式 | +| --- | --- | --- | +| 子路径(过渡,无独立域名) | `/www/`(默认) | 由已有网关转发 `/www/` 到本容器 | +| 独立域名 | `/` | 域名根路径,如 `https://<门户域名>/` | + +```bash +SITE_BASE=/ docker compose -f deploy/docker-compose.yml up -d --build +``` + +内容同源,切换只改构建参数与入口配置,页面不用改。 + +> VitePress 产物里的资源引用是绝对路径(`assets/xxx`),base 与 nginx 的 location 形态必须配套, +> 混用会出现「页面 200 但 JS/CSS 全 404」的白屏。镜像构建脚本按 `SITE_BASE` 自动选对应配置。 + +## 校验 + +门户项目清单与详情页的一致性在构建前自动校验: + +```bash +npm run check +``` diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..cc6dc52 --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,27 @@ +# 开源项目门户部署编排 +# +# docker compose -f deploy/docker-compose.yml up -d --build +# +# 形态切换(站点资源前缀): +# SITE_BASE=/www/ 子路径形态,挂在已有网关的 /www/ 路径下(默认) +# SITE_BASE=/ 独立域名形态,站点独占域名根路径 +# +# SITE_BASE=/ docker compose -f deploy/docker-compose.yml up -d --build +services: + portal: + build: + context: .. + dockerfile: Dockerfile + args: + SITE_BASE: '${SITE_BASE:-/www/}' + image: snowgoat-open-portal:local + container_name: snowgoat-open-portal + restart: unless-stopped + ports: + - "127.0.0.1:${PORTAL_PORT:-8020}:80" + healthcheck: + test: ["CMD", "wget", "--quiet", "--output-document=/dev/null", "http://127.0.0.1${SITE_BASE:-/www/}"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s diff --git a/docker/nginx.prefix.conf b/docker/nginx.prefix.conf new file mode 100644 index 0000000..c14384c --- /dev/null +++ b/docker/nginx.prefix.conf @@ -0,0 +1,24 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # 过渡形态:站点挂在统一网关的子路径下(没有独立域名时用)。 + # + # VitePress 产物里的资源引用是绝对路径(assets/xxx), + # 而 dist 目录是平铺的(index.html、assets/ 直接在根)。 + # 因此必须在子路径下用 alias 把前缀剥掉再落到产物目录, + # 否则页面能返回 200 但 JS/CSS 全部 404 → 白屏。 + # 网关侧对应 location ^~ { proxy_pass http://gw_website; }(不剥前缀)。 + location __SITE_BASE__ { + alias /usr/share/nginx/html/; + try_files $uri $uri.html $uri/ $uri/index.html =404; + } + + # 访问不带尾斜杠的前缀时补斜杠,否则相对资源路径会解析错 + location = __SITE_BASE_NO_SLASH__ { + return 301 __SITE_BASE__; + } +} diff --git a/docker/nginx.root.conf b/docker/nginx.root.conf new file mode 100644 index 0000000..dc0358c --- /dev/null +++ b/docker/nginx.root.conf @@ -0,0 +1,12 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + # 独立域名形态:站点独占域名根路径,产物平铺在根目录。 + location / { + try_files $uri $uri.html $uri/ =404; + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e729a3b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2534 @@ +{ + "name": "snowgoat-open-portal", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "snowgoat-open-portal", + "devDependencies": { + "vitepress": "^1.6.4" + } + }, + "node_modules/@algolia/abtesting": { + "version": "1.27.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.27.0.tgz", + "integrity": "sha512-XXm0DTCmSzHT40mn0Hs8H00pBcuaqQET0BsWfaHrQdijNfrhSZPLueGVQvYAeSeXVuS420arotSfgqY25nFNbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.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.61.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.61.0.tgz", + "integrity": "sha512-NSq61VNhN63nstgbEh2YzygmtybxPnBdFwmjPOa7laJp8RapLrkqwHUaI4ELCyuZMhcuRlUvOL25y+SDVkgnsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.61.0.tgz", + "integrity": "sha512-WBMStmOLas4bWHh0rgOOb8iTQL07fsfPwvEW2vrQL+5v2KWMcRix9cYSQp3SOGjdweNjUszbGO84VBBMHBnHbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.61.0.tgz", + "integrity": "sha512-mzrW0KkEiZHB09cU2Sh2vyxUGSi9fVoglCeKnf3wJ3ixo+7ilHH64wLK45eSoX13+CVXA2KTjZJGcEmBS3Z57Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-insights": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.61.0.tgz", + "integrity": "sha512-TseZAUL8ZUtKQY6MQbJR/Qw9OSf54s9gvcDtQ7GZX9miZD1e24E1/usa1lGrrgq5KDpgQ8+ePCQIITFcq0Y56Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-personalization": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.61.0.tgz", + "integrity": "sha512-4CBpVN2WDVLocAzMU8me5UHWSbf6oXI7KDy3K0pL/8i0eB1+nOMQBU7jmUL6kBl2XMoYAu6tnsZmxpZ59b+Y2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.61.0.tgz", + "integrity": "sha512-PU2XREmx7DdZ6SjuuaM+ZwhfMFOUPXjLeUYyvxTFA8oz06yrY/wcn5V/UOMv01rdeTuG2petMZLzTJADF9KyEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.61.0.tgz", + "integrity": "sha512-npseUJ0UwaiwU4XbKyHiFcZbrS1AbLszbPRxi3W9YUrrqdpvfSeGKMlLv63haH4PZsCog5wG40lJGKXbnrDAEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/ingestion": { + "version": "1.61.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.61.0.tgz", + "integrity": "sha512-rA/W43fD2qQemeQ2/uix/KSEUdikY55RTmgbfBRoF9HjCJ/zryD9RAKJXWxBlFXRBg9q8EPPYH3GlSXcRHnpgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/monitoring": { + "version": "1.61.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.61.0.tgz", + "integrity": "sha512-3CEPgD95sBitQVQsPXmIfMkcX0Kh12d5wmI7iOm1yrllPBu4Vx30Q2xMv9wyHm2C2bHQwz+KPBohtq6Hh1K5eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/recommend": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.61.0.tgz", + "integrity": "sha512-2pCOG8rRFW+0OeUmNUMoRH5xXktCEdUqtjuz6FCFQa1lxqPIUBr4HHIneXTIuAgUC0ckokqBCZk0v5qU7DvBuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.61.0.tgz", + "integrity": "sha512-7Y7P6Kp+7DQkrOCzmIYjoCpLPQoA8vlxcIzyjpfMrokBNX0LIQSPyR5JY/EdSzCN6CvNlYGJ5SiO7j6lZad5Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-fetch": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.61.0.tgz", + "integrity": "sha512-WNTNQcrWcGAgLDU3+6IFWs3QPosMCYSlwlPEdEO2ivLnlm8u5HtGQvOz/JnY9d2bhofDBL+S5wdtm9+Uob+dsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@algolia/requester-node-http": { + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.61.0.tgz", + "integrity": "sha512-CA+6MlgPkjSlGQpx+rLBSnHFy8pyYpGEjs7Yp0kVzOC6RM5jq99Z4KGOuplcNZBjQlM521t0nEvKLxFOv2NSZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.61.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.11", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.11.tgz", + "integrity": "sha512-snZbO7MEDOof+hvNa97EjEY7qD7h2kwvQr5AJC3ZhQudKW5dnej6k3kP9NQV88hJwaS8vDqRLFo9rivLEhle2g==", + "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.12", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.12.tgz", + "integrity": "sha512-WJ7JBp/Q4+z/ImydtI7jS6NVco5++632ExBemSX+Ysb+G1lCwQ5BVo3SY+jGGOcZXI4ZccbZSUSJLNBW6eEpJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.11" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.11", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.11.tgz", + "integrity": "sha512-WCsemW40Cpc6gouC1SrY6PBaZ+oLRlEVY9XBvZBI7il/HyUrb2nJ505wE1MHEFyDZNnrWDEuy4jL50WVHfTTSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.11", + "@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.101", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.101.tgz", + "integrity": "sha512-MXJkMZDancJ/9I+Bgdthi9kXvn3AwWStxoTHwEPwAFQ9kMLBASO1BSstg52fNtjXeizm1Wi91R+QnWxNGkWHPQ==", + "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, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.67.4.tgz", + "integrity": "sha512-/v/pUAPOcwp+r1Hjjdg0cBV1TE89CzGKrKh2FgkIQw2QBcIMmVPOCSfuOZStCn4Xh/98HXfo/ht6ztcssctPNg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.67.4.tgz", + "integrity": "sha512-6tmmB/P52Vt167FXXEw5auiEUgTtZz7aqUgWHqYXToIUE0HFDY6fTdAyeekjjsNk6O/8dtpSKtClxSj1mMneKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-x64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-x64/-/rollup-android-x64-4.67.4.tgz", + "integrity": "sha512-8Z9Q4RmotVmuL4llOvqX814JNiOK1oqoBv+glG5KbpRfUiypqzz2/fxIzK4Pq129l4dT5a8Gszmpc0/XPYoFuQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.67.4.tgz", + "integrity": "sha512-pnq6hssxTtwuRAl6Kdi/+IDY+b1IhkUetjhUkdLAAJCssjfqtL2Oqy/FXJVJFtAWOu1oRlArIvf0Yk1O92x2HQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.67.4.tgz", + "integrity": "sha512-BeIrGZvHMVdJg/N+ohZfFywG/gF41684YhDj2wBvouj7m9ziP1tZDUNwzXRiDY+3WIKngaC4hiUBqVtBPGP5og==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.67.4.tgz", + "integrity": "sha512-fRFX/oqNg/g780DKoS8RIfYcZD59Ru5O/bSeK1N7gQljBFrTxJY/q5EX4eMs5SrJf32VgVBVVYCdfPpzAwPPnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.67.4.tgz", + "integrity": "sha512-bSrBRopG1q+0RuOsW0NtYTtIODlvNA3T3ebx5WnQVdSxWIoXFmj+rZdHUHdSLgFdZ5M6VGmekYE7r4RMGQXjfg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.67.4.tgz", + "integrity": "sha512-L8IvdrJVtl65g1ozwDSyjGPG+FmibhCdFUwmqTItJLw0S3+Oj4QzFs7rfgTUiK7rsPjkCLdG1/GApFxoynXFJQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.67.4.tgz", + "integrity": "sha512-h7PcoQOzC31jshNpQ48J0akB9tsghjkSjSl5AZ6XsVGTxVsln7t7C4SQyw62tNVSaz2SeHgk4VT2ELbL17BSHQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.67.4.tgz", + "integrity": "sha512-KSPuOBNHoOl7AsVjeY1KZci8+0up0U4TFAHU5IzBYN8P+Z6cB9DZq28+JQycZW7f6WLLa/tSzhV7Rdy95bVi+g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.67.4.tgz", + "integrity": "sha512-0E/mKmVk1PlQeQYygIwQm0jlwjANTzGSiNBMPrFx+rdFGFj/2Axh4p6XwcrystQIqXZVudTaGsdbDpzYgJ4wSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.67.4.tgz", + "integrity": "sha512-Fvw7dOSc2Sa9UOipRZVI0zOgdLCzsjVyD/6JuHXzUHTXFu7mMgmeX/0/bCVBIut1dz+nWz3pV4WpS/Qg0XVnxw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.67.4.tgz", + "integrity": "sha512-jzxbVHaE7V3F+P0wEK7UydQtvv7Twfdtx58jI5/3VRx1jJxyrn+qFwfXmqjVFxPhBl+zjaRs+ZJMFJw7vdHaQA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.67.4.tgz", + "integrity": "sha512-fhtrzp9p4GjEJVaigaap9g6X9nP6xgJtKiLLXSDgpE18HXufA5aqfltGn+KAqMtVZReJZfOrXm//y5YSA9BWbA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.67.4.tgz", + "integrity": "sha512-uynaF7IUHwAckV0S+yC1f5esy9gB+aqCBsPH5BOck32TYdCuAn2lVG5tvUcFnEsrviGEmRZxE1NHSOieUPYJEg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.67.4.tgz", + "integrity": "sha512-uaqRFdfb8eIa2bVHN/FE3ndCvR0zV2xv0AwjCfxrqSu6l6fp/54VhjfhslKlf2RIik9L1jwlt4E56PeVX6tQtQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.67.4.tgz", + "integrity": "sha512-JZRow7kmxUDEASnxHuVG5itTm+nTXi9BQUABcVUnUEngC+OPwMrpx1uJ9hIA/v+IcAEBL52ktCSPXk5OJn9Jqg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.67.4.tgz", + "integrity": "sha512-rdrh4e+Lq9fCNKoDPaCqeHXbQCe7yl77Ukl45tlSClwYdZ1gpFGZz1XLJdYtY++FRlfL5aHvb6/0n3GDW/Nxsw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.67.4.tgz", + "integrity": "sha512-wL7MS4r0fYcxluF3ne2plofHZiB/LsqNCnyaUlyiKpAJLb6agPSFz7DEFCfkonWAZXMrLwCmC08b2ZEnEdJkog==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.67.4.tgz", + "integrity": "sha512-4H0XHfd2VufGjX7NjUyeue78sD0bRIoKSGjGqO+F5nSvL6jN48NAU7esdmtFEYxZXwObLtt3MJ/kHS0jASMW3g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.67.4.tgz", + "integrity": "sha512-osRHQbE55pZpCLetpMsFmhkapyZnAUH73qRKMh+npi3boUom6u6hdaTTPSxlInXxwJHsn9r2uDhdz0V7Yoxx2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.67.4.tgz", + "integrity": "sha512-95+exYEyOwrZePsE0czi4q7X5lxKPa21+lmyAZlwbYENITQ0Unk4HAQAFp/p+KhXBHBx9mUABXRYjOC5A1wY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.67.4.tgz", + "integrity": "sha512-FOXOcKhNQpO4Po+Ynan6IbtM67SrXZbgpRJWVYwz53CT5veI7sVzDwVBmWS65N5Imv+wK3SVhIPAl+C5DXXNCg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.67.4.tgz", + "integrity": "sha512-cklKh0gJOkAZQcWziQa3hrjxZKN+PCHZ7SPTyGJDAiBVr05ZXlEjGFCG7zFJMaVibxsmzAe1FimN4u/HBns9+Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.67.4.tgz", + "integrity": "sha512-AegwxJPc9bvUp8fQtlsUHkFMOMkGylWU7glyL+YD4vwG+QaYoGXYLSsQoeTD7kvoLZrVlMWNVhTg1dedY5C1VQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.67.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.67.4.tgz", + "integrity": "sha512-RJZnrwTWj7Iq2ooBwoGbDdC65tDwYawneGcAfFMJqVUrRZMcskka6nTkBpXR/47G7kzn3EW2qupExnaBy11vwg==", + "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.1.0", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.1.0.tgz", + "integrity": "sha512-cVBuhDQjBZaNMTwBquYfPydrUP+E3hE6oYGasx8h6ZrODIM7/r+gxLDXdd66oszbrggZHEntdE6j+5gYIVyMWQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.10.tgz", + "integrity": "sha512-lTyOMnOcmRBzdCv6/4zUZCrEhV0xrqQiUZBZtVcbmLHBXKLnN8q89v/wKRF/Q0HbwVsqbIG3o5HDoFl9sduM+g==", + "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.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.44.tgz", + "integrity": "sha512-k34nCytbK8PQ1gR2mGROYOw6Pnv/mumqIdrZ3x2tbyXZDWm7ViKGLTfdB+DRrWqEQsLgGJvn0WN9jBif5zCTLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.9", + "@vue/shared": "3.5.44", + "entities": "^7.0.1", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.2" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.44.tgz", + "integrity": "sha512-W5AoBFWdw1lQAKiHowkfgFKFab82oSRT6sGsPfw/q1GRjsy/ZJFLHGhJyBRIFN9APLTUduDH9U2JAiPOIyKuYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.44", + "@vue/shared": "3.5.44" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.44.tgz", + "integrity": "sha512-dzHmQ4jXTpdr5FjIQUeykVakN/uzqFbUo9/C5ikBFg3a3PeM6uRxeczx1ZbXBML0/zJstEh3ygYipzR5Z7b2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.9", + "@vue/compiler-core": "3.5.44", + "@vue/compiler-dom": "3.5.44", + "@vue/compiler-ssr": "3.5.44", + "@vue/shared": "3.5.44", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.21", + "postcss": "^8.5.29", + "source-map-js": "^1.2.2" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.44.tgz", + "integrity": "sha512-xr5gb1JVHlfXJwSlRz1FeP6uxoazdzHuMTVLE7up+4Vrqxk219CvxLPxD9NXBt47yvZW7+p4DXfyp4O1fkByIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.44", + "@vue/shared": "3.5.44" + } + }, + "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.44", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.44.tgz", + "integrity": "sha512-u+QJdKeBBEADkPdevsL+6E12QlYVfBD8Zcw5qjDQKtamI6l14KyqazJMobhCKelhWN5zpyKUiEDoTyHE93cqWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.44" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.44.tgz", + "integrity": "sha512-uEa/ndwjhrrhnOfb2p+sZy6zeoamJOISqaLSJGk/8R6nABT1ZldpzcJoPzKj+zHVomVBPcmQYyC2r4LtvDV6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.44", + "@vue/shared": "3.5.44" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.44.tgz", + "integrity": "sha512-3fc4ARcXVhVBaJ3ujWiNZJARD6pkyRcwG+ZYhMzjKtKUp7MAY0HLwr7r3Smep3Li6ZaWT6ewdmx8XqdaD5oNZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.44", + "@vue/runtime-core": "3.5.44", + "@vue/shared": "3.5.44", + "csstype": "^3.2.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.44.tgz", + "integrity": "sha512-R4S1UoH4h5Frrauv8Z5XE5TxV9oBiUSgWIC4TyVK1FK+RocRnOLwFA5Xcmo2011RlgJp+AbZCnw6afrhlgRuUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.44", + "@vue/runtime-dom": "3.5.44", + "@vue/shared": "3.5.44" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.44", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.44.tgz", + "integrity": "sha512-H82XLH0DjmSOdbEwO15x3QTo1f5PWEtv237eLpYKc0mqLu+B8hnq16lFWmuBmNurkeiG3wr+oM1FhOll/YVFRg==", + "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.61.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.61.0.tgz", + "integrity": "sha512-CFtHkGANnIAG6TY5g9s/h+yxZ0SN2/ICMjMY1EWj9gKGiS4LSGFrmMmTA/xxyxOH8AEazFD3YSfRZMh5vIEh2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.27.0", + "@algolia/client-abtesting": "5.61.0", + "@algolia/client-analytics": "5.61.0", + "@algolia/client-common": "5.61.0", + "@algolia/client-insights": "5.61.0", + "@algolia/client-personalization": "5.61.0", + "@algolia/client-query-suggestions": "5.61.0", + "@algolia/client-search": "5.61.0", + "@algolia/ingestion": "1.61.0", + "@algolia/monitoring": "1.61.0", + "@algolia/recommend": "5.61.0", + "@algolia/requester-browser-xhr": "5.61.0", + "@algolia/requester-fetch": "5.61.0", + "@algolia/requester-node-http": "5.61.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.6", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.6.tgz", + "integrity": "sha512-1SZUxCN3TtJAE7e2BQN2MBHsoZ1gnmi9GoCP5Di59CSWptIezSAW09yDZyVbanb78V9eCwrKqdQsjtfVTxYHWA==", + "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.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "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.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.32.tgz", + "integrity": "sha512-LJlKCCAUFKOuZxipUdYw1NzIITEsPcgyOG9LkvRJvuKj/bRzbuRY0ARXvL0pWGpsZvn8jku+LMep2eU0seHp8g==", + "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.20", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "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.67.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.67.4.tgz", + "integrity": "sha512-Lsv3oKcz5jgOQJej/p7nfwbVEdAbDT+z6OPf/SCdI+nF+q2ENp0pTKT35ZwXAmH8g45mfrIiJeEyAqKYSYoL9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.10" + }, + "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.67.4", + "@rollup/rollup-android-arm64": "4.67.4", + "@rollup/rollup-android-x64": "4.67.4", + "@rollup/rollup-darwin-arm64": "4.67.4", + "@rollup/rollup-darwin-x64": "4.67.4", + "@rollup/rollup-freebsd-arm64": "4.67.4", + "@rollup/rollup-freebsd-x64": "4.67.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.67.4", + "@rollup/rollup-linux-arm-musleabihf": "4.67.4", + "@rollup/rollup-linux-arm64-gnu": "4.67.4", + "@rollup/rollup-linux-arm64-musl": "4.67.4", + "@rollup/rollup-linux-loong64-gnu": "4.67.4", + "@rollup/rollup-linux-loong64-musl": "4.67.4", + "@rollup/rollup-linux-ppc64-gnu": "4.67.4", + "@rollup/rollup-linux-ppc64-musl": "4.67.4", + "@rollup/rollup-linux-riscv64-gnu": "4.67.4", + "@rollup/rollup-linux-riscv64-musl": "4.67.4", + "@rollup/rollup-linux-s390x-gnu": "4.67.4", + "@rollup/rollup-linux-x64-gnu": "4.67.4", + "@rollup/rollup-linux-x64-musl": "4.67.4", + "@rollup/rollup-openbsd-x64": "4.67.4", + "@rollup/rollup-openharmony-arm64": "4.67.4", + "@rollup/rollup-win32-arm64-msvc": "4.67.4", + "@rollup/rollup-win32-ia32-msvc": "4.67.4", + "@rollup/rollup-win32-x64-gnu": "4.67.4", + "@rollup/rollup-win32-x64-msvc": "4.67.4", + "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.1", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.5.1.tgz", + "integrity": "sha512-dMCuwDUY6Noz3zVKLefBC4wq+aJV20yc7vWmM7uTNGwtQSFF5kX7OUIUsxuVajz/bdt5Xqdah3/0NLjth+cM5A==", + "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.2.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.2.0.tgz", + "integrity": "sha512-fpsYs/VVoZxfGY9/j3FQpZmN8wdLJaV1Pt38AaJNZu9uKIHcFU3halCdBveEq1HGKO1OEfJY65w1zvoFV1b3qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.1.0.tgz", + "integrity": "sha512-vKXxz6O38sKDj1mtx/k2cWvkkFBuYGx6uGrlzBkVeWCRF/F8sdI0j3Wbkz/5rVNRRuVc8UrgRdbCxNhmYXgP3w==", + "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.44", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.44.tgz", + "integrity": "sha512-dvvmaOCG7lAMkJTPqPwWeGMsPS6DIsFsfZDUgBp9V6mHf9b3+/wyVwYR4Es+WV6uJC0FKRxp81Obcq0ZwUcGFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.44", + "@vue/compiler-sfc": "3.5.44", + "@vue/runtime-dom": "3.5.44", + "@vue/server-renderer": "3.5.44", + "@vue/shared": "3.5.44" + }, + "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..994db3b --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "snowgoat-open-portal", + "private": true, + "type": "module", + "scripts": { + "dev": "vitepress dev . --host 127.0.0.1", + "build": "vitepress build .", + "preview": "vitepress preview . --host 127.0.0.1", + "check": "node scripts/check-registry.mjs", + "prebuild": "npm run check", + "predev": "npm run check" + }, + "devDependencies": { + "vitepress": "^1.6.4" + } +} diff --git a/pages/about.md b/pages/about.md new file mode 100644 index 0000000..9141760 --- /dev/null +++ b/pages/about.md @@ -0,0 +1,25 @@ +--- +title: 关于 +description: 雪羊科技开源项目门户说明 +outline: deep +--- + +# 关于 + +雪羊科技开源项目门户汇集公司对外发布的开源项目。当前收录物联网卡管理平台(iotLCM)、DTU 设备管理平台(秀杰 DTU)与中后台开发框架(XiuAdmin)。 + +## 许可证 + +全部项目以 **Apache-2.0** 发布。可自由使用、修改、商用与再分发;分发时保留版权声明与许可证原文,并对修改部分注明变更。各项目依赖的上游组件保留其原始许可。 + +## 参与贡献 + +1. 从目标项目的默认分支切出特性分支,命名 `feat/xxx`、`fix/xxx` +2. 提交前确保各自的构建与测试通过(Go 服务跑 `go build ./...` 与 `go test ./...`,前端跑 `pnpm build`) +3. 提交合入请求并说明变更动机 + +## 门户本身 + +门户是一个独立的 VitePress 工程,与平台代码不在同一个仓库。构建产物是纯静态站点,可用任意静态服务器或容器托管。 + +镜像构建与部署说明见[门户部署](/guide/portal-deploy)。 diff --git a/pages/guide/portal-deploy.md b/pages/guide/portal-deploy.md new file mode 100644 index 0000000..d92afe7 --- /dev/null +++ b/pages/guide/portal-deploy.md @@ -0,0 +1,52 @@ +--- +title: 门户部署 +description: 开源项目门户的构建与部署方式 +outline: deep +--- + +# 门户部署 + +门户是一个独立的 VitePress 工程,产物是纯静态文件。 + +## 本地构建 + +```bash +npm ci +npm run build +``` + +产物在 `.vitepress/dist/`。 + +## 容器部署 + +```bash +docker compose -f deploy/docker-compose.yml up -d --build +``` + +默认发布在宿主机 `127.0.0.1:8020`,容器内监听 80。 + +## 两种路径形态 + +构建参数 `SITE_BASE` 决定站点资源前缀: + +| 形态 | 参数 | 访问方式 | +| --- | --- | --- | +| 子路径(过渡形态,无独立域名) | `/www/`(默认) | 挂在已有网关的 `/www/` 路径下 | +| 独立域名 | `/` | 站点独占域名根路径 | + +```bash +SITE_BASE=/ docker compose -f deploy/docker-compose.yml up -d --build +``` + +两者内容完全同源,切换只改构建参数与入口配置,页面不用改。 + +> VitePress 产物里的资源引用是绝对路径(`assets/xxx`),base 与 nginx 的 location 形态必须配套,混用会出现「页面 200 但 JS/CSS 全 404」的白屏。镜像构建脚本按 `SITE_BASE` 自动选对应的 nginx 配置。 + +## 新增项目 + +项目清单由 `data/projects.ts` 单一注册表驱动,新增项目不需要改动站点其它部分: + +1. 在注册表里加一条记录 +2. 写 `pages/projects//index.md` 详情页 + +构建前会自动校验注册表与详情页目录是否一一对应。 diff --git a/pages/index.md b/pages/index.md new file mode 100644 index 0000000..411759f --- /dev/null +++ b/pages/index.md @@ -0,0 +1,39 @@ +--- +layout: home + +hero: + name: 雪羊科技开源 + text: 物联网与中后台基础软件 + tagline: 开源项目门户 · Apache-2.0 + actions: + - theme: brand + text: 浏览全部项目 + link: /projects/ + - theme: alt + text: iotLCM 快速开始 + link: /projects/iotlcm/guide/quickstart + +features: + - title: 全生命周期管理 + details: iotLCM 覆盖物联网 SIM 卡的入库、划拨、激活、续费、停机、流量与状态同步、销户全流程。 + - title: 设备接入闭环 + details: 秀杰 DTU 管理平台覆盖 DTU 设备生产、出厂、划拨、绑定、配置下发、固件 OTA 与指令下发。 + - title: 中后台开发底座 + details: XiuAdmin 是基于 GoFrame + Vue3 的全栖中后台框架,租户、权限、代码生成、消息队列等内置可用。 + - title: 一条命令部署 + details: 各项目均提供 Docker Compose 编排与预构建镜像,clone 之后即可跑起来。 + - title: 统一 Apache-2.0 + details: 全部项目以 Apache-2.0 发布,可自由使用、修改、商用与再分发。 + - title: 持续新增 + details: 门户项目清单由单一注册表驱动,新增项目不需要改动站点其它部分。 +--- + +## 开源项目 + + + +## 使用说明 + +- 每个项目在「项目详情」页给出定位、能力边界与代码仓地址 +- 部署与运维细节见各项目的指南页 +- 源码仓统一托管在 Gitee 企业仓 `snowgoat` 命名空间下 diff --git a/pages/projects/index.md b/pages/projects/index.md new file mode 100644 index 0000000..47fb029 --- /dev/null +++ b/pages/projects/index.md @@ -0,0 +1,20 @@ +--- +title: 全部项目 +description: 雪羊科技开源项目清单 +outline: deep +--- + +# 全部项目 + + + +## 关于这份清单 + +项目清单由站点源码里的单一注册表维护(`data/projects.ts`),首页卡片、侧边栏与本页都从它生成。 + +新增一个项目需要两步: + +1. 在注册表里加一条记录(名称、定位、说明、代码仓、许可证、技术栈、状态) +2. 写 `pages/projects//index.md` 详情页,若有子页面(快速开始、部署、教程)在记录的 `sections` 里登记 + +站点构建前会自动校验「注册表条目」与「详情页目录」是否一一对应,不一致直接报错,避免清单与页面脱节。 diff --git a/pages/projects/iotlcm/guide/deploy.md b/pages/projects/iotlcm/guide/deploy.md new file mode 100644 index 0000000..795bfa4 --- /dev/null +++ b/pages/projects/iotlcm/guide/deploy.md @@ -0,0 +1,111 @@ +--- +title: 部署与运维 +description: 生产部署前的必改项、可选组件、离线部署与常见问题 +outline: deep +--- + +# 部署与运维 + +## 一键启动 + +```bash +git clone https://gitee.com/snowgoat/iotlcm.git +cd iotlcm/deploy +docker compose up -d +``` + +部署编排与数据库初始化脚本都在仓库的 `deploy/` 目录: + +```text +deploy/ +├── docker-compose.yml # 服务编排(含默认口令与端口) +├── compose.memlimit.yml # 容器内存上限(按机器规格叠加使用) +├── config/ # 各服务配置 + gateway / nginx 两种入口配置 +├── schema/init.sql # MySQL 初始化(95 表 + 种子数据) +├── tdengine-init/ # 时序库建库建表(首次启动自动执行) +└── data/ # 运行数据,首次启动自动创建 +``` + +## 可选组件 + +```bash +docker compose --profile with-mock up -d # 运营商接口挡板 +docker compose --profile with-bot up -d # 飞书通知(运维自用) +docker compose --profile with-nginx up -d # 自带反向代理(多域名入口) +docker compose --profile with-gateway up -d # 单端口入口(默认对外 5051) +``` + +多个 profile 可组合。 + +### 单端口入口(with-gateway) + +只暴露一个端口时用它。容器内监听 80,宿主机端口由 `GATEWAY_PORT` 控制(默认 5051): + +```bash +docker compose --profile with-gateway up -d +# 或换端口 +GATEWAY_PORT=8088 docker compose --profile with-gateway up -d +``` + +| 路径 | 去向 | +| --- | --- | +| `/` | 管理端(admin-ui,内部已代理 `/api/` 到 admin-svr) | +| `/docs/` | 文档站 | +| `/openapi/` | 对外 API | +| `/route/open/` | 运营商能力代理(白名单 / 共享 Token) | + +配置见 `config/gateway/nginx.conf`。小程序 / H5 端的静态资源是根路径部署的,不能挂在同一域名的子路径下,需要单独域名或端口(见 `with-nginx` 的 app 段)。 + +`with-bot` 是把全量同步等运维事件推送到飞书群的**内部运维工具**,不是平台功能。它需要你自己的飞书自建应用凭证(`config/bot/config.yaml` 的 `appId` / `appSecret` / `chatId`),没填就不启动。 + +**默认不启动,也不影响平台功能**;不需要飞书通知就完全不用管它。 + +## 线上暴露到公网 + +80 / 443 入站在多数办公宽带上被运营商封禁,可评估三种形态: + +| 形态 | 适用 | 代价 | +| --- | --- | --- | +| 高位端口 NAT | 内部验收、演示 | 地址带端口,不适合对外正式发布 | +| 独立子域 + 反代 | 有公网 IP 的服务器 | 需要域名解析与证书 | +| 云主机统一入口 | 正式对外发布 | 需要域名(以及国内服务器的备案) | + +## 上线前必改 + +| 项 | 说明 | +| --- | --- | +| 数据库口令 | MySQL 的 root 与应用账号口令 | +| Redis 口令 | 缓存层口令 | +| RabbitMQ 口令 | 队列层口令 | +| admin 口令 | 种子账号初始口令统一重置过,必须改 | +| JWT 密钥 | 管理端与用户端签发令牌用 | +| 运营商通道凭据 | 通道配置的 appKey / appSecret / 账号,按运营商要求申请 | +| 对象存储 | 图片与附件的存放位置 | + +## 离线部署 + +目标机器不能出网时: + +1. 在有网机器上拉全部镜像并导出: + +```bash +docker compose pull +docker save -o iotlcm-images.tar $(docker compose config --images) +``` + +2. 拷贝 `iotlcm-images.tar` 与仓库的 `deploy/` 目录到目标机器; +3. `docker load -i iotlcm-images.tar` 后再 `docker compose up -d`。 + +## 常见问题 + +| 现象 | 原因与处置 | +| --- | --- | +| MySQL 初始化中途失败 | schema 只在数据卷为空时执行,改完脚本必须清空卷才会重跑:`docker compose down && sudo rm -rf ./data/mysql && docker compose up -d` | +| 访问 8019 端口白屏 | 文档站必须带 `/docs/` 路径,裸端口会白屏 | +| 偶发 502 | 容器重建后 upstream IP 变化,nginx 未重新解析;配置已带 `resolver` + `resolve`,若仍出现,重启网关容器即可 | +| 通道调用报 IP 鉴权失败 | 运营商侧需要报备出口 IP,未报备则拒绝调用 | +| 端口被占用 | 编排里业务端口默认绑 `127.0.0.1`,改端口映射即可避开冲突 | + +## 监控 + +Consul 提供服务注册与健康探针,Prometheus 指标入口在编排内已开。日志按服务落在 `deploy/data/logs/` 下,配合 logrotate 生效。 diff --git a/pages/projects/iotlcm/guide/quickstart.md b/pages/projects/iotlcm/guide/quickstart.md new file mode 100644 index 0000000..39a5756 --- /dev/null +++ b/pages/projects/iotlcm/guide/quickstart.md @@ -0,0 +1,81 @@ +--- +title: 快速开始 +description: 三步把 iotLCM 开源版跑起来 +outline: deep +--- + +# 快速开始 + +## 前置条件 + +| 项 | 要求 | +| --- | --- | +| 操作系统 | Linux(x86_64 / arm64) | +| Docker | 20.10 以上,含 Compose V2(`docker compose version` 可用) | +| 内存 | 建议 4 GB 以上 | +| 磁盘 | 建议 40 GB 以上(含镜像与数据库) | +| 端口 | 3306 / 6379 / 5672 / 6041 / 6030 / 8500 默认占用,起步前先确认空闲 | + +## 第一步:取代码 + +```bash +git clone https://gitee.com/snowgoat/iotlcm.git +cd iotlcm +``` + +## 第二步:起栈 + +```bash +cd deploy +docker compose up -d +``` + +不需要复制或修改任何文件,编排里已带可用的默认配置。首次启动会自动: + +1. MySQL 建库并导入 schema(13 个脚本按序执行:建表 → 结构补齐 → 创建应用账号 → 重置种子账号口令 → 导入通道模板、字典、菜单等种子数据),约 30 秒 ~ 1 分钟 +2. TDengine 自动建库建表(流量历史库) +3. 其余服务依次启动并向 Consul 注册 + +观察进度: + +```bash +docker compose logs -f mysql +``` + +看到 `[initdb] 应用账号 u_iotlcm 已创建` 与 `[initdb] 种子账号口令已统一重置` 表示初始化完成。 + +## 第三步:登录 + +部署完成后访问 `http://127.0.0.1:8009`,账号 `admin`,初始口令见仓库的 `deploy/README.md`。 + +> **正式使用前必须修改默认口令**:数据库、Redis、RabbitMQ、admin 账号口令与 JWT 密钥。清单见[部署与运维](/projects/iotlcm/guide/deploy)的「上线前必改」。 + +## 端口对照 + +| 服务 | 宿主机端口 | 说明 | +| --- | --- | --- | +| 管理端 | 8009 | Web 管理平台 | +| 对外接口 | 8000 | OpenAPI V3 与兼容接口 | +| 用户端 | 8018 | 小程序 / H5 | +| 文档站 | 8019 | 使用手册与接口文档,必须带 `/docs/` 路径 | +| 运营商对接 | 8110 / 8310 | 通道协议适配 | +| 通道缓存 | 8510 | 缓存转发 | +| MySQL | 3306 | 库名 `db_iotlcm` | +| Redis | 6379 | 缓存与运行状态 | +| RabbitMQ | 5672 / 15672 | 队列与管理界面 | +| TDengine | 6041 / 6030 | 时序库 | +| Consul | 8500 | 服务注册 | + +编排默认把业务端口绑定在 `127.0.0.1`,需要局域网或公网访问时,改用反向代理编排或并入宿主机已有的 nginx。 + +## 停止与清理 + +```bash +docker compose down # 停止,数据保留 +docker compose down -v # 停止并删除数据卷(不可恢复) +``` + +## 下一步 + +- [部署与运维](/projects/iotlcm/guide/deploy) +- [教程视频](/projects/iotlcm/guide/tutorial) diff --git a/pages/projects/iotlcm/guide/tutorial.md b/pages/projects/iotlcm/guide/tutorial.md new file mode 100644 index 0000000..23c74eb --- /dev/null +++ b/pages/projects/iotlcm/guide/tutorial.md @@ -0,0 +1,65 @@ +--- +title: 教程视频 +description: 部署与使用的录屏教程 +outline: deep +--- + +# 教程视频 + +开源版的上手路径只有两条:**把平台跑起来**(部署)与**把平台用起来**(使用)。两条路径各一支录屏视频,文字文档只作配套说明,不替代视频。 + +## 部署教程 + +| 项 | 内容 | +| --- | --- | +| 标题 | iotLCM 开源版部署教程:从零到可用 | +| 目标观众 | 第一次接触本项目、具备 Linux 与 Docker 基础的开发者与实施工程师 | +| 时长 | 12 ~ 15 分钟 | +| 发布位置 | 官网本页 + 代码仓 README 顶部 + B 站 | +| 关联文档 | [快速开始](/projects/iotlcm/guide/quickstart)、[部署与运维](/projects/iotlcm/guide/deploy) | +| 关联仓库路径 | `deploy/`、`docs/` | + +视频覆盖: + +1. 环境准备:Docker 与 Compose 版本检查、端口占用确认、机器规格建议 +2. 取代码:`git clone` 公开仓库,确认目录结构 +3. 启动:`docker compose up -d`,观察 MySQL 初始化日志直到种子数据导入完成 +4. 验证:登录管理端、打开文档站与 OpenAPI 文档、跑一次状态查询 +5. 收尾:改默认口令、停栈与清理数据卷 + +## 使用教程 + +| 项 | 内容 | +| --- | --- | +| 标题 | iotLCM 开源版使用教程:核心功能实操 | +| 目标观众 | 已完成部署、准备给业务方上手的管理员与运营人员 | +| 时长 | 15 ~ 20 分钟 | +| 发布位置 | 官网本页 + 代码仓 README 顶部 + B 站 | +| 关联文档 | [功能概览](/projects/iotlcm/) | +| 关联仓库路径 | `admin-svr/`、`admin-ui/`、`openapi/`、`worker-svr/` | + +视频覆盖: + +1. 卡信息:列表检索、按三码查卡、卡详情与用量查看 +2. 库存与划拨:入库后的代理商维度划拨 +3. 资费与业务受理:套餐配置、开通/续费/停复机、达量断网 +4. 通道与批次:通道配置查看、批量操作与异步进度 +5. 对外接口:申请 API 凭证并完成一次真实调用 +6. 账号与工单:企业用户与角色、告警工单处理 + +## 视频文件放置约定 + +成片放在代码仓的 `website/public/videos/` 下,文件名用小写连字符加版本号(如 `deploy-tutorial-v1.mp4`),页面里以相对路径引用: + +```html + +``` + +若改投 B 站等外部托管,页面保留外链入口即可,视频文件不进仓库(避免仓库体积膨胀)。 + +## 录制备忘 + +- 录屏环境用与观众一致的环境:干净的 Ubuntu + Docker Compose V2,不要在已有业务实例上录 +- 涉及口令的片段一律打码,示例口令用编排里的默认值 +- 步骤与[快速开始](/projects/iotlcm/guide/quickstart)严格一致,视频里出现的每条命令都必须能原样复制执行 +- 每个视频产出配套字幕或要点说明(Markdown),随视频一起发布 diff --git a/pages/projects/iotlcm/index.md b/pages/projects/iotlcm/index.md new file mode 100644 index 0000000..1a68ba0 --- /dev/null +++ b/pages/projects/iotlcm/index.md @@ -0,0 +1,58 @@ +--- +title: iotLCM +description: 物联网卡全生命周期管理平台 +outline: deep +--- + +# iotLCM + +物联网卡全生命周期管理平台。卡片从运营商渠道入库 → 划拨给代理商 → 激活 / 续费 / 停机 → 流量与状态同步 → 销户,一个平台覆盖 SIM 卡管理全程。 + +对接**中国移动 OneLink**、**中国电信 5G CMP**、**中国联通 10646** 等运营商接口,支持以共享 Token 模式接入三方渠道商,并提供对外的 OpenAPI 服务。 + +| 项 | 值 | +| --- | --- | +| 代码仓 | | +| 许可证 | Apache-2.0 | +| 状态 | 已发布 | +| 技术栈 | GoFrame v2、Vue 3 + Vben Admin、MySQL、Redis、RabbitMQ、TDengine、Consul、Docker Compose | +| 文档站 | | + +## 能力概览 + +| 域 | 能力 | +| --- | --- | +| 卡资产 | 卡信息、批量导入、入库 / 库存 / 出库、批量开停复机、续费、变更套餐、达量断网 | +| 通信管理 | 通道与接入模板、运营商能力对接、共享 Token 接入三方渠道、通道缓存转发 | +| 资费 | 套餐与流量池、定价、生效与到期策略 | +| 代理商 | 代理商与分佣、划拨与回收 | +| 数据同步 | 流量 / 状态 / IMEI 全量同步与增量对齐、历史账期时序数据 | +| OpenAPI | V3 接口、旧版兼容接口、运营商能力代理(白名单转发 / 共享 Token) | +| 运营 | 工单、预警、执行日志、审计、智能诊断 | +| 端 | Web 管理端、小程序 / H5 用户端 | + +## 服务构成 + +单仓多服务:全部后端服务、前端应用、文档站与部署编排都在同一个仓库里。 + +| 目录 | 说明 | 镜像 | +| --- | --- | --- | +| `admin-svr/` | 管理端后端(GoFrame) | `iotlcm-admin-svr` | +| `admin-ui/` | 管理端前端(Vue 3 + Vben Admin) | `iotlcm-admin-ui` | +| `openapi/` | 对外 API 网关 | `iotlcm-openapi` | +| `worker-svr/` | 异步执行(RabbitMQ 消费者、全量同步、批量任务) | `iotlcm-worker-svr` | +| `upstream-chan/` | 运营商 / 三方渠道对接层 | `iotlcm-upstream-chan` | +| `upstream-proxy/` | 通道缓存转发层 | `iotlcm-upstream-proxy` | +| `app/server/` | 用户端服务(GoFrame) | `iotlcm-app-server` | +| `app/app/` | 用户端前端(uni-app,基于 unibest) | `iotlcm-app-web` | +| `sms/` | 短信服务(HTTP / gRPC) | `iotlcm-sms` | +| `bot/` | 飞书通知机器人(运维自用,可选) | `iotlcm-bot` | +| `docs/` | 文档站(VitePress)与 OpenAPI 合同 | `iotlcm-docs` | +| `onelink-mock/` | OneLink 接口挡板(联调 / 演示,可选) | `iotlcm-onelink-mock` | +| `deploy/` | Docker Compose 编排与数据库初始化 | — | + +## 下一步 + +- [快速开始](/projects/iotlcm/guide/quickstart) — 三步把整套跑起来 +- [部署与运维](/projects/iotlcm/guide/deploy) — 生产部署前的必改项、可选组件、离线部署与排错 +- [教程视频](/projects/iotlcm/guide/tutorial) — 部署与使用的录屏教程 diff --git a/pages/projects/xiu-admin/index.md b/pages/projects/xiu-admin/index.md new file mode 100644 index 0000000..543e8e5 --- /dev/null +++ b/pages/projects/xiu-admin/index.md @@ -0,0 +1,66 @@ +--- +title: XiuAdmin +description: 基于 GoFrame2 + Vue3 的全栖中后台框架 +outline: deep +--- + +# XiuAdmin + +基于全新 GoFrame2 + Vue3 + VueVbenAdmin 开发的全栖框架,适合大型中后台完整应用开发。 + +| 项 | 值 | +| --- | --- | +| 代码仓 | | +| 许可证 | Apache-2.0 | +| 状态 | 已发布 | +| 技术栈 | GoFrame v2、Vue 3、Vue Vben Admin、Ant Design Vue、asynq | + +## 框架特征 + +- 高生产率:极强的可扩展性,应用化、模块化、插件化机制敏捷开发,几分钟即可搭建一个应用开发框架 +- 快速生成代码:无需编写代码,只需创建表进行简单配置就能生成完善的 CURD、树表等常用开发代码,所需表单控件也是勾选即可直接生成 +- 认证机制:采用 JWT 的用户状态认证 +- 路由模式:得益于 GoFrame 提供了规范化的路由注册方式,无需注解自动生成 api 文档 +- 模块化设计,面向接口开发 + +## 内置功能 + +1. 租户管理:系统内租户的管理,如租户套餐、过期时间、用户数量、企业信息等 +2. 租户套餐管理:租户所能使用的套餐管理,如套餐内所包含的菜单等 +3. 客户端管理:系统内对接的所有客户端管理,如 pc 端、小程序端等 +4. 用户管理:用户是系统操作者,完成系统用户配置 +5. 部门管理:配置系统组织机构(公司、部门、岗位),树结构展现支持数据权限 +6. 岗位管理:配置系统用户所属担任职务 +7. 菜单管理:配置系统菜单,操作权限、按钮权限标识等 +8. 角色管理:角色菜单权限分配、设置角色按机构或按上下级关系进行数据范围权限划分 +9. 字典管理:对系统中经常使用的一些特定数据进行维护,支持枚举字典和自定义方法字典 +10. 配置管理:对系统动态配置常用参数 +11. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询 +12. 登录日志:系统登录日志记录查询,包含登录异常 +13. 服务日志:服务端运行所产生的警告、异常、崩溃日志的详细数据和堆栈信息 +14. 在线用户:当前系统中活跃用户状态监控 +15. 定时任务:在线(添加、修改、删除)任务调度,包含执行结果日志 +16. 代码生成:支持自动化生成前后端代码。CURD 关联表、树表、消息队列、定时任务一键生成等 +17. 服务监控:监视当前系统 CPU、内存、磁盘、网络、堆栈等相关信息 +18. 缓存监控:对系统的缓存信息查询、命令统计等 +19. 附件管理:文件图片上传,大文件分片上传、断点续传,支持本地 +20. 消息队列:Asynq 消息队列 +21. 通知公告:采用 WebSocket 实时推送在线用户最新通知、公告、私信消息 +22. 常用工具:集成常用的工具包和命令行工具,可以快速开发自定义命令行,多种启动入口 + +## 目录结构 + +```text +xiu-admin/ +├── server/ # GoFrame 后端服务 +├── vue/ # 前端 pnpm monorepo +├── docs/ # 文档与演示图例 +├── build/ # 构建脚本 +└── deploy/ # 部署配置 +``` + +## 参与贡献 + +1. Fork 代码仓并创建特性分支 +2. 提交前确保 `go build ./...` 与 `pnpm build` 通过 +3. 提交 Pull Request 并说明变更动机 diff --git a/pages/projects/xiu-dtu/index.md b/pages/projects/xiu-dtu/index.md new file mode 100644 index 0000000..9df7d12 --- /dev/null +++ b/pages/projects/xiu-dtu/index.md @@ -0,0 +1,140 @@ +--- +title: 秀杰 DTU 管理平台 +description: DTU 设备全生命周期管理平台 +outline: deep +--- + +# 秀杰 DTU 管理平台 + +面向 DTU(数据传输单元)设备全生命周期的开源管理平台,覆盖设备生产、出厂、代理商划拨、终端客户绑定、配置下发、固件 OTA 升级、指令下发与运行监控的完整闭环。 + +| 项 | 值 | +| --- | --- | +| 代码仓 | | +| 许可证 | Apache-2.0 | +| 状态 | 已发布 | +| 技术栈 | GoFrame v2、Vue 3 + Vite + TypeScript、Vben Admin 5.x、Ant Design Vue、MySQL 8、Redis、TDengine(可选)、asynq、VitePress | + +## 功能概览 + +| 模块 | 说明 | +| --- | --- | +| 生产中心 | 产品、硬件型号、工厂、生产批次、设备生产与导入导出 | +| 研发中心 | 固件管理、固件版本、OTA 升级任务 | +| 配置中心 | 产品通用模型、配置分组、配置版本与下发状态 | +| 代理中心 | 代理商设备列表、下级代理、设备划拨与划拨历史、我的订单 | +| 系统管理 | 用户、角色、菜单、部门、字典、参数、租户、监控 | +| 设备接入 | HTTP / TCP 双通道接入,指令下发、事件上报、UART 隧道 | + +## 目录结构 + +```text +. +├── server/ # GoFrame 后端服务 +│ ├── api/ # 接口定义 +│ ├── internal/ # 业务逻辑 +│ ├── config/ # 配置文件 +│ └── storage/ # 数据库初始化脚本 +├── vue/ # 前端 pnpm monorepo +│ └── apps/web-antd/ +├── docs_ui/ # VitePress 文档站 +├── docker/ # Docker 部署配置 +├── deploy/ # systemd / nginx 部署样例 +└── tools/ # 设备联调与压测脚本 +``` + +## 快速开始 + +环境要求:Go 1.25+、Node.js 24+ 与 pnpm 10+、MySQL 8、Redis 7。 + +### 1. 初始化数据库 + +```sh +mysql -u root -p -e "CREATE DATABASE xiujie_dtu DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" +mysql -u root -p xiujie_dtu < server/storage/data/xiu_admin.sql +mysql -u root -p xiujie_dtu < server/storage/data/xiu_dtu_init.sql +mysql -u root -p xiujie_dtu < server/storage/data/xiu_dtu_menu.sql +mysql -u root -p xiujie_dtu < server/storage/data/xiu_dtu_roles.sql +``` + +### 2. 配置后端 + +```sh +cp server/config/config_default.yaml server/config/config.yaml +``` + +按实际环境修改 `config.yaml` 中的数据库、Redis 连接信息。JWT 签名密钥通过环境变量注入,长度不少于 32 位,未提供时服务会拒绝签发与校验令牌。 + +### 3. 启动后端 + +```sh +cd server +go run main.go +``` + +后端默认监听:控制台接口 `:5689`、设备 HTTP 接口 `:5692`、设备 TCP 接入 `:5690`。 + +### 4. 启动前端 + +```sh +cd vue +pnpm install +pnpm dev +``` + +前端开发地址 `http://localhost:5688`。默认管理员账号 `admin`,首次登录后请立即修改。 + +### 5. 启动文档站(可选) + +```sh +cd docs_ui +npm install +npm run docs:dev +``` + +文档站地址 `http://localhost:5687`。 + +## 设备联调 + +`tools/` 下提供设备侧联调与压测脚本: + +```sh +# HTTP 通道联调 +BASE_URL="http://127.0.0.1:5692" \ +DEVICE_KEY="202606270101010001" \ +PRODUCT_KEY="DTU_TEST" \ +PROJECT_KEY="PROJECT_KEY_TEST" \ +./tools/test-device-http-v4.sh + +# TCP 通道联调(含心跳与指令监听) +TCP_HOST="127.0.0.1" \ +DEVICE_KEY="202606270101010001" \ +PRODUCT_KEY="DTU_TEST" \ +PROJECT_KEY="PROJECT_KEY_TEST" \ +python3 tools/test-device-tcp-v4.py --heartbeat --listen-command + +# 2 万设备压测 +BASE_URL="http://127.0.0.1:5689" TCP_HOST="127.0.0.1" \ +FACTORY_CODE="TEST_FACTORY_ROLE" PH_CODE="HW_V1" \ +PRODUCT_KEY="DTU_TEST" PROJECT_KEY="PROJECT_KEY_TEST" \ +python3 tools/stress-2w-devices.py --count 20000 --device-key-template 'SIM{index:012d}' +``` + +协议细节见代码仓文档站的「通信协议」章节。 + +## Docker 部署 + +```sh +cp docker/dtu_iot/.env.example docker/dtu_iot/.env +# 编辑 .env,填入实际域名、数据库与 Redis 口令 +cd docker/dtu_base && ./deploy.sh # 初始化 MySQL / Redis / TDengine +cd ../dtu_iot && ./deploy.sh # 部署业务服务 +``` + +镜像构建与推送: + +```sh +export DOCKER_USERNAME='your-registry-user' +export DOCKER_PASSWORD='your-registry-token' +make docker-build docker-push +``` diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..00ad3b4 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/scripts/check-registry.mjs b/scripts/check-registry.mjs new file mode 100644 index 0000000..ce30b51 --- /dev/null +++ b/scripts/check-registry.mjs @@ -0,0 +1,49 @@ +#!/usr/bin/env node +/** + * 校验「项目注册表」与「详情页目录」是否一一对应。 + * + * 门户的项目清单由 data/projects.ts 单一驱动。如果注册表加了项目却忘了写详情页, + * 或者写了详情页却没登记进注册表,首页卡片与侧边栏就会和实际内容脱节。 + * 这个脚本在 dev / build 之前自动跑,不一致直接退出非零。 + */ +import { readdirSync, readFileSync, existsSync } from 'node:fs' +import { fileURLToPath } from 'node:url' +import { dirname, join } from 'node:path' + +const root = join(dirname(fileURLToPath(import.meta.url)), '..') +const dataDir = join(root, 'data') +const pagesDir = join(root, 'pages', 'projects') + +// 注册表是 TS 源文件,这里只需要 id 列表,正则抽取即可,不引入编译步骤 +const registrySrc = readdirSync(dataDir) + .filter((f) => f.endsWith('.ts')) + .map((f) => readFileSync(join(dataDir, f), 'utf-8')) + .join('\n') + +const registered = [...registrySrc.matchAll(/\bid:\s*'([^']+)'/g)].map((m) => m[1]) + +if (registered.length === 0) { + console.error('[check] 注册表里没解析到任何项目,检查 data/projects.ts 的格式') + process.exit(1) +} + +const onDisk = existsSync(pagesDir) + ? readdirSync(pagesDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name) + : [] + +const missingPages = registered.filter((id) => !onDisk.includes(id)) +const missingEntries = onDisk.filter((id) => !registered.includes(id)) + +if (missingPages.length || missingEntries.length) { + if (missingPages.length) { + console.error(`[check] 注册表里有项目但缺详情页:${missingPages.join(', ')}`) + } + if (missingEntries.length) { + console.error(`[check] 有详情页但没登记进注册表:${missingEntries.join(', ')}`) + } + process.exit(1) +} + +console.log(`[check] OK:注册表 ${registered.length} 个项目与详情页一一对应(${registered.join(', ')})`)