diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3d8e1d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+# Dependencies
+node_modules/
+
+# VitePress build output
+docs/.vitepress/dist/
+docs/.vitepress/cache/
+
+# Logs
+*.log
+npm-debug.log*
+
+# Editor directories
+.idea/
+.vscode/
+*.swp
+*.swo
+
+# OS files
+.DS_Store
+Thumbs.db
+
+# Temporary files
+*.tmp
+*.temp
diff --git a/README.md b/README.md
index 3e9378f..332cd03 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,136 @@
-# learn-ai
\ No newline at end of file
+# AI学习之路 - 人工智能入门教程
+
+面向软件工程专业毕业生的中文人工智能入门学习教程网站。
+
+## ✨ 特性
+
+- **内容与代码分离**:使用Markdown编写内容,方便更新维护
+- **VitePress驱动**:现代化静态站点生成器,构建速度快
+- **数学公式支持**:集成MathJax渲染数学公式
+- **代码高亮**:自动语法高亮,支持多种编程语言
+- **响应式设计**:支持桌面和移动端浏览
+- **全文搜索**:内置本地搜索功能
+
+## 📚 教程大纲
+
+### 第0章:前置知识
+- 数学基础 - 线性代数、微积分、概率论
+- Python科学计算 - NumPy、Pandas、Matplotlib
+- 数据处理基础 - 数据预处理、特征工程
+
+### 第1章:AI基础概念
+- 什么是人工智能 - AI定义、历史与分类
+- 机器学习概述 - 监督学习、无监督学习、强化学习
+- 开发环境搭建 - Anaconda、Jupyter、GPU配置
+
+### 第2章:机器学习入门
+- 线性回归 - 模型原理、梯度下降、代码实现
+
+### 第3章:深度学习入门
+- 神经网络基础 - 感知机、激活函数、反向传播
+
+### 第4章:实战项目
+- 房价预测 - 完整的回归任务流程
+
+## 🚀 快速开始
+
+### 安装依赖
+
+```bash
+npm install
+```
+
+### 本地开发
+
+```bash
+npm run docs:dev
+```
+
+访问 http://localhost:5173 预览网站。
+
+### 构建生产版本
+
+```bash
+npm run docs:build
+```
+
+构建产物在 `docs/.vitepress/dist` 目录。
+
+### 预览构建结果
+
+```bash
+npm run docs:preview
+```
+
+## 📁 项目结构
+
+```
+learn-ai/
+├── docs/ # 文档源文件
+│ ├── .vitepress/ # VitePress配置
+│ │ └── config.mts # 站点配置
+│ ├── chapters/ # 教程章节
+│ │ ├── prerequisites/ # 前置知识
+│ │ ├── basics/ # AI基础
+│ │ ├── machine-learning/ # 机器学习
+│ │ ├── deep-learning/ # 深度学习
+│ │ └── projects/ # 实战项目
+│ ├── public/ # 静态资源
+│ ├── index.md # 首页
+│ ├── outline.md # 学习大纲
+│ └── resources.md # 推荐资源
+├── package.json
+└── README.md
+```
+
+## 📝 内容更新
+
+所有教程内容都在 `docs/chapters/` 目录下,使用Markdown格式编写。
+
+### 添加新章节
+
+1. 在对应目录创建新的 `.md` 文件
+2. 在 `docs/.vitepress/config.mts` 中更新侧边栏配置
+3. 运行 `npm run docs:dev` 预览
+
+### Markdown增强功能
+
+```markdown
+# 提示框
+::: info 信息
+这是一个信息提示
+:::
+
+::: tip 提示
+这是一个提示
+:::
+
+::: warning 警告
+这是一个警告
+:::
+
+# 数学公式
+行内公式: $E = mc^2$
+
+块级公式:
+$$
+\frac{\partial L}{\partial w} = \frac{2}{m}\sum_{i=1}^{m}(wx_i + b - y_i)x_i
+$$
+
+# 代码块
+```python
+import numpy as np
+print("Hello, AI!")
+```
+```
+
+## 🔗 参考资源
+
+- [吴恩达机器学习课程](https://www.coursera.org/learn/machine-learning)
+- [李沐《动手学深度学习》](https://d2l.ai/zh/)
+- [Fast.ai深度学习课程](https://www.fast.ai/)
+- [VitePress文档](https://vitepress.dev/)
+
+## 📄 许可证
+
+MIT License
\ No newline at end of file
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
new file mode 100644
index 0000000..49f3a02
--- /dev/null
+++ b/docs/.vitepress/config.mts
@@ -0,0 +1,180 @@
+import { defineConfig } from 'vitepress'
+import mathjax3 from 'markdown-it-mathjax3'
+
+// 自定义MathJax元素标签
+const customElements = [
+ 'mjx-container',
+ 'mjx-assistive-mml',
+ 'math',
+ 'maction',
+ 'maligngroup',
+ 'malignmark',
+ 'menclose',
+ 'merror',
+ 'mfenced',
+ 'mfrac',
+ 'mi',
+ 'mlongdiv',
+ 'mmultiscripts',
+ 'mn',
+ 'mo',
+ 'mover',
+ 'mpadded',
+ 'mphantom',
+ 'mroot',
+ 'mrow',
+ 'ms',
+ 'mscarries',
+ 'mscarry',
+ 'msgroup',
+ 'mstack',
+ 'msline',
+ 'mspace',
+ 'msqrt',
+ 'msrow',
+ 'mstyle',
+ 'msub',
+ 'msup',
+ 'msubsup',
+ 'mtable',
+ 'mtd',
+ 'mtext',
+ 'mtr',
+ 'munder',
+ 'munderover',
+ 'semantics',
+ 'annotation',
+ 'annotation-xml'
+]
+
+export default defineConfig({
+ lang: 'zh-CN',
+ title: 'AI学习之路',
+ description: '面向软件工程毕业生的人工智能入门教程',
+
+ head: [
+ ['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }],
+ ],
+
+ markdown: {
+ config: (md) => {
+ md.use(mathjax3)
+ },
+ lineNumbers: true,
+ },
+
+ vue: {
+ template: {
+ compilerOptions: {
+ isCustomElement: (tag) => customElements.includes(tag)
+ }
+ }
+ },
+
+ themeConfig: {
+ logo: '/logo.svg',
+
+ nav: [
+ { text: '首页', link: '/' },
+ { text: '教程', link: '/chapters/prerequisites/math' },
+ { text: '资源推荐', link: '/resources' },
+ ],
+
+ sidebar: {
+ '/chapters/': [
+ {
+ text: '第0章:前置知识',
+ collapsed: false,
+ items: [
+ { text: '数学基础', link: '/chapters/prerequisites/math' },
+ { text: 'Python科学计算', link: '/chapters/prerequisites/python-scientific' },
+ { text: '数据处理基础', link: '/chapters/prerequisites/data-processing' },
+ ]
+ },
+ {
+ text: '第1章:AI基础概念',
+ collapsed: false,
+ items: [
+ { text: '什么是人工智能', link: '/chapters/basics/what-is-ai' },
+ { text: '机器学习概述', link: '/chapters/basics/ml-overview' },
+ { text: '开发环境搭建', link: '/chapters/basics/environment-setup' },
+ ]
+ },
+ {
+ text: '第2章:机器学习入门',
+ collapsed: false,
+ items: [
+ { text: '线性回归', link: '/chapters/machine-learning/linear-regression' },
+ ]
+ },
+ {
+ text: '第3章:深度学习入门',
+ collapsed: false,
+ items: [
+ { text: '神经网络基础', link: '/chapters/deep-learning/neural-networks' },
+ ]
+ },
+ {
+ text: '第4章:实战项目',
+ collapsed: false,
+ items: [
+ { text: '房价预测', link: '/chapters/projects/house-price' },
+ ]
+ },
+ ],
+ },
+
+ socialLinks: [
+ { icon: 'github', link: 'https://github.com/LeeGoDamn/learn-ai' }
+ ],
+
+ footer: {
+ message: '面向软件工程毕业生的人工智能入门教程',
+ copyright: '© 2024 AI学习之路'
+ },
+
+ search: {
+ provider: 'local',
+ options: {
+ translations: {
+ button: {
+ buttonText: '搜索',
+ buttonAriaLabel: '搜索文档'
+ },
+ modal: {
+ noResultsText: '无法找到相关结果',
+ resetButtonTitle: '清除查询条件',
+ footer: {
+ selectText: '选择',
+ navigateText: '切换'
+ }
+ }
+ }
+ }
+ },
+
+ outline: {
+ label: '页面导航',
+ level: [2, 3]
+ },
+
+ docFooter: {
+ prev: '上一页',
+ next: '下一页'
+ },
+
+ lastUpdated: {
+ text: '最后更新于',
+ formatOptions: {
+ dateStyle: 'short',
+ timeStyle: 'medium'
+ }
+ },
+
+ returnToTopLabel: '回到顶部',
+ sidebarMenuLabel: '菜单',
+ darkModeSwitchLabel: '主题',
+ lightModeSwitchTitle: '切换到浅色模式',
+ darkModeSwitchTitle: '切换到深色模式'
+ }
+})
diff --git a/docs/chapters/basics/environment-setup.md b/docs/chapters/basics/environment-setup.md
new file mode 100644
index 0000000..dc2e10e
--- /dev/null
+++ b/docs/chapters/basics/environment-setup.md
@@ -0,0 +1,282 @@
+# 开发环境搭建
+
+::: info 本章概述
+本章将指导你搭建完整的AI开发环境,包括Anaconda、Jupyter Notebook、常用库安装以及GPU配置。
+:::
+
+## 1. Python环境管理
+
+### 1.1 为什么需要环境管理?
+
+不同的AI项目可能需要不同版本的Python和库。环境管理工具可以:
+- 隔离不同项目的依赖,避免冲突
+- 方便复制和共享环境配置
+- 便于切换Python版本
+
+### 1.2 Anaconda安装
+
+**Anaconda** 是最流行的Python科学计算发行版,预装了大量常用库。
+
+::: tip 下载安装
+1. 访问 [Anaconda官网](https://www.anaconda.com/download)
+2. 下载对应操作系统的安装包
+3. 运行安装程序,按提示完成安装
+4. 建议勾选"添加到环境变量"选项
+:::
+
+### 1.3 Conda常用命令
+
+```bash
+# 查看版本
+conda --version
+
+# 创建新环境
+conda create -n ai_env python=3.10
+
+# 激活环境
+conda activate ai_env
+
+# 退出环境
+conda deactivate
+
+# 查看所有环境
+conda env list
+
+# 删除环境
+conda remove -n ai_env --all
+
+# 导出环境配置
+conda env export > environment.yml
+
+# 从配置文件创建环境
+conda env create -f environment.yml
+```
+
+### 1.4 安装常用库
+
+```bash
+# 激活环境后安装库
+conda activate ai_env
+
+# 基础科学计算库
+conda install numpy pandas matplotlib seaborn
+
+# 机器学习库
+conda install scikit-learn
+
+# 深度学习框架(二选一)
+# PyTorch(推荐)
+conda install pytorch torchvision torchaudio -c pytorch
+
+# TensorFlow
+conda install tensorflow
+
+# 其他常用库
+conda install jupyter jupyterlab
+pip install tqdm # 进度条
+```
+
+## 2. Jupyter Notebook
+
+**Jupyter Notebook** 是交互式编程环境,非常适合数据分析和机器学习实验。
+
+### 2.1 启动Jupyter
+
+```bash
+# 启动 Jupyter Notebook
+jupyter notebook
+
+# 或启动 Jupyter Lab(更现代的界面)
+jupyter lab
+```
+
+执行后会自动打开浏览器,访问 `http://localhost:8888`
+
+### 2.2 常用快捷键
+
+| 快捷键 | 功能 | 模式 |
+|--------|------|------|
+| Shift + Enter | 运行当前单元格,跳到下一个 | 通用 |
+| Ctrl + Enter | 运行当前单元格 | 通用 |
+| Esc | 进入命令模式 | 编辑模式 |
+| Enter | 进入编辑模式 | 命令模式 |
+| A / B | 在上方/下方插入单元格 | 命令模式 |
+| D + D | 删除当前单元格 | 命令模式 |
+| M / Y | 切换为Markdown/代码 | 命令模式 |
+
+### 2.3 Notebook最佳实践
+
+- 每个单元格只做一件事,保持简洁
+- 使用Markdown单元格添加说明文档
+- 定期保存,使用版本控制
+- 运行顺序很重要,建议从头到尾运行
+- 重要实验结果要截图或导出
+
+## 3. Google Colab(免费GPU)
+
+**Google Colab** 是谷歌提供的免费云端Jupyter环境,无需本地配置,还提供免费GPU。
+
+### 3.1 使用Colab
+
+1. 访问 [Google Colab](https://colab.research.google.com)
+2. 登录Google账号
+3. 新建笔记本或上传本地.ipynb文件
+
+### 3.2 启用GPU
+
+::: tip 启用GPU加速
+1. 菜单栏 → 修改 → 笔记本设置
+2. 硬件加速器选择"GPU"或"TPU"
+3. 点击保存
+:::
+
+```python
+# 检查GPU是否可用
+import torch
+print(f"PyTorch版本: {torch.__version__}")
+print(f"CUDA可用: {torch.cuda.is_available()}")
+if torch.cuda.is_available():
+ print(f"GPU型号: {torch.cuda.get_device_name(0)}")
+```
+
+### 3.3 Colab实用技巧
+
+```python
+# 挂载Google Drive(持久存储)
+from google.colab import drive
+drive.mount('/content/drive')
+
+# 安装额外的库
+!pip install transformers
+
+# 下载文件
+!wget https://example.com/data.csv
+
+# 查看GPU使用情况
+!nvidia-smi
+```
+
+## 4. GPU配置(本地)
+
+如果你有NVIDIA GPU,可以配置本地CUDA环境以加速深度学习训练。
+
+### 4.1 检查GPU
+
+```bash
+# Windows: 打开命令提示符
+nvidia-smi
+
+# 如果能显示GPU信息,说明驱动已安装
+```
+
+### 4.2 安装CUDA工具包
+
+1. 确认GPU支持的CUDA版本
+2. 安装对应版本的CUDA Toolkit
+3. 安装cuDNN库
+4. 配置环境变量
+
+::: warning 版本兼容性
+PyTorch和TensorFlow对CUDA版本有要求。建议先确认框架需要的CUDA版本,再安装对应版本。
+
+最简单的方式是使用conda安装,它会自动处理依赖:
+:::
+
+```bash
+# PyTorch with CUDA 11.8
+conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia
+
+# TensorFlow with GPU support
+pip install tensorflow[and-cuda]
+```
+
+## 5. 常用IDE配置
+
+### 5.1 VS Code
+
+Visual Studio Code是最流行的代码编辑器,对Python和Jupyter有很好的支持。
+
+::: tip 推荐扩展
+- **Python** - 微软官方Python支持
+- **Jupyter** - 在VS Code中运行Notebook
+- **Pylance** - Python语言服务器
+- **GitHub Copilot** - AI编程助手
+- **GitLens** - Git增强
+:::
+
+### 5.2 PyCharm
+
+PyCharm是专业的Python IDE,社区版免费,对大型项目支持较好。
+
+## 6. 验证环境
+
+运行以下代码验证环境是否正确配置:
+
+```python
+import sys
+print(f"Python版本: {sys.version}")
+
+import numpy as np
+print(f"NumPy版本: {np.__version__}")
+
+import pandas as pd
+print(f"Pandas版本: {pd.__version__}")
+
+import sklearn
+print(f"Scikit-learn版本: {sklearn.__version__}")
+
+import matplotlib
+print(f"Matplotlib版本: {matplotlib.__version__}")
+
+# 深度学习框架
+try:
+ import torch
+ print(f"PyTorch版本: {torch.__version__}")
+ print(f"CUDA可用: {torch.cuda.is_available()}")
+except ImportError:
+ print("PyTorch未安装")
+
+try:
+ import tensorflow as tf
+ print(f"TensorFlow版本: {tf.__version__}")
+ print(f"GPU可用: {len(tf.config.list_physical_devices('GPU')) > 0}")
+except ImportError:
+ print("TensorFlow未安装")
+
+print("\n环境配置完成!可以开始学习了!")
+```
+
+## 7. 推荐的项目结构
+
+```
+my_ai_project/
+├── data/ # 数据文件
+│ ├── raw/ # 原始数据
+│ └── processed/ # 处理后的数据
+├── notebooks/ # Jupyter笔记本
+│ ├── 01_eda.ipynb # 探索性分析
+│ ├── 02_training.ipynb # 模型训练
+│ └── 03_evaluation.ipynb
+├── src/ # 源代码
+│ ├── __init__.py
+│ ├── data_processing.py
+│ ├── models.py
+│ └── utils.py
+├── models/ # 保存的模型
+├── results/ # 结果和图表
+├── requirements.txt # 依赖列表
+├── environment.yml # Conda环境配置
+└── README.md # 项目说明
+```
+
+## 8. 本章小结
+
+- 使用Anaconda管理Python环境和依赖
+- Jupyter Notebook是交互式实验的首选工具
+- Google Colab提供免费GPU,适合没有本地GPU的学习者
+- 本地GPU配置需要注意CUDA版本兼容性
+- 良好的项目结构有助于代码管理和协作
+
+::: tip 下一步
+环境配置完成后,我们将开始学习机器学习的核心算法——从线性回归开始!
+:::
diff --git a/docs/chapters/basics/ml-overview.md b/docs/chapters/basics/ml-overview.md
new file mode 100644
index 0000000..3ed091e
--- /dev/null
+++ b/docs/chapters/basics/ml-overview.md
@@ -0,0 +1,218 @@
+# 机器学习概述
+
+::: info 本章概述
+本章深入介绍机器学习的三大范式(监督学习、无监督学习、强化学习),以及机器学习工作流程和常用算法分类。
+:::
+
+## 1. 什么是机器学习
+
+**机器学习(Machine Learning)** 是人工智能的核心分支,它使计算机能够从数据中自动学习规律,无需显式编程。
+
+::: tip 经典定义
+**汤姆·米切尔(Tom Mitchell)**:如果一个程序在任务T上的性能P随着经验E的增加而提高,则称该程序从经验E中学习。
+:::
+
+举个例子:垃圾邮件过滤器
+
+- **任务T**:将邮件分类为垃圾邮件或正常邮件
+- **性能P**:分类准确率
+- **经验E**:用户标记的邮件数据
+
+## 2. 监督学习(Supervised Learning)
+
+监督学习是最常见的机器学习类型,使用带有标签的数据进行训练。
+
+### 2.1 基本概念
+
+- **特征(Features)**:输入变量,用于描述样本的属性,通常表示为 X
+- **标签(Label)**:目标变量,我们要预测的值,通常表示为 y
+- **训练集**:用于训练模型的数据
+- **测试集**:用于评估模型性能的数据
+
+### 2.2 问题类型
+
+| 类型 | 描述 | 例子 | 常用算法 |
+|------|------|------|----------|
+| **回归** | 预测连续数值 | 房价预测、温度预测 | 线性回归、随机森林 |
+| **分类** | 预测离散类别 | 垃圾邮件识别、图像分类 | 逻辑回归、SVM、神经网络 |
+
+### 2.3 代码示例
+
+```python
+from sklearn.model_selection import train_test_split
+from sklearn.linear_model import LinearRegression
+from sklearn.metrics import mean_squared_error
+import numpy as np
+
+# 1. 准备数据
+X = np.array([[1], [2], [3], [4], [5], [6], [7], [8], [9], [10]])
+y = np.array([2.1, 4.2, 5.8, 8.1, 9.9, 12.1, 14.0, 16.2, 17.9, 20.1])
+
+# 2. 划分训练集和测试集
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
+
+# 3. 创建并训练模型
+model = LinearRegression()
+model.fit(X_train, y_train)
+
+# 4. 预测
+y_pred = model.predict(X_test)
+
+# 5. 评估
+mse = mean_squared_error(y_test, y_pred)
+print(f"均方误差: {mse:.4f}")
+print(f"模型参数: y = {model.coef_[0]:.2f}x + {model.intercept_:.2f}")
+```
+
+## 3. 无监督学习(Unsupervised Learning)
+
+无监督学习使用没有标签的数据,目标是发现数据中隐藏的结构和模式。
+
+### 3.1 主要任务
+
+| 任务 | 描述 | 例子 | 常用算法 |
+|------|------|------|----------|
+| **聚类** | 将相似样本分组 | 客户分群、文档分类 | K-means、DBSCAN、层次聚类 |
+| **降维** | 减少特征数量 | 数据可视化、特征提取 | PCA、t-SNE、UMAP |
+| **异常检测** | 识别异常样本 | 欺诈检测、故障诊断 | Isolation Forest、One-class SVM |
+
+### 3.2 聚类示例
+
+```python
+from sklearn.cluster import KMeans
+from sklearn.datasets import make_blobs
+import matplotlib.pyplot as plt
+
+# 生成示例数据
+X, _ = make_blobs(n_samples=300, centers=4, cluster_std=0.6, random_state=42)
+
+# K-means聚类
+kmeans = KMeans(n_clusters=4, random_state=42)
+labels = kmeans.fit_predict(X)
+
+# 可视化
+plt.figure(figsize=(8, 6))
+plt.scatter(X[:, 0], X[:, 1], c=labels, cmap='viridis')
+plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1],
+ c='red', marker='x', s=200, linewidths=3)
+plt.title('K-means聚类结果')
+plt.savefig('kmeans_result.png')
+plt.show()
+```
+
+## 4. 强化学习(Reinforcement Learning)
+
+强化学习与监督学习和无监督学习不同,它通过智能体与环境的交互来学习最优策略。
+
+### 4.1 核心概念
+
+- **智能体(Agent)**:学习者,做出决策
+- **环境(Environment)**:智能体交互的外部世界
+- **状态(State)**:环境的当前情况
+- **动作(Action)**:智能体可执行的操作
+- **奖励(Reward)**:动作后环境给予的反馈
+- **策略(Policy)**:从状态到动作的映射
+
+```
+┌──────────┐ 动作 ┌──────────┐
+│ │ ──────────────────▶ │ │
+│ 智能体 │ │ 环境 │
+│ │ ◀────────────────── │ │
+└──────────┘ 状态 + 奖励 └──────────┘
+```
+
+### 4.2 典型应用
+
+- **游戏AI**:AlphaGo、Atari游戏、星际争霸
+- **机器人控制**:机械臂操作、自主导航
+- **推荐系统**:个性化推荐、广告投放
+- **自动驾驶**:决策规划
+
+## 5. 机器学习工作流程
+
+一个完整的机器学习项目通常包含以下步骤:
+
+1. **问题定义** → 明确业务目标和评估指标
+2. **数据收集** → 获取相关数据
+3. **数据探索** → EDA,理解数据特征
+4. **数据预处理** → 清洗、转换、特征工程
+5. **模型选择** → 根据问题类型选择合适的算法
+6. **模型训练** → 在训练集上拟合模型
+7. **模型评估** → 在测试集上评估性能
+8. **模型调优** → 超参数优化、特征选择
+9. **模型部署** → 将模型投入生产环境
+10. **监控维护** → 持续监控和更新
+
+## 6. 常用算法概览
+
+### 6.1 线性模型
+- 线性回归(Linear Regression)
+- 逻辑回归(Logistic Regression)
+- 正则化:Ridge、Lasso
+
+### 6.2 树模型
+- 决策树(Decision Tree)
+- 随机森林(Random Forest)
+- 梯度提升树(XGBoost、LightGBM)
+
+### 6.3 支持向量机
+- 线性SVM
+- 核SVM(RBF、多项式核)
+
+### 6.4 神经网络
+- 多层感知机(MLP)
+- 卷积神经网络(CNN)
+- 循环神经网络(RNN/LSTM)
+- Transformer
+
+## 7. 模型评估指标
+
+### 7.1 回归问题
+
+| 指标 | 公式描述 | 特点 |
+|------|----------|------|
+| MSE | 均方误差 | 对大误差敏感 |
+| RMSE | 均方根误差 | 与原始单位相同 |
+| MAE | 平均绝对误差 | 对异常值鲁棒 |
+| R² | 决定系数 | 解释方差比例 |
+
+### 7.2 分类问题
+
+| 指标 | 描述 | 适用场景 |
+|------|------|----------|
+| 准确率 | 正确预测的比例 | 类别平衡时 |
+| 精确率 | 预测为正中真正为正的比例 | 关注假阳性时 |
+| 召回率 | 真正为正中被预测为正的比例 | 关注假阴性时 |
+| F1分数 | 精确率和召回率的调和平均 | 综合评估 |
+| AUC-ROC | ROC曲线下面积 | 类别不平衡时 |
+
+```python
+from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
+from sklearn.metrics import confusion_matrix, classification_report
+
+# 假设有真实标签和预测标签
+y_true = [1, 0, 1, 1, 0, 1, 0, 0, 1, 0]
+y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 1, 0]
+
+# 计算各项指标
+print(f"准确率: {accuracy_score(y_true, y_pred):.4f}")
+print(f"精确率: {precision_score(y_true, y_pred):.4f}")
+print(f"召回率: {recall_score(y_true, y_pred):.4f}")
+print(f"F1分数: {f1_score(y_true, y_pred):.4f}")
+
+# 混淆矩阵
+print("\n混淆矩阵:")
+print(confusion_matrix(y_true, y_pred))
+
+# 详细报告
+print("\n分类报告:")
+print(classification_report(y_true, y_pred))
+```
+
+## 8. 本章小结
+
+- **监督学习**:从带标签数据学习,用于分类和回归问题
+- **无监督学习**:从无标签数据发现结构,用于聚类和降维
+- **强化学习**:通过交互学习最优策略
+- 机器学习项目包含数据准备、模型训练、评估调优等多个阶段
+- 选择合适的评估指标对于模型选择至关重要
diff --git a/docs/chapters/basics/what-is-ai.md b/docs/chapters/basics/what-is-ai.md
new file mode 100644
index 0000000..7bb01e3
--- /dev/null
+++ b/docs/chapters/basics/what-is-ai.md
@@ -0,0 +1,141 @@
+# 什么是人工智能
+
+::: info 本章概述
+本章将帮助你建立对人工智能领域的整体认识,了解AI的定义、发展历程、主要分支以及核心概念,为后续深入学习奠定基础。
+:::
+
+## 1. 人工智能的定义
+
+人工智能(Artificial Intelligence,简称AI)是一个广泛的概念,指的是机器模拟人类智能行为的能力。不同学者和机构对AI有不同的定义:
+
+| 定义视角 | 描述 |
+|----------|------|
+| 像人一样思考 | 模拟人类认知过程的系统(认知科学方法) |
+| 像人一样行动 | 通过图灵测试的系统(行为主义方法) |
+| 理性地思考 | 使用逻辑进行推理的系统(逻辑学方法) |
+| 理性地行动 | 在给定知识下做出最优决策的智能代理(现代主流定义) |
+
+::: tip 经典定义
+**约翰·麦卡锡(John McCarthy)** 在1956年首次提出"人工智能"这一术语,将其定义为:"研究如何使计算机做本来只有人才能做的智能工作。"
+:::
+
+## 2. AI、机器学习与深度学习的关系
+
+这三个概念经常被混用,但它们是包含关系:
+
+```
+┌─────────────────────────────────────────┐
+│ 人工智能 (AI) │
+│ ┌─────────────────────────────────┐ │
+│ │ 机器学习 (ML) │ │
+│ │ ┌─────────────────────────┐ │ │
+│ │ │ 深度学习 (DL) │ │ │
+│ │ └─────────────────────────┘ │ │
+│ └─────────────────────────────────┘ │
+└─────────────────────────────────────────┘
+```
+
+- **人工智能(AI)**:最广泛的概念,包括所有使机器表现出智能行为的技术
+- **机器学习(ML)**:AI的子集,让机器从数据中学习规律,无需显式编程
+- **深度学习(DL)**:ML的子集,使用深层神经网络进行学习
+
+## 3. AI发展历史
+
+### 3.1 重要里程碑
+
+| 年份 | 事件 | 意义 |
+|------|------|------|
+| 1950 | 图灵提出图灵测试 | 定义了机器智能的评判标准 |
+| 1956 | 达特茅斯会议 | "人工智能"术语诞生,AI成为独立学科 |
+| 1957 | 感知机诞生 | 最早的神经网络模型 |
+| 1986 | 反向传播算法 | 使多层神经网络训练成为可能 |
+| 1997 | 深蓝击败卡斯帕罗夫 | AI首次在国际象棋击败人类冠军 |
+| 2012 | AlexNet赢得ImageNet | 深度学习革命开始 |
+| 2016 | AlphaGo击败李世石 | AI在围棋领域超越人类 |
+| 2022 | ChatGPT发布 | 大语言模型引发AI应用浪潮 |
+
+### 3.2 AI的三次浪潮
+
+- **第一次浪潮(1956-1970s)**:符号主义AI,专家系统,因计算能力限制而衰退
+- **第二次浪潮(1980s-2000s)**:统计机器学习方法兴起,SVM、随机森林等
+- **第三次浪潮(2010s-至今)**:深度学习革命,大模型时代
+
+## 4. AI的主要分支
+
+### 4.1 按问题类型分类
+
+**机器学习三大范式:**
+
+| 类型 | 描述 | 典型应用 |
+|------|------|----------|
+| **监督学习** | 从带标签的数据中学习,预测新数据的标签 | 图像分类、垃圾邮件过滤、房价预测 |
+| **无监督学习** | 从无标签数据中发现结构和模式 | 用户分群、异常检测、降维 |
+| **强化学习** | 通过与环境交互,最大化累积奖励 | 游戏AI、机器人控制、推荐系统 |
+
+### 4.2 按应用领域分类
+
+- **计算机视觉(CV)**:图像识别、目标检测、人脸识别、自动驾驶
+- **自然语言处理(NLP)**:机器翻译、情感分析、问答系统、ChatGPT
+- **语音识别**:语音转文字、语音助手、声纹识别
+- **推荐系统**:电商推荐、内容推荐、广告投放
+- **机器人学**:工业机器人、服务机器人、无人机
+
+## 5. 核心概念解析
+
+### 5.1 模型(Model)
+
+模型是机器学习的核心,它是从数据中学习到的规律的数学表示。简单来说:
+
+```
+输入(X) → 模型(f) → 输出(Y)
+```
+
+- 模型接收输入数据,产生预测结果
+- 模型通过训练过程从数据中学习参数
+- 不同的模型适用于不同类型的问题
+
+### 5.2 训练与推理
+
+| 阶段 | 描述 | 计算需求 |
+|------|------|----------|
+| **训练(Training)** | 使用训练数据调整模型参数 | 高(需要大量计算和数据) |
+| **推理(Inference)** | 使用训练好的模型进行预测 | 相对低 |
+
+### 5.3 过拟合与欠拟合
+
+- **过拟合(Overfitting)**:模型在训练数据上表现很好,但在新数据上表现差。就像死记硬背考试答案,换个题就不会了。
+- **欠拟合(Underfitting)**:模型太简单,无法捕捉数据中的规律。就像只学了皮毛,理解不深入。
+
+### 5.4 损失函数与优化
+
+- **损失函数(Loss Function)**:衡量模型预测值与真实值之间差距的函数。训练的目标是最小化损失。
+- **优化器(Optimizer)**:用于更新模型参数以减小损失的算法。最常用的是梯度下降及其变体。
+
+## 6. AI的现实应用
+
+AI已经深入我们生活的方方面面:
+
+- **智能手机**:人脸解锁、语音助手、照片增强
+- **社交媒体**:内容推荐、广告定向、内容审核
+- **电商**:商品推荐、智能客服、价格优化
+- **医疗**:医学影像分析、疾病预测、药物研发
+- **交通**:自动驾驶、路线优化、交通预测
+- **金融**:风控评估、量化交易、欺诈检测
+
+## 7. 学习AI需要什么?
+
+::: tip 技能要求
+- **编程能力**:Python是首选语言(你已经具备!)
+- **数学基础**:线性代数、微积分、概率统计(前一章已覆盖)
+- **数据处理能力**:NumPy、Pandas、数据清洗(前一章已覆盖)
+- **算法思维**:理解算法原理,不只是调用API
+- **实践经验**:多做项目,在实践中学习
+:::
+
+## 8. 本章小结
+
+- 人工智能是让机器表现出智能行为的技术,机器学习和深度学习是其子集
+- AI经历了三次浪潮,当前处于深度学习和大模型驱动的第三次浪潮
+- 机器学习主要分为监督学习、无监督学习和强化学习三种范式
+- 理解模型、训练、过拟合等核心概念是学习AI的基础
+- AI已广泛应用于各行各业,是当今最热门的技术领域之一
diff --git a/docs/chapters/deep-learning/neural-networks.md b/docs/chapters/deep-learning/neural-networks.md
new file mode 100644
index 0000000..3eb7db6
--- /dev/null
+++ b/docs/chapters/deep-learning/neural-networks.md
@@ -0,0 +1,302 @@
+# 神经网络基础
+
+::: info 本章概述
+神经网络是深度学习的基础。本章将介绍神经网络的核心概念:感知机、激活函数、前向传播和反向传播算法。
+:::
+
+## 1. 从感知机到神经网络
+
+### 1.1 感知机(Perceptron)
+
+感知机是最简单的神经网络模型,由Frank Rosenblatt于1957年提出。它模拟了生物神经元的工作方式。
+
+$$y = \begin{cases} 1 & \text{if } \sum_{i} w_i x_i + b > 0 \\ 0 & \text{otherwise} \end{cases}$$
+
+```
+ x₁ ─────┐
+ │ w₁
+ x₂ ─────┼──────►[Σ]──────►[激活]──────► y
+ │ w₂
+ x₃ ─────┘
+ w₃
+```
+
+### 1.2 多层感知机(MLP)
+
+单层感知机只能解决线性可分问题。通过堆叠多层神经元,我们可以学习复杂的非线性关系。
+
+```
+输入层 隐藏层1 隐藏层2 输出层
+ ●──────────●───────────●──────────●
+ ●──────────●───────────●──────────●
+ ●──────────●───────────●
+ ●───────────●
+```
+
+## 2. 激活函数
+
+激活函数引入非线性,使神经网络能够学习复杂模式。
+
+### 2.1 常用激活函数
+
+| 函数 | 公式 | 特点 |
+|------|------|------|
+| **Sigmoid** | $\sigma(x) = \frac{1}{1+e^{-x}}$ | 输出(0,1),易梯度消失 |
+| **Tanh** | $\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}$ | 输出(-1,1),零中心化 |
+| **ReLU** | $f(x) = \max(0, x)$ | 计算简单,最常用 |
+| **Leaky ReLU** | $f(x) = \max(0.01x, x)$ | 解决ReLU死神经元问题 |
+| **Softmax** | $\sigma(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}}$ | 多分类输出层 |
+
+```python
+import numpy as np
+
+# 激活函数实现
+def sigmoid(x):
+ return 1 / (1 + np.exp(-x))
+
+def tanh(x):
+ return np.tanh(x)
+
+def relu(x):
+ return np.maximum(0, x)
+
+def leaky_relu(x, alpha=0.01):
+ return np.where(x > 0, x, alpha * x)
+
+def softmax(x):
+ exp_x = np.exp(x - np.max(x)) # 数值稳定性
+ return exp_x / np.sum(exp_x)
+
+# 导数(用于反向传播)
+def sigmoid_derivative(x):
+ s = sigmoid(x)
+ return s * (1 - s)
+
+def relu_derivative(x):
+ return np.where(x > 0, 1, 0)
+```
+
+## 3. 前向传播
+
+前向传播是数据从输入层经过隐藏层到输出层的计算过程。
+
+$$\mathbf{z}^{[l]} = \mathbf{W}^{[l]}\mathbf{a}^{[l-1]} + \mathbf{b}^{[l]}$$
+
+$$\mathbf{a}^{[l]} = g^{[l]}(\mathbf{z}^{[l]})$$
+
+```python
+class NeuralNetwork:
+ def __init__(self, layer_dims):
+ """
+ layer_dims: 各层神经元数量,如 [784, 128, 64, 10]
+ """
+ self.L = len(layer_dims) - 1 # 层数
+ self.parameters = {}
+
+ # 初始化参数(He初始化)
+ for l in range(1, self.L + 1):
+ self.parameters[f'W{l}'] = np.random.randn(
+ layer_dims[l], layer_dims[l-1]
+ ) * np.sqrt(2 / layer_dims[l-1])
+ self.parameters[f'b{l}'] = np.zeros((layer_dims[l], 1))
+
+ def forward(self, X):
+ """前向传播"""
+ self.cache = {'A0': X}
+ A = X
+
+ for l in range(1, self.L + 1):
+ W = self.parameters[f'W{l}']
+ b = self.parameters[f'b{l}']
+
+ Z = np.dot(W, A) + b
+
+ # 最后一层用softmax,其他用ReLU
+ if l == self.L:
+ A = self.softmax(Z)
+ else:
+ A = np.maximum(0, Z) # ReLU
+
+ self.cache[f'Z{l}'] = Z
+ self.cache[f'A{l}'] = A
+
+ return A
+
+ def softmax(self, Z):
+ exp_Z = np.exp(Z - np.max(Z, axis=0, keepdims=True))
+ return exp_Z / np.sum(exp_Z, axis=0, keepdims=True)
+```
+
+## 4. 反向传播
+
+反向传播是计算损失函数对每个参数梯度的算法,基于链式法则。
+
+### 4.1 链式法则回顾
+
+$$\frac{\partial L}{\partial w} = \frac{\partial L}{\partial a} \cdot \frac{\partial a}{\partial z} \cdot \frac{\partial z}{\partial w}$$
+
+### 4.2 反向传播公式
+
+对于输出层(交叉熵损失 + Softmax):
+
+$$\mathbf{dZ}^{[L]} = \mathbf{A}^{[L]} - \mathbf{Y}$$
+
+对于隐藏层(ReLU激活):
+
+$$\mathbf{dZ}^{[l]} = \mathbf{W}^{[l+1]T}\mathbf{dZ}^{[l+1]} * g'^{[l]}(\mathbf{Z}^{[l]})$$
+
+参数梯度:
+
+$$\mathbf{dW}^{[l]} = \frac{1}{m}\mathbf{dZ}^{[l]}\mathbf{A}^{[l-1]T}$$
+
+$$\mathbf{db}^{[l]} = \frac{1}{m}\sum\mathbf{dZ}^{[l]}$$
+
+```python
+def backward(self, Y):
+ """反向传播"""
+ m = Y.shape[1]
+ grads = {}
+
+ # 输出层梯度
+ dZ = self.cache[f'A{self.L}'] - Y
+
+ for l in reversed(range(1, self.L + 1)):
+ A_prev = self.cache[f'A{l-1}']
+
+ grads[f'dW{l}'] = (1/m) * np.dot(dZ, A_prev.T)
+ grads[f'db{l}'] = (1/m) * np.sum(dZ, axis=1, keepdims=True)
+
+ if l > 1:
+ W = self.parameters[f'W{l}']
+ dA = np.dot(W.T, dZ)
+ # ReLU导数
+ dZ = dA * (self.cache[f'Z{l-1}'] > 0)
+
+ return grads
+
+def update_parameters(self, grads, learning_rate):
+ """更新参数"""
+ for l in range(1, self.L + 1):
+ self.parameters[f'W{l}'] -= learning_rate * grads[f'dW{l}']
+ self.parameters[f'b{l}'] -= learning_rate * grads[f'db{l}']
+```
+
+## 5. 完整实现示例
+
+```python
+import numpy as np
+from sklearn.datasets import make_moons
+from sklearn.model_selection import train_test_split
+import matplotlib.pyplot as plt
+
+# 生成数据
+X, y = make_moons(n_samples=1000, noise=0.2, random_state=42)
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
+
+# 转换为正确的形状
+X_train = X_train.T # (2, 800)
+X_test = X_test.T # (2, 200)
+y_train = y_train.reshape(1, -1) # (1, 800)
+y_test = y_test.reshape(1, -1) # (1, 200)
+
+class SimpleNN:
+ def __init__(self, n_input, n_hidden, n_output):
+ # He初始化
+ self.W1 = np.random.randn(n_hidden, n_input) * np.sqrt(2/n_input)
+ self.b1 = np.zeros((n_hidden, 1))
+ self.W2 = np.random.randn(n_output, n_hidden) * np.sqrt(2/n_hidden)
+ self.b2 = np.zeros((n_output, 1))
+
+ def forward(self, X):
+ self.Z1 = np.dot(self.W1, X) + self.b1
+ self.A1 = np.maximum(0, self.Z1) # ReLU
+ self.Z2 = np.dot(self.W2, self.A1) + self.b2
+ self.A2 = 1 / (1 + np.exp(-self.Z2)) # Sigmoid
+ return self.A2
+
+ def compute_loss(self, Y, A2):
+ m = Y.shape[1]
+ loss = -np.mean(Y * np.log(A2 + 1e-8) + (1-Y) * np.log(1-A2 + 1e-8))
+ return loss
+
+ def backward(self, X, Y):
+ m = X.shape[1]
+
+ dZ2 = self.A2 - Y
+ dW2 = (1/m) * np.dot(dZ2, self.A1.T)
+ db2 = (1/m) * np.sum(dZ2, axis=1, keepdims=True)
+
+ dA1 = np.dot(self.W2.T, dZ2)
+ dZ1 = dA1 * (self.Z1 > 0)
+ dW1 = (1/m) * np.dot(dZ1, X.T)
+ db1 = (1/m) * np.sum(dZ1, axis=1, keepdims=True)
+
+ return dW1, db1, dW2, db2
+
+ def update(self, grads, lr):
+ dW1, db1, dW2, db2 = grads
+ self.W1 -= lr * dW1
+ self.b1 -= lr * db1
+ self.W2 -= lr * dW2
+ self.b2 -= lr * db2
+
+ def train(self, X, Y, epochs, lr):
+ losses = []
+ for epoch in range(epochs):
+ A2 = self.forward(X)
+ loss = self.compute_loss(Y, A2)
+ grads = self.backward(X, Y)
+ self.update(grads, lr)
+ losses.append(loss)
+ if epoch % 100 == 0:
+ print(f"Epoch {epoch}, Loss: {loss:.4f}")
+ return losses
+
+ def predict(self, X):
+ A2 = self.forward(X)
+ return (A2 > 0.5).astype(int)
+
+# 训练
+nn = SimpleNN(n_input=2, n_hidden=16, n_output=1)
+losses = nn.train(X_train, y_train, epochs=1000, lr=0.5)
+
+# 评估
+predictions = nn.predict(X_test)
+accuracy = np.mean(predictions == y_test)
+print(f"\n测试集准确率: {accuracy:.4f}")
+```
+
+## 6. 常见问题与解决方案
+
+### 6.1 梯度消失/爆炸
+
+| 问题 | 原因 | 解决方案 |
+|------|------|----------|
+| 梯度消失 | Sigmoid/Tanh在饱和区梯度接近0 | 使用ReLU激活函数 |
+| 梯度爆炸 | 权重过大导致梯度累积 | 梯度裁剪、BatchNorm |
+
+### 6.2 过拟合
+
+- **正则化**:L1/L2正则化
+- **Dropout**:随机丢弃神经元
+- **数据增强**:增加训练数据
+- **早停**:验证集性能不再提升时停止训练
+
+### 6.3 参数初始化
+
+| 方法 | 公式 | 适用场景 |
+|------|------|----------|
+| Xavier | $\mathcal{N}(0, \frac{1}{n_{in}})$ | Tanh/Sigmoid |
+| He | $\mathcal{N}(0, \frac{2}{n_{in}})$ | ReLU |
+
+## 7. 本章小结
+
+- **感知机** 是神经网络的基本单元
+- **激活函数** 引入非线性,ReLU是最常用的选择
+- **前向传播** 计算网络输出
+- **反向传播** 利用链式法则计算梯度
+- 理解这些基础对于使用深度学习框架至关重要
+
+::: tip 下一步
+掌握了神经网络基础后,可以学习PyTorch或TensorFlow等深度学习框架,它们会自动处理反向传播和参数更新。
+:::
diff --git a/docs/chapters/machine-learning/linear-regression.md b/docs/chapters/machine-learning/linear-regression.md
new file mode 100644
index 0000000..ff72f0f
--- /dev/null
+++ b/docs/chapters/machine-learning/linear-regression.md
@@ -0,0 +1,286 @@
+# 线性回归
+
+::: info 本章概述
+线性回归是最基础的机器学习算法,理解它对于掌握更复杂的模型至关重要。本章将从原理讲起,手把手实现梯度下降,并使用sklearn进行实战。
+:::
+
+## 1. 什么是线性回归
+
+线性回归是一种用于预测连续数值的监督学习算法。它假设输入特征和输出之间存在线性关系。
+
+### 1.1 一元线性回归
+
+最简单的情况是只有一个特征的线性回归:
+
+$$y = wx + b$$
+
+- $y$ - 预测值(目标变量)
+- $x$ - 输入特征
+- $w$ - 权重(斜率)
+- $b$ - 偏置(截距)
+
+### 1.2 多元线性回归
+
+当有多个特征时:
+
+$$y = w_1x_1 + w_2x_2 + ... + w_nx_n + b = \mathbf{w}^T\mathbf{x} + b$$
+
+用矩阵形式表示更简洁。
+
+## 2. 损失函数
+
+为了训练模型,我们需要一个衡量预测好坏的指标——损失函数。线性回归通常使用**均方误差(MSE)**:
+
+$$L(w, b) = \frac{1}{m}\sum_{i=1}^{m}(y_i - \hat{y}_i)^2 = \frac{1}{m}\sum_{i=1}^{m}(y_i - (wx_i + b))^2$$
+
+其中 $m$ 是样本数量,$y_i$ 是真实值,$\hat{y}_i$ 是预测值。
+
+::: tip 为什么用平方?
+- 平方可以放大大误差,使模型更关注大偏差
+- 平方使正负误差不会相互抵消
+- 平方函数可导,便于优化
+:::
+
+## 3. 梯度下降
+
+梯度下降是求解最优参数的核心算法。其思想是:沿着损失函数梯度的反方向更新参数,逐步找到最小值。
+
+### 3.1 算法步骤
+
+1. 随机初始化参数 $w$ 和 $b$
+2. 计算损失函数对参数的梯度
+3. 更新参数:$w = w - \eta \frac{\partial L}{\partial w}$
+4. 重复步骤2-3直到收敛
+
+### 3.2 梯度计算
+
+对于一元线性回归,梯度公式为:
+
+$$\frac{\partial L}{\partial w} = \frac{2}{m}\sum_{i=1}^{m}(wx_i + b - y_i)x_i$$
+
+$$\frac{\partial L}{\partial b} = \frac{2}{m}\sum_{i=1}^{m}(wx_i + b - y_i)$$
+
+## 4. 从零实现线性回归
+
+```python
+import numpy as np
+import matplotlib.pyplot as plt
+
+# 生成模拟数据
+np.random.seed(42)
+X = 2 * np.random.rand(100, 1)
+y = 4 + 3 * X + np.random.randn(100, 1) # y = 4 + 3x + 噪声
+
+# 可视化数据
+plt.scatter(X, y, alpha=0.6)
+plt.xlabel('X')
+plt.ylabel('y')
+plt.title('训练数据')
+plt.show()
+
+class LinearRegressionScratch:
+ def __init__(self, learning_rate=0.01, n_iterations=1000):
+ self.lr = learning_rate
+ self.n_iterations = n_iterations
+ self.w = None
+ self.b = None
+ self.losses = []
+
+ def fit(self, X, y):
+ m, n_features = X.shape
+
+ # 初始化参数
+ self.w = np.zeros((n_features, 1))
+ self.b = 0
+
+ # 梯度下降
+ for i in range(self.n_iterations):
+ # 预测
+ y_pred = np.dot(X, self.w) + self.b
+
+ # 计算损失
+ loss = np.mean((y - y_pred) ** 2)
+ self.losses.append(loss)
+
+ # 计算梯度
+ dw = -(2/m) * np.dot(X.T, (y - y_pred))
+ db = -(2/m) * np.sum(y - y_pred)
+
+ # 更新参数
+ self.w -= self.lr * dw
+ self.b -= self.lr * db
+
+ if i % 100 == 0:
+ print(f"Iteration {i}, Loss: {loss:.4f}")
+
+ return self
+
+ def predict(self, X):
+ return np.dot(X, self.w) + self.b
+
+# 训练模型
+model = LinearRegressionScratch(learning_rate=0.1, n_iterations=1000)
+model.fit(X, y)
+
+print(f"\n学习到的参数:")
+print(f"w = {model.w[0][0]:.4f} (真实值: 3)")
+print(f"b = {model.b:.4f} (真实值: 4)")
+
+# 绘制结果
+plt.figure(figsize=(12, 4))
+
+# 拟合曲线
+plt.subplot(1, 2, 1)
+plt.scatter(X, y, alpha=0.6, label='数据点')
+plt.plot(X, model.predict(X), color='red', label='拟合线')
+plt.xlabel('X')
+plt.ylabel('y')
+plt.title('线性回归拟合结果')
+plt.legend()
+
+# 损失曲线
+plt.subplot(1, 2, 2)
+plt.plot(model.losses)
+plt.xlabel('Iteration')
+plt.ylabel('Loss')
+plt.title('训练损失曲线')
+
+plt.tight_layout()
+plt.show()
+```
+
+## 5. 使用sklearn实现
+
+在实际项目中,我们通常使用成熟的库而不是从零实现:
+
+```python
+from sklearn.linear_model import LinearRegression
+from sklearn.model_selection import train_test_split
+from sklearn.metrics import mean_squared_error, r2_score
+import numpy as np
+
+# 生成数据
+np.random.seed(42)
+X = 2 * np.random.rand(100, 1)
+y = 4 + 3 * X.flatten() + np.random.randn(100)
+
+# 划分训练集和测试集
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
+
+# 创建并训练模型
+model = LinearRegression()
+model.fit(X_train, y_train)
+
+# 预测
+y_pred = model.predict(X_test)
+
+# 评估
+print(f"权重 w: {model.coef_[0]:.4f}")
+print(f"偏置 b: {model.intercept_:.4f}")
+print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}")
+print(f"R² Score: {r2_score(y_test, y_pred):.4f}")
+```
+
+## 6. 多元线性回归实战
+
+使用加州房价数据集进行多特征回归:
+
+```python
+from sklearn.datasets import fetch_california_housing
+from sklearn.linear_model import LinearRegression
+from sklearn.model_selection import train_test_split
+from sklearn.preprocessing import StandardScaler
+from sklearn.metrics import mean_squared_error, r2_score
+import pandas as pd
+import numpy as np
+
+# 加载加州房价数据集
+housing = fetch_california_housing()
+X = pd.DataFrame(housing.data, columns=housing.feature_names)
+y = housing.target
+
+print("特征名称:", housing.feature_names)
+print("数据形状:", X.shape)
+print("\n数据预览:")
+print(X.head())
+
+# 划分数据
+X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
+
+# 特征标准化
+scaler = StandardScaler()
+X_train_scaled = scaler.fit_transform(X_train)
+X_test_scaled = scaler.transform(X_test)
+
+# 训练模型
+model = LinearRegression()
+model.fit(X_train_scaled, y_train)
+
+# 预测和评估
+y_pred = model.predict(X_test_scaled)
+print(f"\nMSE: {mean_squared_error(y_test, y_pred):.4f}")
+print(f"RMSE: {np.sqrt(mean_squared_error(y_test, y_pred)):.4f}")
+print(f"R² Score: {r2_score(y_test, y_pred):.4f}")
+
+# 特征重要性
+importance = pd.DataFrame({
+ 'Feature': housing.feature_names,
+ 'Coefficient': model.coef_
+}).sort_values('Coefficient', key=abs, ascending=False)
+print("\n特征系数(绝对值排序):")
+print(importance)
+```
+
+## 7. 正则化
+
+当特征很多时,模型容易过拟合。正则化通过限制参数大小来防止过拟合。
+
+### 7.1 Ridge回归(L2正则化)
+
+$$L = \frac{1}{m}\sum_{i=1}^{m}(y_i - \hat{y}_i)^2 + \alpha\sum_{j=1}^{n}w_j^2$$
+
+### 7.2 Lasso回归(L1正则化)
+
+$$L = \frac{1}{m}\sum_{i=1}^{m}(y_i - \hat{y}_i)^2 + \alpha\sum_{j=1}^{n}|w_j|$$
+
+```python
+from sklearn.linear_model import Ridge, Lasso, ElasticNet
+
+# Ridge回归
+ridge = Ridge(alpha=1.0)
+ridge.fit(X_train_scaled, y_train)
+print(f"Ridge R²: {ridge.score(X_test_scaled, y_test):.4f}")
+
+# Lasso回归
+lasso = Lasso(alpha=0.1)
+lasso.fit(X_train_scaled, y_train)
+print(f"Lasso R²: {lasso.score(X_test_scaled, y_test):.4f}")
+
+# ElasticNet(L1和L2的组合)
+elastic = ElasticNet(alpha=0.1, l1_ratio=0.5)
+elastic.fit(X_train_scaled, y_train)
+print(f"ElasticNet R²: {elastic.score(X_test_scaled, y_test):.4f}")
+```
+
+::: tip 正则化选择
+- **Ridge**:特征多且都有一定贡献时使用
+- **Lasso**:需要特征选择时使用(会使部分系数变为0)
+- **ElasticNet**:结合两者优点
+:::
+
+## 8. 学习率的影响
+
+| 学习率 | 效果 | 问题 |
+|--------|------|------|
+| 太小(0.0001) | 收敛很慢 | 需要很多迭代 |
+| 适中(0.01-0.1) | 稳定收敛 | 理想选择 |
+| 太大(1.0) | 不收敛 | 损失震荡或发散 |
+
+## 9. 本章小结
+
+- **线性回归** 假设特征和目标之间存在线性关系
+- **损失函数**(MSE)衡量预测与真实值的差距
+- **梯度下降** 通过迭代更新参数来最小化损失
+- **学习率** 控制每次更新的步长,需要适当选择
+- **正则化**(Ridge/Lasso)防止过拟合
+- 实际项目中使用sklearn等成熟库,但理解原理很重要
diff --git a/docs/chapters/prerequisites/data-processing.md b/docs/chapters/prerequisites/data-processing.md
new file mode 100644
index 0000000..c28e478
--- /dev/null
+++ b/docs/chapters/prerequisites/data-processing.md
@@ -0,0 +1,378 @@
+# 数据处理基础
+
+::: info 本章概述
+在机器学习中,"数据决定上限,模型决定下限"。本章介绍数据预处理和特征工程的基本方法,这些技能在实际项目中至关重要。
+:::
+
+## 1. 数据预处理概述
+
+真实世界的数据往往是"脏"的,需要经过清洗和转换才能用于模型训练。数据预处理的质量直接影响模型的性能。
+
+### 1.1 数据质量问题
+
+| 问题类型 | 描述 | 处理方法 |
+|----------|------|----------|
+| 缺失值 | 数据中存在空值或NaN | 删除、填充、插值 |
+| 异常值 | 极端偏离正常范围的值 | 检测并处理或删除 |
+| 重复值 | 相同的记录出现多次 | 去重 |
+| 类型错误 | 数据类型不正确 | 类型转换 |
+| 格式不一致 | 同类数据格式不统一 | 标准化格式 |
+
+## 2. 缺失值处理
+
+### 2.1 检测缺失值
+
+```python
+import pandas as pd
+import numpy as np
+
+# 创建包含缺失值的数据
+df = pd.DataFrame({
+ 'age': [25, 30, np.nan, 35, 40],
+ 'salary': [50000, np.nan, 60000, np.nan, 80000],
+ 'city': ['北京', '上海', None, '广州', '深圳']
+})
+
+# 检测缺失值
+print(df.isnull()) # 返回布尔矩阵
+print(df.isnull().sum()) # 每列缺失值数量
+print(df.isnull().sum().sum()) # 总缺失值数量
+
+# 缺失值比例
+missing_ratio = df.isnull().sum() / len(df)
+print(missing_ratio)
+```
+
+### 2.2 处理缺失值
+
+```python
+# 方法1:删除
+df_dropped = df.dropna() # 删除任何含缺失值的行
+df_dropped = df.dropna(subset=['age']) # 只考虑特定列
+
+# 方法2:填充固定值
+df['age'] = df['age'].fillna(0)
+df['city'] = df['city'].fillna('未知')
+
+# 方法3:统计量填充
+df['age'] = df['age'].fillna(df['age'].mean()) # 均值
+df['salary'] = df['salary'].fillna(df['salary'].median()) # 中位数
+df['city'] = df['city'].fillna(df['city'].mode()[0]) # 众数
+
+# 方法4:前向/后向填充(时序数据)
+df['value'] = df['value'].fillna(method='ffill') # 前向填充
+df['value'] = df['value'].fillna(method='bfill') # 后向填充
+
+# 方法5:插值
+df['value'] = df['value'].interpolate(method='linear')
+```
+
+::: warning 注意事项
+选择缺失值处理方法时要考虑:
+1. 缺失的原因(随机缺失 vs 系统性缺失)
+2. 缺失比例(高于30%可能需要删除该特征)
+3. 业务含义(有时缺失本身就是有意义的信息)
+:::
+
+## 3. 异常值处理
+
+### 3.1 检测异常值
+
+```python
+import numpy as np
+import pandas as pd
+
+# 创建示例数据
+np.random.seed(42)
+data = np.random.randn(100) * 10 + 50
+data[0] = 200 # 添加异常值
+data[50] = -50
+
+df = pd.DataFrame({'value': data})
+
+# 方法1:统计方法(3σ原则)
+mean = df['value'].mean()
+std = df['value'].std()
+outliers_3sigma = df[(df['value'] < mean - 3*std) | (df['value'] > mean + 3*std)]
+print(f"3σ异常值数量: {len(outliers_3sigma)}")
+
+# 方法2:IQR方法(箱线图原理)
+Q1 = df['value'].quantile(0.25)
+Q3 = df['value'].quantile(0.75)
+IQR = Q3 - Q1
+lower = Q1 - 1.5 * IQR
+upper = Q3 + 1.5 * IQR
+outliers_iqr = df[(df['value'] < lower) | (df['value'] > upper)]
+print(f"IQR异常值数量: {len(outliers_iqr)}")
+```
+
+### 3.2 处理异常值
+
+```python
+# 方法1:删除异常值
+df_cleaned = df[(df['value'] >= lower) & (df['value'] <= upper)]
+
+# 方法2:截断(Winsorization)
+df['value_clipped'] = df['value'].clip(lower=lower, upper=upper)
+
+# 方法3:替换为边界值
+df.loc[df['value'] < lower, 'value'] = lower
+df.loc[df['value'] > upper, 'value'] = upper
+
+# 方法4:用缺失值代替,再填充
+df.loc[df['value'] < lower, 'value'] = np.nan
+df['value'] = df['value'].fillna(df['value'].median())
+```
+
+## 4. 特征缩放
+
+不同特征的量纲可能差异很大,这会影响某些算法(如梯度下降、KNN、SVM)的性能。
+
+### 4.1 标准化(Standardization)
+
+将数据转换为均值为0,标准差为1的分布:
+
+```python
+from sklearn.preprocessing import StandardScaler
+
+# 创建示例数据
+data = np.array([[1, 10000], [2, 20000], [3, 30000], [4, 40000]])
+df = pd.DataFrame(data, columns=['feature1', 'feature2'])
+
+# 使用StandardScaler
+scaler = StandardScaler()
+scaled_data = scaler.fit_transform(df)
+
+print("原始数据:")
+print(df)
+print("\n标准化后:")
+print(pd.DataFrame(scaled_data, columns=['feature1', 'feature2']))
+```
+
+### 4.2 归一化(Min-Max Scaling)
+
+将数据缩放到[0, 1]范围:
+
+```python
+from sklearn.preprocessing import MinMaxScaler
+
+scaler = MinMaxScaler()
+normalized_data = scaler.fit_transform(df)
+
+print("归一化后:")
+print(pd.DataFrame(normalized_data, columns=['feature1', 'feature2']))
+# 所有值都在[0, 1]范围内
+```
+
+::: tip 何时使用哪种方法?
+- **标准化:** 数据近似正态分布,或算法假设数据是正态分布(如逻辑回归、神经网络)
+- **归一化:** 需要有界数据,或使用距离计算的算法(如KNN、神经网络的图像输入)
+- **不缩放:** 决策树、随机森林等基于规则的算法对特征缩放不敏感
+:::
+
+## 5. 类别特征编码
+
+机器学习算法通常需要数值输入,因此需要将类别特征转换为数值。
+
+### 5.1 标签编码(Label Encoding)
+
+```python
+from sklearn.preprocessing import LabelEncoder
+
+# 适用于有序类别
+df = pd.DataFrame({
+ 'size': ['small', 'medium', 'large', 'medium', 'small']
+})
+
+le = LabelEncoder()
+df['size_encoded'] = le.fit_transform(df['size'])
+print(df)
+# small -> 2, medium -> 1, large -> 0(按字母顺序)
+
+# 查看映射
+print(dict(zip(le.classes_, range(len(le.classes_)))))
+```
+
+### 5.2 独热编码(One-Hot Encoding)
+
+```python
+from sklearn.preprocessing import OneHotEncoder
+import pandas as pd
+
+# 适用于无序类别
+df = pd.DataFrame({
+ 'color': ['red', 'blue', 'green', 'red', 'blue']
+})
+
+# 使用pandas
+df_encoded = pd.get_dummies(df, columns=['color'], prefix='color')
+print(df_encoded)
+# color_blue color_green color_red
+# 0 0 0 1
+# 1 1 0 0
+# 2 0 1 0
+# ...
+
+# 使用sklearn
+encoder = OneHotEncoder(sparse_output=False)
+encoded = encoder.fit_transform(df[['color']])
+print(encoded)
+```
+
+### 5.3 目标编码(Target Encoding)
+
+```python
+# 用于高基数类别特征(类别数量很多)
+df = pd.DataFrame({
+ 'city': ['北京', '上海', '北京', '广州', '上海', '北京'],
+ 'target': [1, 0, 1, 0, 1, 1]
+})
+
+# 计算每个类别的目标均值
+target_mean = df.groupby('city')['target'].mean()
+df['city_encoded'] = df['city'].map(target_mean)
+print(df)
+```
+
+## 6. 特征工程入门
+
+特征工程是利用领域知识从原始数据中创造新特征的过程,好的特征可以显著提升模型性能。
+
+### 6.1 特征创建
+
+```python
+import pandas as pd
+import numpy as np
+
+# 原始数据
+df = pd.DataFrame({
+ 'length': [10, 20, 15, 25],
+ 'width': [5, 10, 8, 12],
+ 'date': pd.to_datetime(['2024-01-15', '2024-03-20', '2024-06-10', '2024-12-25'])
+})
+
+# 数值特征组合
+df['area'] = df['length'] * df['width'] # 面积
+df['perimeter'] = 2 * (df['length'] + df['width']) # 周长
+df['ratio'] = df['length'] / df['width'] # 长宽比
+
+# 日期特征提取
+df['year'] = df['date'].dt.year
+df['month'] = df['date'].dt.month
+df['day'] = df['date'].dt.day
+df['dayofweek'] = df['date'].dt.dayofweek # 0=周一
+df['is_weekend'] = df['dayofweek'].isin([5, 6]).astype(int)
+df['quarter'] = df['date'].dt.quarter
+
+print(df)
+```
+
+### 6.2 特征分箱(Binning)
+
+```python
+# 将连续变量离散化
+df = pd.DataFrame({
+ 'age': [22, 35, 45, 18, 60, 28, 55]
+})
+
+# 等宽分箱
+df['age_bin_equal'] = pd.cut(df['age'], bins=3, labels=['young', 'middle', 'old'])
+
+# 自定义分箱
+bins = [0, 25, 40, 60, 100]
+labels = ['青年', '中年', '中老年', '老年']
+df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels)
+
+# 等频分箱(每个箱的样本数相近)
+df['age_quantile'] = pd.qcut(df['age'], q=3, labels=['low', 'medium', 'high'])
+
+print(df)
+```
+
+### 6.3 特征选择
+
+```python
+from sklearn.feature_selection import SelectKBest, f_classif
+from sklearn.ensemble import RandomForestClassifier
+import numpy as np
+
+# 生成示例数据
+np.random.seed(42)
+X = np.random.randn(100, 10)
+y = (X[:, 0] + X[:, 1] > 0).astype(int) # 只有前两个特征有用
+
+# 方法1:基于统计的特征选择
+selector = SelectKBest(f_classif, k=5)
+X_selected = selector.fit_transform(X, y)
+print(f"选择的特征索引: {selector.get_support(indices=True)}")
+
+# 方法2:基于模型的特征重要性
+rf = RandomForestClassifier(n_estimators=100, random_state=42)
+rf.fit(X, y)
+
+# 特征重要性
+importance = pd.DataFrame({
+ 'feature': [f'feature_{i}' for i in range(10)],
+ 'importance': rf.feature_importances_
+}).sort_values('importance', ascending=False)
+print(importance)
+```
+
+## 7. 数据预处理流水线
+
+在实际项目中,通常使用Pipeline将多个预处理步骤组合起来。
+
+```python
+from sklearn.pipeline import Pipeline
+from sklearn.compose import ColumnTransformer
+from sklearn.preprocessing import StandardScaler, OneHotEncoder
+from sklearn.impute import SimpleImputer
+
+# 定义数值和类别特征
+numeric_features = ['age', 'salary']
+categorical_features = ['city', 'gender']
+
+# 数值特征处理流水线
+numeric_transformer = Pipeline(steps=[
+ ('imputer', SimpleImputer(strategy='median')), # 填充缺失值
+ ('scaler', StandardScaler()) # 标准化
+])
+
+# 类别特征处理流水线
+categorical_transformer = Pipeline(steps=[
+ ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
+ ('onehot', OneHotEncoder(handle_unknown='ignore'))
+])
+
+# 组合处理器
+preprocessor = ColumnTransformer(
+ transformers=[
+ ('num', numeric_transformer, numeric_features),
+ ('cat', categorical_transformer, categorical_features)
+ ])
+
+# 完整的机器学习流水线
+from sklearn.linear_model import LogisticRegression
+
+full_pipeline = Pipeline(steps=[
+ ('preprocessor', preprocessor),
+ ('classifier', LogisticRegression())
+])
+
+# 使用流水线
+# full_pipeline.fit(X_train, y_train)
+# predictions = full_pipeline.predict(X_test)
+```
+
+::: danger 重要提示
+预处理操作必须先在训练集上fit,然后用同样的参数transform测试集。使用Pipeline可以避免数据泄露(data leakage)问题。
+:::
+
+## 8. 本章小结
+
+- **缺失值处理:** 根据数据特点选择删除、填充或插值
+- **异常值处理:** 使用统计方法检测,选择合适的处理策略
+- **特征缩放:** 标准化和归一化是最常用的方法
+- **类别编码:** 标签编码用于有序类别,独热编码用于无序类别
+- **特征工程:** 创造新特征、分箱、特征选择等技术
+- **Pipeline:** 组织预处理步骤,确保一致性
diff --git a/docs/chapters/prerequisites/math.md b/docs/chapters/prerequisites/math.md
new file mode 100644
index 0000000..0674dd1
--- /dev/null
+++ b/docs/chapters/prerequisites/math.md
@@ -0,0 +1,244 @@
+# 数学基础
+
+::: info 本章概述
+数学是机器学习和深度学习的基础。本章将帮助你回顾并补充AI学习所需的核心数学知识,包括线性代数、微积分和概率统计。
+:::
+
+## 1. 线性代数基础
+
+线性代数是机器学习中最重要的数学工具之一。几乎所有的机器学习算法都涉及到向量和矩阵运算。
+
+### 1.1 向量 (Vector)
+
+向量是一个有序的数字列表,可以表示为列向量或行向量。在机器学习中,向量常用于表示数据特征。
+
+$$\vec{x} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix}$$
+
+**常用向量运算:**
+
+- **向量加法:** 对应元素相加
+- **标量乘法:** 每个元素乘以标量
+- **点积(内积):** $\vec{a} \cdot \vec{b} = \sum_{i=1}^{n} a_i b_i$
+- **向量范数:** $||\vec{x}||_2 = \sqrt{\sum_{i=1}^{n} x_i^2}$(L2范数)
+
+```python
+import numpy as np
+
+# 创建向量
+a = np.array([1, 2, 3])
+b = np.array([4, 5, 6])
+
+# 向量加法
+print(a + b) # [5 7 9]
+
+# 标量乘法
+print(2 * a) # [2 4 6]
+
+# 点积
+print(np.dot(a, b)) # 32
+
+# L2范数
+print(np.linalg.norm(a)) # 3.7416...
+```
+
+### 1.2 矩阵 (Matrix)
+
+矩阵是一个二维数组,在机器学习中用于表示数据集、权重参数等。
+
+$$A = \begin{bmatrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{m1} & a_{m2} & \cdots & a_{mn} \end{bmatrix}$$
+
+**常用矩阵运算:**
+
+| 运算 | 描述 | 条件 |
+|------|------|------|
+| 矩阵加法 | 对应元素相加 | 相同形状 |
+| 矩阵乘法 | $C_{ij} = \sum_k A_{ik} B_{kj}$ | A的列数 = B的行数 |
+| 转置 | 行列互换 $A^T$ | 任意矩阵 |
+| 逆矩阵 | $A^{-1}A = I$ | 方阵且可逆 |
+
+```python
+import numpy as np
+
+# 创建矩阵
+A = np.array([[1, 2], [3, 4]])
+B = np.array([[5, 6], [7, 8]])
+
+# 矩阵乘法
+print(np.dot(A, B))
+# [[19 22]
+# [43 50]]
+
+# 转置
+print(A.T)
+# [[1 3]
+# [2 4]]
+
+# 逆矩阵
+print(np.linalg.inv(A))
+# [[-2. 1. ]
+# [ 1.5 -0.5]]
+
+# 特征值和特征向量
+eigenvalues, eigenvectors = np.linalg.eig(A)
+print("特征值:", eigenvalues)
+```
+
+::: tip 为什么重要?
+在神经网络中,前向传播本质上就是矩阵乘法:$y = Wx + b$,其中W是权重矩阵,x是输入向量,b是偏置向量。
+:::
+
+## 2. 微积分基础
+
+微积分在机器学习中主要用于优化算法,特别是梯度下降法。理解导数和偏导数对于理解模型训练过程至关重要。
+
+### 2.1 导数 (Derivative)
+
+导数表示函数在某一点的变化率,几何意义是曲线在该点的切线斜率。
+
+$$f'(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h}$$
+
+**常用导数公式:**
+
+- $\frac{d}{dx}(x^n) = nx^{n-1}$
+- $\frac{d}{dx}(e^x) = e^x$
+- $\frac{d}{dx}(\ln x) = \frac{1}{x}$
+- $\frac{d}{dx}(\sin x) = \cos x$
+
+### 2.2 偏导数与梯度
+
+对于多变量函数,偏导数表示函数对某一变量的变化率。梯度是所有偏导数组成的向量,指向函数增长最快的方向。
+
+$$\nabla f = \begin{bmatrix} \frac{\partial f}{\partial x_1} \\ \frac{\partial f}{\partial x_2} \\ \vdots \\ \frac{\partial f}{\partial x_n} \end{bmatrix}$$
+
+```python
+# 使用数值方法计算梯度
+import numpy as np
+
+def numerical_gradient(f, x, h=1e-5):
+ """计算函数f在点x处的数值梯度"""
+ grad = np.zeros_like(x)
+ for i in range(len(x)):
+ x_plus = x.copy()
+ x_minus = x.copy()
+ x_plus[i] += h
+ x_minus[i] -= h
+ grad[i] = (f(x_plus) - f(x_minus)) / (2 * h)
+ return grad
+
+# 示例:f(x, y) = x^2 + y^2
+def f(x):
+ return x[0]**2 + x[1]**2
+
+point = np.array([3.0, 4.0])
+print(numerical_gradient(f, point)) # [6. 8.]
+# 理论值:梯度 = [2x, 2y] = [6, 8]
+```
+
+### 2.3 链式法则
+
+链式法则是反向传播算法的数学基础,用于计算复合函数的导数。
+
+$$\frac{dz}{dx} = \frac{dz}{dy} \cdot \frac{dy}{dx}$$
+
+::: warning 核心概念
+神经网络的反向传播算法本质上就是链式法则的应用。通过链式法则,我们可以高效地计算损失函数对每个参数的梯度。
+:::
+
+## 3. 概率论与统计基础
+
+概率论为机器学习中的不确定性建模提供了数学框架,是理解贝叶斯学习、生成模型等的基础。
+
+### 3.1 基本概念
+
+- **概率:** 事件发生可能性的度量,范围[0, 1]
+- **条件概率:** $P(A|B) = \frac{P(A \cap B)}{P(B)}$
+- **贝叶斯定理:** $P(A|B) = \frac{P(B|A)P(A)}{P(B)}$
+
+### 3.2 常见概率分布
+
+| 分布 | 公式 | 应用场景 |
+|------|------|----------|
+| 伯努利分布 | $P(X=1) = p$ | 二分类问题 |
+| 高斯分布 | $f(x) = \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}$ | 连续变量建模 |
+| 多项式分布 | 伯努利分布的推广 | 多分类问题 |
+
+### 3.3 期望、方差与协方差
+
+- **期望(均值):** $E[X] = \sum_x x \cdot P(X=x)$
+- **方差:** $Var(X) = E[(X - E[X])^2]$
+- **协方差:** $Cov(X, Y) = E[(X - E[X])(Y - E[Y])]$
+
+```python
+import numpy as np
+from scipy import stats
+
+# 生成正态分布数据
+data = np.random.normal(loc=0, scale=1, size=1000)
+
+# 计算统计量
+print(f"均值: {np.mean(data):.4f}")
+print(f"方差: {np.var(data):.4f}")
+print(f"标准差: {np.std(data):.4f}")
+
+# 正态分布PDF
+x = np.linspace(-3, 3, 100)
+pdf = stats.norm.pdf(x, loc=0, scale=1)
+```
+
+## 4. 最优化基础
+
+机器学习模型训练的本质是求解优化问题,即找到使损失函数最小的参数。
+
+### 4.1 梯度下降法
+
+梯度下降是最常用的优化算法,通过沿着梯度的反方向迭代更新参数。
+
+$$\theta_{t+1} = \theta_t - \eta \nabla L(\theta_t)$$
+
+其中 $\eta$ 是学习率,$\nabla L$ 是损失函数的梯度。
+
+```python
+import numpy as np
+
+def gradient_descent(gradient_func, initial_params, learning_rate=0.01, epochs=100):
+ """基础梯度下降算法"""
+ params = initial_params.copy()
+ history = [params.copy()]
+
+ for _ in range(epochs):
+ grad = gradient_func(params)
+ params = params - learning_rate * grad
+ history.append(params.copy())
+
+ return params, history
+
+# 示例:最小化 f(x) = x^2
+def gradient(x):
+ return 2 * x
+
+x0 = np.array([5.0])
+optimal_x, history = gradient_descent(gradient, x0)
+print(f"最优解: {optimal_x[0]:.6f}") # 接近0
+```
+
+### 4.2 梯度下降的变体
+
+| 算法 | 特点 |
+|------|------|
+| 批量梯度下降 (BGD) | 使用全部数据计算梯度,稳定但慢 |
+| 随机梯度下降 (SGD) | 每次使用单个样本,快但不稳定 |
+| 小批量梯度下降 | 折中方案,最常用 |
+| Adam | 自适应学习率,深度学习首选 |
+
+## 5. 本章小结
+
+- **线性代数:** 向量和矩阵运算是数据表示和模型计算的基础
+- **微积分:** 导数和梯度用于模型优化,链式法则是反向传播的核心
+- **概率统计:** 为不确定性建模提供数学框架
+- **最优化:** 梯度下降法是训练模型的核心算法
+
+::: info 推荐学习资源
+- 3Blue1Brown《线性代数的本质》视频系列
+- 《深度学习》(花书)第2-4章数学基础
+- Khan Academy 微积分和概率统计课程
+:::
diff --git a/docs/chapters/prerequisites/python-scientific.md b/docs/chapters/prerequisites/python-scientific.md
new file mode 100644
index 0000000..9f809ac
--- /dev/null
+++ b/docs/chapters/prerequisites/python-scientific.md
@@ -0,0 +1,398 @@
+# Python科学计算
+
+::: info 本章概述
+Python是AI和机器学习领域最流行的编程语言。本章介绍NumPy、Pandas、Matplotlib这三个核心科学计算库的基础用法。
+:::
+
+## 1. NumPy - 数值计算基础
+
+NumPy(Numerical Python)是Python科学计算的基础包,提供了高效的多维数组对象和各种数学函数。
+
+### 1.1 创建数组
+
+```python
+import numpy as np
+
+# 从列表创建数组
+arr = np.array([1, 2, 3, 4, 5])
+print(arr) # [1 2 3 4 5]
+
+# 创建二维数组
+matrix = np.array([[1, 2, 3], [4, 5, 6]])
+print(matrix.shape) # (2, 3)
+
+# 常用创建函数
+zeros = np.zeros((3, 4)) # 全零数组
+ones = np.ones((2, 3)) # 全一数组
+eye = np.eye(3) # 单位矩阵
+rand = np.random.rand(3, 3) # 随机数组 [0, 1)
+randn = np.random.randn(3, 3) # 标准正态分布
+
+# 等间隔数组
+linspace = np.linspace(0, 10, 5) # [0, 2.5, 5, 7.5, 10]
+arange = np.arange(0, 10, 2) # [0, 2, 4, 6, 8]
+```
+
+### 1.2 数组属性与索引
+
+```python
+arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
+
+# 数组属性
+print(arr.shape) # (3, 3) - 形状
+print(arr.dtype) # int64 - 数据类型
+print(arr.size) # 9 - 元素总数
+print(arr.ndim) # 2 - 维度数
+
+# 索引和切片
+print(arr[0, 0]) # 1 - 单个元素
+print(arr[0, :]) # [1 2 3] - 第一行
+print(arr[:, 1]) # [2 5 8] - 第二列
+print(arr[0:2, 1:3]) # 子矩阵
+
+# 布尔索引
+print(arr[arr > 5]) # [6 7 8 9]
+
+# 花式索引
+print(arr[[0, 2], :]) # 第0行和第2行
+```
+
+### 1.3 数组运算
+
+```python
+a = np.array([1, 2, 3])
+b = np.array([4, 5, 6])
+
+# 逐元素运算
+print(a + b) # [5 7 9]
+print(a * b) # [4 10 18]
+print(a ** 2) # [1 4 9]
+print(np.sqrt(a)) # [1. 1.414 1.732]
+
+# 矩阵运算
+A = np.array([[1, 2], [3, 4]])
+B = np.array([[5, 6], [7, 8]])
+
+print(np.dot(A, B)) # 矩阵乘法
+print(A @ B) # 矩阵乘法(Python 3.5+)
+print(A * B) # 逐元素乘法
+
+# 聚合运算
+arr = np.array([[1, 2, 3], [4, 5, 6]])
+print(np.sum(arr)) # 21 - 总和
+print(np.sum(arr, axis=0)) # [5 7 9] - 按列求和
+print(np.sum(arr, axis=1)) # [6 15] - 按行求和
+print(np.mean(arr)) # 3.5 - 均值
+print(np.max(arr)) # 6 - 最大值
+print(np.argmax(arr)) # 5 - 最大值索引
+```
+
+### 1.4 广播机制
+
+广播(Broadcasting)允许NumPy在形状不同的数组间进行算术运算。
+
+```python
+# 广播示例
+a = np.array([[1, 2, 3], [4, 5, 6]]) # 形状 (2, 3)
+b = np.array([10, 20, 30]) # 形状 (3,)
+
+# b被"广播"成 [[10, 20, 30], [10, 20, 30]]
+print(a + b)
+# [[11 22 33]
+# [14 25 36]]
+
+# 标量广播
+print(a * 2)
+# [[ 2 4 6]
+# [ 8 10 12]]
+```
+
+::: tip 广播规则
+1. 如果两个数组维度数不同,在维度少的数组前面补1
+2. 在任一维度上,大小为1的可以与任意大小匹配
+3. 两个数组在所有维度上兼容才能广播
+:::
+
+## 2. Pandas - 数据处理利器
+
+Pandas提供了DataFrame和Series两种数据结构,非常适合处理表格型数据。
+
+### 2.1 数据结构
+
+```python
+import pandas as pd
+
+# Series - 一维数据
+s = pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])
+print(s['a']) # 1
+
+# DataFrame - 二维表格数据
+df = pd.DataFrame({
+ 'name': ['Alice', 'Bob', 'Charlie'],
+ 'age': [25, 30, 35],
+ 'city': ['北京', '上海', '广州']
+})
+print(df)
+# name age city
+# 0 Alice 25 北京
+# 1 Bob 30 上海
+# 2 Charlie 35 广州
+
+# 从文件读取
+# df = pd.read_csv('data.csv')
+# df = pd.read_excel('data.xlsx')
+```
+
+### 2.2 数据选择与过滤
+
+```python
+# 创建示例数据
+df = pd.DataFrame({
+ 'name': ['Alice', 'Bob', 'Charlie', 'David'],
+ 'age': [25, 30, 35, 28],
+ 'salary': [50000, 60000, 70000, 55000]
+})
+
+# 选择列
+print(df['name']) # 单列,返回Series
+print(df[['name', 'age']]) # 多列,返回DataFrame
+
+# 选择行
+print(df.iloc[0]) # 按位置索引
+print(df.loc[0]) # 按标签索引
+print(df.iloc[0:2]) # 切片
+
+# 条件过滤
+print(df[df['age'] > 28]) # age大于28的行
+print(df[(df['age'] > 25) & (df['salary'] > 55000)])
+
+# 使用query方法
+print(df.query('age > 28 and salary > 55000'))
+```
+
+### 2.3 数据处理
+
+```python
+# 处理缺失值
+df = pd.DataFrame({
+ 'A': [1, 2, None, 4],
+ 'B': [5, None, 7, 8]
+})
+
+print(df.isnull().sum()) # 统计缺失值
+df_filled = df.fillna(0) # 填充缺失值
+df_dropped = df.dropna() # 删除含缺失值的行
+
+# 数据转换
+df['A'] = df['A'].astype(float) # 类型转换
+
+# 应用函数
+df['A_squared'] = df['A'].apply(lambda x: x**2 if pd.notna(x) else None)
+
+# 分组聚合
+df = pd.DataFrame({
+ 'category': ['A', 'A', 'B', 'B'],
+ 'value': [10, 20, 30, 40]
+})
+print(df.groupby('category')['value'].mean())
+# category
+# A 15.0
+# B 35.0
+
+# 排序
+df_sorted = df.sort_values('value', ascending=False)
+```
+
+### 2.4 合并数据
+
+```python
+# 合并DataFrame
+df1 = pd.DataFrame({'id': [1, 2], 'name': ['A', 'B']})
+df2 = pd.DataFrame({'id': [1, 2], 'score': [90, 85]})
+
+# merge - 类似SQL JOIN
+merged = pd.merge(df1, df2, on='id')
+
+# concat - 拼接
+df3 = pd.concat([df1, df1], axis=0) # 垂直拼接
+df4 = pd.concat([df1, df2], axis=1) # 水平拼接
+```
+
+## 3. Matplotlib - 数据可视化
+
+Matplotlib是Python最基础的绘图库,可以创建各种静态、动态和交互式图表。
+
+### 3.1 基础绘图
+
+```python
+import matplotlib.pyplot as plt
+import numpy as np
+
+# 折线图
+x = np.linspace(0, 10, 100)
+y = np.sin(x)
+
+plt.figure(figsize=(10, 6))
+plt.plot(x, y, label='sin(x)', color='blue', linestyle='-')
+plt.plot(x, np.cos(x), label='cos(x)', color='red', linestyle='--')
+plt.xlabel('x')
+plt.ylabel('y')
+plt.title('三角函数图像')
+plt.legend()
+plt.grid(True)
+plt.savefig('plot.png')
+plt.show()
+```
+
+### 3.2 常用图表类型
+
+```python
+# 散点图
+plt.scatter(x, y, c='blue', alpha=0.5)
+
+# 柱状图
+categories = ['A', 'B', 'C', 'D']
+values = [23, 45, 56, 78]
+plt.bar(categories, values)
+
+# 直方图
+data = np.random.randn(1000)
+plt.hist(data, bins=30, edgecolor='black')
+
+# 饼图
+sizes = [15, 30, 45, 10]
+labels = ['A', 'B', 'C', 'D']
+plt.pie(sizes, labels=labels, autopct='%1.1f%%')
+
+# 热力图
+data = np.random.rand(10, 10)
+plt.imshow(data, cmap='hot')
+plt.colorbar()
+```
+
+### 3.3 子图布局
+
+```python
+# 创建子图
+fig, axes = plt.subplots(2, 2, figsize=(12, 10))
+
+# 在各子图中绘制
+axes[0, 0].plot(x, np.sin(x))
+axes[0, 0].set_title('Sin')
+
+axes[0, 1].plot(x, np.cos(x))
+axes[0, 1].set_title('Cos')
+
+axes[1, 0].plot(x, np.tan(x))
+axes[1, 0].set_title('Tan')
+
+axes[1, 1].plot(x, np.exp(-x))
+axes[1, 1].set_title('Exp')
+
+plt.tight_layout()
+plt.show()
+```
+
+::: tip 可视化最佳实践
+- 始终添加标题、轴标签和图例
+- 选择合适的图表类型展示数据
+- 使用适当的配色方案
+- 保持图表简洁,避免信息过载
+:::
+
+## 4. Seaborn - 统计可视化
+
+Seaborn是基于Matplotlib的高级可视化库,特别适合统计数据可视化。
+
+```python
+import seaborn as sns
+
+# 使用内置数据集
+tips = sns.load_dataset('tips')
+
+# 分布图
+sns.histplot(tips['total_bill'], kde=True)
+
+# 散点图带回归线
+sns.regplot(x='total_bill', y='tip', data=tips)
+
+# 箱线图
+sns.boxplot(x='day', y='total_bill', data=tips)
+
+# 热力图(相关性矩阵)
+corr = tips.select_dtypes(include=[np.number]).corr()
+sns.heatmap(corr, annot=True, cmap='coolwarm')
+
+# 成对关系图
+sns.pairplot(tips, hue='sex')
+```
+
+## 5. 实战练习
+
+::: details 练习:探索性数据分析
+
+```python
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+
+# 1. 创建模拟数据
+np.random.seed(42)
+n_samples = 200
+
+data = pd.DataFrame({
+ 'feature1': np.random.randn(n_samples),
+ 'feature2': np.random.randn(n_samples) * 2,
+ 'target': np.random.randint(0, 2, n_samples)
+})
+
+# 添加一些特征间的关系
+data['feature3'] = data['feature1'] * 2 + np.random.randn(n_samples) * 0.5
+
+# 2. 数据探索
+print("数据形状:", data.shape)
+print("\n数据统计:")
+print(data.describe())
+print("\n缺失值:")
+print(data.isnull().sum())
+
+# 3. 可视化
+fig, axes = plt.subplots(2, 2, figsize=(12, 10))
+
+# 特征分布
+axes[0, 0].hist(data['feature1'], bins=20, edgecolor='black')
+axes[0, 0].set_title('Feature1 分布')
+
+# 散点图
+axes[0, 1].scatter(data['feature1'], data['feature3'],
+ c=data['target'], cmap='coolwarm', alpha=0.6)
+axes[0, 1].set_xlabel('feature1')
+axes[0, 1].set_ylabel('feature3')
+axes[0, 1].set_title('Feature1 vs Feature3')
+
+# 箱线图
+data.boxplot(column=['feature1', 'feature2', 'feature3'], ax=axes[1, 0])
+axes[1, 0].set_title('特征箱线图')
+
+# 相关性热力图
+corr = data.corr()
+im = axes[1, 1].imshow(corr, cmap='coolwarm')
+axes[1, 1].set_xticks(range(len(corr.columns)))
+axes[1, 1].set_yticks(range(len(corr.columns)))
+axes[1, 1].set_xticklabels(corr.columns)
+axes[1, 1].set_yticklabels(corr.columns)
+axes[1, 1].set_title('相关性矩阵')
+plt.colorbar(im, ax=axes[1, 1])
+
+plt.tight_layout()
+plt.savefig('eda_example.png', dpi=150)
+plt.show()
+```
+:::
+
+## 6. 本章小结
+
+- **NumPy:** 高效的数组运算,是所有科学计算库的基础
+- **Pandas:** 强大的数据处理能力,适合表格数据的清洗和分析
+- **Matplotlib:** 基础可视化工具,支持各种图表类型
+- **Seaborn:** 高级统计可视化,更美观的默认样式
diff --git a/docs/chapters/projects/house-price.md b/docs/chapters/projects/house-price.md
new file mode 100644
index 0000000..9e3a0ad
--- /dev/null
+++ b/docs/chapters/projects/house-price.md
@@ -0,0 +1,351 @@
+# 房价预测实战
+
+::: info 项目概述
+本项目将使用加州房价数据集,完整演示一个机器学习项目的全流程:数据探索、特征工程、模型训练、评估和优化。
+:::
+
+## 1. 项目背景
+
+房价预测是经典的回归问题。我们的目标是根据房屋的各种特征(如位置、面积、房龄等)预测其价格。
+
+### 1.1 数据集介绍
+
+我们使用加州房价数据集(California Housing Dataset),包含以下特征:
+
+| 特征 | 描述 |
+|------|------|
+| MedInc | 街区居民收入中位数 |
+| HouseAge | 房屋年龄中位数 |
+| AveRooms | 平均房间数 |
+| AveBedrms | 平均卧室数 |
+| Population | 街区人口 |
+| AveOccup | 平均入住人数 |
+| Latitude | 纬度 |
+| Longitude | 经度 |
+
+## 2. 数据探索(EDA)
+
+```python
+import numpy as np
+import pandas as pd
+import matplotlib.pyplot as plt
+import seaborn as sns
+from sklearn.datasets import fetch_california_housing
+
+# 加载数据
+housing = fetch_california_housing()
+df = pd.DataFrame(housing.data, columns=housing.feature_names)
+df['MedHouseVal'] = housing.target # 目标变量:房价中位数(单位:10万美元)
+
+print("数据形状:", df.shape)
+print("\n数据预览:")
+print(df.head())
+
+print("\n基本统计信息:")
+print(df.describe())
+
+print("\n缺失值检查:")
+print(df.isnull().sum())
+```
+
+### 2.1 数据分布可视化
+
+```python
+# 目标变量分布
+plt.figure(figsize=(12, 4))
+
+plt.subplot(1, 2, 1)
+plt.hist(df['MedHouseVal'], bins=50, edgecolor='black')
+plt.xlabel('房价中位数(10万美元)')
+plt.ylabel('频数')
+plt.title('房价分布')
+
+plt.subplot(1, 2, 2)
+df['MedHouseVal'].plot(kind='box')
+plt.ylabel('房价中位数')
+plt.title('房价箱线图')
+
+plt.tight_layout()
+plt.show()
+
+# 特征分布
+fig, axes = plt.subplots(2, 4, figsize=(16, 8))
+for i, col in enumerate(housing.feature_names):
+ ax = axes[i // 4, i % 4]
+ df[col].hist(bins=30, ax=ax, edgecolor='black')
+ ax.set_title(col)
+plt.tight_layout()
+plt.show()
+```
+
+### 2.2 相关性分析
+
+```python
+# 相关性矩阵
+plt.figure(figsize=(10, 8))
+corr_matrix = df.corr()
+sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0, fmt='.2f')
+plt.title('特征相关性矩阵')
+plt.tight_layout()
+plt.show()
+
+# 与目标变量的相关性
+print("\n与房价的相关性:")
+print(corr_matrix['MedHouseVal'].sort_values(ascending=False))
+```
+
+### 2.3 地理分布可视化
+
+```python
+# 地理位置与房价的关系
+plt.figure(figsize=(12, 8))
+plt.scatter(df['Longitude'], df['Latitude'],
+ c=df['MedHouseVal'], cmap='viridis',
+ alpha=0.5, s=df['Population']/100)
+plt.colorbar(label='房价中位数')
+plt.xlabel('经度')
+plt.ylabel('纬度')
+plt.title('加州房价地理分布')
+plt.show()
+```
+
+## 3. 数据预处理
+
+```python
+from sklearn.model_selection import train_test_split
+from sklearn.preprocessing import StandardScaler
+
+# 分离特征和目标
+X = df.drop('MedHouseVal', axis=1)
+y = df['MedHouseVal']
+
+# 划分训练集和测试集
+X_train, X_test, y_train, y_test = train_test_split(
+ X, y, test_size=0.2, random_state=42
+)
+
+print(f"训练集大小: {X_train.shape[0]}")
+print(f"测试集大小: {X_test.shape[0]}")
+
+# 特征标准化
+scaler = StandardScaler()
+X_train_scaled = scaler.fit_transform(X_train)
+X_test_scaled = scaler.transform(X_test)
+
+print("\n标准化后的特征统计:")
+print(f"均值: {X_train_scaled.mean(axis=0).round(2)}")
+print(f"标准差: {X_train_scaled.std(axis=0).round(2)}")
+```
+
+## 4. 模型训练与比较
+
+```python
+from sklearn.linear_model import LinearRegression, Ridge, Lasso
+from sklearn.tree import DecisionTreeRegressor
+from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
+from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
+import time
+
+# 定义评估函数
+def evaluate_model(model, X_train, X_test, y_train, y_test, name):
+ start = time.time()
+ model.fit(X_train, y_train)
+ train_time = time.time() - start
+
+ y_train_pred = model.predict(X_train)
+ y_test_pred = model.predict(X_test)
+
+ results = {
+ 'Model': name,
+ 'Train RMSE': np.sqrt(mean_squared_error(y_train, y_train_pred)),
+ 'Test RMSE': np.sqrt(mean_squared_error(y_test, y_test_pred)),
+ 'Train R²': r2_score(y_train, y_train_pred),
+ 'Test R²': r2_score(y_test, y_test_pred),
+ 'MAE': mean_absolute_error(y_test, y_test_pred),
+ 'Train Time': train_time
+ }
+ return results, model
+
+# 训练多个模型
+models = {
+ 'Linear Regression': LinearRegression(),
+ 'Ridge': Ridge(alpha=1.0),
+ 'Lasso': Lasso(alpha=0.1),
+ 'Decision Tree': DecisionTreeRegressor(max_depth=10, random_state=42),
+ 'Random Forest': RandomForestRegressor(n_estimators=100, max_depth=10, random_state=42),
+ 'Gradient Boosting': GradientBoostingRegressor(n_estimators=100, max_depth=5, random_state=42)
+}
+
+results_list = []
+trained_models = {}
+
+for name, model in models.items():
+ results, trained_model = evaluate_model(
+ model, X_train_scaled, X_test_scaled, y_train, y_test, name
+ )
+ results_list.append(results)
+ trained_models[name] = trained_model
+ print(f"{name}: Test R² = {results['Test R²']:.4f}, Test RMSE = {results['Test RMSE']:.4f}")
+
+# 结果汇总
+results_df = pd.DataFrame(results_list)
+print("\n模型对比:")
+print(results_df.to_string(index=False))
+```
+
+### 4.1 模型性能可视化
+
+```python
+# 模型对比图
+fig, axes = plt.subplots(1, 2, figsize=(14, 5))
+
+# R² 分数对比
+ax1 = axes[0]
+x = range(len(results_df))
+width = 0.35
+ax1.bar([i - width/2 for i in x], results_df['Train R²'], width, label='Train')
+ax1.bar([i + width/2 for i in x], results_df['Test R²'], width, label='Test')
+ax1.set_xlabel('模型')
+ax1.set_ylabel('R² Score')
+ax1.set_title('各模型R²分数对比')
+ax1.set_xticks(x)
+ax1.set_xticklabels(results_df['Model'], rotation=45, ha='right')
+ax1.legend()
+
+# RMSE 对比
+ax2 = axes[1]
+ax2.bar([i - width/2 for i in x], results_df['Train RMSE'], width, label='Train')
+ax2.bar([i + width/2 for i in x], results_df['Test RMSE'], width, label='Test')
+ax2.set_xlabel('模型')
+ax2.set_ylabel('RMSE')
+ax2.set_title('各模型RMSE对比')
+ax2.set_xticks(x)
+ax2.set_xticklabels(results_df['Model'], rotation=45, ha='right')
+ax2.legend()
+
+plt.tight_layout()
+plt.show()
+```
+
+## 5. 特征重要性分析
+
+```python
+# 使用随机森林的特征重要性
+rf_model = trained_models['Random Forest']
+
+feature_importance = pd.DataFrame({
+ 'Feature': housing.feature_names,
+ 'Importance': rf_model.feature_importances_
+}).sort_values('Importance', ascending=False)
+
+plt.figure(figsize=(10, 6))
+plt.barh(feature_importance['Feature'], feature_importance['Importance'])
+plt.xlabel('重要性')
+plt.title('随机森林特征重要性')
+plt.gca().invert_yaxis()
+plt.tight_layout()
+plt.show()
+
+print("特征重要性排名:")
+print(feature_importance)
+```
+
+## 6. 超参数调优
+
+```python
+from sklearn.model_selection import GridSearchCV, cross_val_score
+
+# 对随机森林进行超参数调优
+param_grid_small = {
+ 'n_estimators': [100, 200],
+ 'max_depth': [10, 15],
+ 'min_samples_split': [2, 5]
+}
+
+rf = RandomForestRegressor(random_state=42)
+grid_search = GridSearchCV(
+ rf, param_grid_small, cv=5, scoring='r2', n_jobs=-1, verbose=1
+)
+grid_search.fit(X_train_scaled, y_train)
+
+print(f"\n最佳参数: {grid_search.best_params_}")
+print(f"最佳交叉验证R²: {grid_search.best_score_:.4f}")
+
+# 用最佳模型评估
+best_model = grid_search.best_estimator_
+y_pred = best_model.predict(X_test_scaled)
+print(f"测试集R²: {r2_score(y_test, y_pred):.4f}")
+print(f"测试集RMSE: {np.sqrt(mean_squared_error(y_test, y_pred)):.4f}")
+```
+
+## 7. 预测结果分析
+
+```python
+# 使用最佳模型进行预测
+y_pred = best_model.predict(X_test_scaled)
+
+# 预测值 vs 真实值
+plt.figure(figsize=(10, 5))
+
+plt.subplot(1, 2, 1)
+plt.scatter(y_test, y_pred, alpha=0.5)
+plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], 'r--', lw=2)
+plt.xlabel('真实值')
+plt.ylabel('预测值')
+plt.title('预测值 vs 真实值')
+
+# 残差分布
+plt.subplot(1, 2, 2)
+residuals = y_test - y_pred
+plt.hist(residuals, bins=50, edgecolor='black')
+plt.xlabel('残差')
+plt.ylabel('频数')
+plt.title('残差分布')
+plt.axvline(x=0, color='r', linestyle='--')
+
+plt.tight_layout()
+plt.show()
+
+# 残差统计
+print(f"残差均值: {residuals.mean():.4f}")
+print(f"残差标准差: {residuals.std():.4f}")
+```
+
+## 8. 模型保存与加载
+
+```python
+import joblib
+
+# 保存模型和标准化器
+joblib.dump(best_model, 'house_price_model.pkl')
+joblib.dump(scaler, 'scaler.pkl')
+print("模型已保存!")
+
+# 加载模型
+loaded_model = joblib.load('house_price_model.pkl')
+loaded_scaler = joblib.load('scaler.pkl')
+
+# 使用加载的模型进行预测
+new_data = np.array([[8.3, 41, 6.98, 1.02, 322, 2.56, 37.88, -122.23]])
+new_data_scaled = loaded_scaler.transform(new_data)
+prediction = loaded_model.predict(new_data_scaled)
+print(f"预测房价: ${prediction[0] * 100000:.2f}")
+```
+
+## 9. 项目总结
+
+::: tip 关键收获
+- **数据探索**:理解数据分布和特征关系是建模的基础
+- **特征工程**:标准化对某些算法至关重要
+- **模型比较**:集成方法(如随机森林)通常优于单一模型
+- **超参数调优**:可以进一步提升模型性能
+- **模型评估**:关注训练集和测试集的差距,避免过拟合
+:::
+
+### 9.1 进一步改进方向
+
+- 尝试更多特征工程(如交叉特征、多项式特征)
+- 使用XGBoost或LightGBM等更强的模型
+- 进行更细致的超参数调优
+- 尝试神经网络模型
+- 集成多个模型(Stacking)
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..d04f584
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,41 @@
+---
+layout: home
+
+hero:
+ name: "AI学习之路"
+ text: "人工智能入门学习教程"
+ tagline: 面向软件工程专业毕业生的系统性AI学习路径
+ actions:
+ - theme: brand
+ text: 开始学习
+ link: /chapters/prerequisites/math
+ - theme: alt
+ text: 查看大纲
+ link: /outline
+
+features:
+ - icon: 🎯
+ title: 目标人群
+ details: 专为具有编程基础的学习者设计,特别适合刚毕业的软件工程专业学生。无需从零学习编程语法,直接进入AI核心概念。
+ - icon: 🛤️
+ title: 学习路径
+ details: 从必要的前置知识开始,逐步深入到机器学习和深度学习的核心算法,最后通过实战项目巩固所学。
+ - icon: 💻
+ title: 实战导向
+ details: 每个章节都配有完整的代码示例和可视化演示,帮助你在实践中理解抽象概念。
+ - icon: 📚
+ title: 参考资源
+ details: 本教程参考了吴恩达课程、李沐《动手学深度学习》、Fast.ai等业界顶尖资源,并结合中文学习者特点进行编排。
+---
+
+
diff --git a/docs/outline.md b/docs/outline.md
new file mode 100644
index 0000000..0a2a7aa
--- /dev/null
+++ b/docs/outline.md
@@ -0,0 +1,66 @@
+# 学习大纲
+
+本教程专为具有编程基础的软件工程毕业生设计,系统性地介绍人工智能和机器学习的核心概念与实践技能。
+
+## 第0章:前置知识
+
+在正式学习AI之前,需要补充一些必要的基础知识。
+
+| 章节 | 主要内容 | 预计时间 |
+|------|----------|----------|
+| [数学基础](/chapters/prerequisites/math) | 线性代数、微积分、概率论与统计 | 45分钟 |
+| [Python科学计算](/chapters/prerequisites/python-scientific) | NumPy、Pandas、Matplotlib基础 | 40分钟 |
+| [数据处理基础](/chapters/prerequisites/data-processing) | 数据预处理、特征工程入门 | 35分钟 |
+
+## 第1章:AI基础概念
+
+建立对人工智能领域的整体认识。
+
+| 章节 | 主要内容 | 预计时间 |
+|------|----------|----------|
+| [什么是人工智能](/chapters/basics/what-is-ai) | AI的定义、发展历史与分类 | 30分钟 |
+| [机器学习概述](/chapters/basics/ml-overview) | 监督学习、无监督学习、强化学习 | 35分钟 |
+| [开发环境搭建](/chapters/basics/environment-setup) | Anaconda、Jupyter、GPU配置 | 25分钟 |
+
+## 第2章:机器学习入门
+
+学习经典机器学习算法的原理和实现。
+
+| 章节 | 主要内容 | 预计时间 |
+|------|----------|----------|
+| [线性回归](/chapters/machine-learning/linear-regression) | 模型原理、梯度下降、代码实现 | 45分钟 |
+
+::: tip 更多章节开发中
+逻辑回归与分类、决策树与集成学习、模型评估与优化等章节即将上线。
+:::
+
+## 第3章:深度学习入门
+
+探索神经网络和深度学习的世界。
+
+| 章节 | 主要内容 | 预计时间 |
+|------|----------|----------|
+| [神经网络基础](/chapters/deep-learning/neural-networks) | 感知机、激活函数、反向传播 | 50分钟 |
+
+::: tip 更多章节开发中
+深度学习框架、CNN、RNN、Transformer等章节即将上线。
+:::
+
+## 第4章:实战项目
+
+通过完整项目巩固所学知识。
+
+| 章节 | 主要内容 | 预计时间 |
+|------|----------|----------|
+| [房价预测](/chapters/projects/house-price) | 完整的回归任务流程 | 60分钟 |
+
+::: tip 更多项目开发中
+图像分类器、情感分析等项目即将上线。
+:::
+
+## 学习建议
+
+1. **按顺序学习**:建议按照章节顺序学习,因为后续内容会依赖前面的知识
+2. **动手实践**:每个章节的代码示例都要亲自运行,理解每一行的作用
+3. **做笔记**:记录关键概念和自己的理解,有助于加深记忆
+4. **完成项目**:实战项目是检验学习效果的最佳方式
diff --git a/docs/public/logo.svg b/docs/public/logo.svg
new file mode 100644
index 0000000..1f3124a
--- /dev/null
+++ b/docs/public/logo.svg
@@ -0,0 +1,18 @@
+
diff --git a/docs/resources.md b/docs/resources.md
new file mode 100644
index 0000000..524e9f9
--- /dev/null
+++ b/docs/resources.md
@@ -0,0 +1,110 @@
+# 推荐资源
+
+学习AI不仅需要系统的教程,还需要参考优质的外部资源。以下是经过精选的推荐资源列表。
+
+## 📹 视频课程
+
+### 入门课程
+
+| 课程 | 讲师/机构 | 特点 |
+|------|-----------|------|
+| **机器学习** | 吴恩达 (Coursera) | 经典入门课程,讲解清晰 |
+| **动手学深度学习** | 李沐 (B站) | 中文讲解,代码实践丰富 |
+| **Deep Learning Specialization** | 吴恩达 (Coursera) | 系统性深度学习课程 |
+| **Practical Deep Learning** | Fast.ai | 实战导向,快速上手 |
+| **Introduction to Deep Learning** | MIT | 学术性强,理论深入 |
+
+### 进阶课程
+
+| 课程 | 讲师/机构 | 特点 |
+|------|-----------|------|
+| **CS231n** | Stanford | 计算机视觉经典课程 |
+| **CS224n** | Stanford | 自然语言处理经典课程 |
+| **强化学习** | David Silver | 强化学习入门首选 |
+
+## 📚 经典书籍
+
+### 机器学习
+
+| 书籍 | 作者 | 难度 |
+|------|------|------|
+| **《机器学习》(西瓜书)** | 周志华 | ⭐⭐⭐ |
+| **《统计学习方法》** | 李航 | ⭐⭐⭐⭐ |
+| **《Pattern Recognition and Machine Learning》** | Bishop | ⭐⭐⭐⭐⭐ |
+
+### 深度学习
+
+| 书籍 | 作者 | 难度 |
+|------|------|------|
+| **《深度学习》(花书)** | Ian Goodfellow | ⭐⭐⭐⭐ |
+| **《动手学深度学习》** | 李沐等 | ⭐⭐⭐ |
+| **《神经网络与深度学习》** | 邱锡鹏 | ⭐⭐⭐ |
+
+### 实践指南
+
+| 书籍 | 作者 | 难度 |
+|------|------|------|
+| **《Python机器学习》** | Sebastian Raschka | ⭐⭐⭐ |
+| **《Hands-On Machine Learning》** | Aurélien Géron | ⭐⭐⭐ |
+
+## 💻 实践平台
+
+| 平台 | 描述 | 链接 |
+|------|------|------|
+| **Kaggle** | 数据科学竞赛平台,提供免费数据集和GPU | [kaggle.com](https://www.kaggle.com) |
+| **Google Colab** | 免费的云端Jupyter环境,提供免费GPU | [colab.research.google.com](https://colab.research.google.com) |
+| **天池** | 阿里云AI竞赛平台 | [tianchi.aliyun.com](https://tianchi.aliyun.com) |
+| **HuggingFace** | 模型和数据集仓库 | [huggingface.co](https://huggingface.co) |
+
+## 🔧 常用工具
+
+### 深度学习框架
+
+| 工具 | 特点 |
+|------|------|
+| **PyTorch** | 动态图,调试方便,学术界首选 |
+| **TensorFlow** | 静态图,部署方便,工业界常用 |
+| **JAX** | 函数式编程,高性能计算 |
+
+### 数据处理
+
+| 工具 | 用途 |
+|------|------|
+| **NumPy** | 数值计算基础 |
+| **Pandas** | 表格数据处理 |
+| **Scikit-learn** | 经典机器学习算法库 |
+
+### 可视化
+
+| 工具 | 用途 |
+|------|------|
+| **Matplotlib** | 基础绑图 |
+| **Seaborn** | 统计可视化 |
+| **TensorBoard** | 训练过程可视化 |
+| **Weights & Biases** | 实验跟踪和可视化 |
+
+## 🌐 社区资源
+
+| 社区 | 描述 |
+|------|------|
+| **知乎** | 中文AI技术讨论 |
+| **CSDN** | 技术博客和教程 |
+| **GitHub** | 开源项目和代码 |
+| **arXiv** | 最新学术论文 |
+| **Papers with Code** | 论文配套代码 |
+
+## 🎯 学习路径建议
+
+::: info 初学者路径
+1. 先学习 Python 基础和科学计算库
+2. 完成吴恩达《机器学习》课程
+3. 阅读《机器学习》(西瓜书)前几章
+4. 参加 Kaggle 入门竞赛
+:::
+
+::: info 进阶路径
+1. 学习《动手学深度学习》
+2. 根据兴趣选择 CV 或 NLP 方向
+3. 阅读经典论文,复现关键算法
+4. 参与开源项目或实际业务
+:::
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..ca438bc
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2951 @@
+{
+ "name": "learn-ai",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "learn-ai",
+ "version": "1.0.0",
+ "license": "ISC",
+ "devDependencies": {
+ "markdown-it-mathjax3": "^4.3.2",
+ "vitepress": "^1.6.4"
+ }
+ },
+ "node_modules/@algolia/abtesting": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.11.0.tgz",
+ "integrity": "sha512-a7oQ8dwiyoyVmzLY0FcuBqyqcNSq78qlcOtHmNBumRlHCSnXDcuoYGBGPN1F6n8JoGhviDDsIaF/oQrzTzs6Lg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.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.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.45.0.tgz",
+ "integrity": "sha512-WTW0VZA8xHMbzuQD5b3f41ovKZ0MNTIXkWfm0F2PU+XGcLxmxX15UqODzF2sWab0vSbi3URM1xLhJx+bXbd1eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-analytics": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.45.0.tgz",
+ "integrity": "sha512-I3g7VtvG/QJOH3tQO7E7zWTwBfK/nIQXShFLR8RvPgWburZ626JNj332M3wHCYcaAMivN9WJG66S2JNXhm6+Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-common": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.45.0.tgz",
+ "integrity": "sha512-/nTqm1tLiPtbUr+8kHKyFiCOfhRfgC+JxLvOCq471gFZZOlsh6VtFRiKI60/zGmHTojFC6B0mD80PB7KeK94og==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-insights": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.45.0.tgz",
+ "integrity": "sha512-suQTx/1bRL1g/K2hRtbK3ANmbzaZCi13487sxxmqok+alBDKKw0/TI73ZiHjjFXM2NV52inwwcmW4fUR45206Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-personalization": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.45.0.tgz",
+ "integrity": "sha512-CId/dbjpzI3eoUhPU6rt/z4GrRsDesqFISEMOwrqWNSrf4FJhiUIzN42Ac+Gzg69uC0RnzRYy60K1y4Na5VSMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-query-suggestions": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.45.0.tgz",
+ "integrity": "sha512-tjbBKfA8fjAiFtvl9g/MpIPiD6pf3fj7rirVfh1eMIUi8ybHP4ovDzIaE216vHuRXoePQVCkMd2CokKvYq1CLw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/client-search": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.45.0.tgz",
+ "integrity": "sha512-nxuCid+Nszs4xqwIMDw11pRJPes2c+Th1yup/+LtpjFH8QWXkr3SirNYSD3OXAeM060HgWWPLA8/Fxk+vwxQOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/ingestion": {
+ "version": "1.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.45.0.tgz",
+ "integrity": "sha512-t+1doBzhkQTeOOjLHMlm4slmXBhvgtEGQhOmNpMPTnIgWOyZyESWdm+XD984qM4Ej1i9FRh8VttOGrdGnAjAng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/monitoring": {
+ "version": "1.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.45.0.tgz",
+ "integrity": "sha512-IaX3ZX1A/0wlgWZue+1BNWlq5xtJgsRo7uUk/aSiYD7lPbJ7dFuZ+yTLFLKgbl4O0QcyHTj1/mSBj9ryF1Lizg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/recommend": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.45.0.tgz",
+ "integrity": "sha512-1jeMLoOhkgezCCPsOqkScwYzAAc1Jr5T2hisZl0s32D94ZV7d1OHozBukgOjf8Dw+6Hgi6j52jlAdUWTtkX9Mg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-browser-xhr": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.45.0.tgz",
+ "integrity": "sha512-46FIoUkQ9N7wq4/YkHS5/W9Yjm4Ab+q5kfbahdyMpkBPJ7IBlwuNEGnWUZIQ6JfUZuJVojRujPRHMihX4awUMg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-fetch": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.45.0.tgz",
+ "integrity": "sha512-XFTSAtCwy4HdBhSReN2rhSyH/nZOM3q3qe5ERG2FLbYId62heIlJBGVyAPRbltRwNlotlydbvSJ+SQ0ruWC2cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@algolia/requester-node-http": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.45.0.tgz",
+ "integrity": "sha512-8mTg6lHx5i44raCU52APsu0EqMsdm4+7Hch/e4ZsYZw0hzwkuaMFh826ngnkYf9XOl58nHoou63aZ874m8AbpQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/client-common": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
+ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.28.5"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
+ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@docsearch/css": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz",
+ "integrity": "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@docsearch/js": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/js/-/js-3.8.2.tgz",
+ "integrity": "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@docsearch/react": "3.8.2",
+ "preact": "^10.0.0"
+ }
+ },
+ "node_modules/@docsearch/react": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.8.2.tgz",
+ "integrity": "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/autocomplete-core": "1.17.7",
+ "@algolia/autocomplete-preset-algolia": "1.17.7",
+ "@docsearch/css": "3.8.2",
+ "algoliasearch": "^5.14.2"
+ },
+ "peerDependencies": {
+ "@types/react": ">= 16.8.0 < 19.0.0",
+ "react": ">= 16.8.0 < 19.0.0",
+ "react-dom": ">= 16.8.0 < 19.0.0",
+ "search-insights": ">= 1 < 3"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "search-insights": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+ "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+ "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+ "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+ "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+ "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+ "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+ "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+ "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+ "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+ "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+ "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+ "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+ "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+ "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+ "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+ "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+ "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+ "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+ "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+ "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.21.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+ "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@iconify-json/simple-icons": {
+ "version": "1.2.60",
+ "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.60.tgz",
+ "integrity": "sha512-KlwLBKCdMCqfySdkAA+jehdUx6VSjnj6lvzQKus7HjkPSQ6QP58d6xiptkIp0jd/Hw3PW2++nRuGvCvSYaF0Mg==",
+ "dev": true,
+ "license": "CC0-1.0",
+ "dependencies": {
+ "@iconify/types": "*"
+ }
+ },
+ "node_modules/@iconify/types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+ "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz",
+ "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz",
+ "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz",
+ "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz",
+ "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz",
+ "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz",
+ "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz",
+ "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz",
+ "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz",
+ "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz",
+ "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz",
+ "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz",
+ "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz",
+ "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz",
+ "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz",
+ "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz",
+ "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz",
+ "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz",
+ "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz",
+ "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz",
+ "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz",
+ "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.53.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz",
+ "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@shikijs/core": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-2.5.0.tgz",
+ "integrity": "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/engine-javascript": "2.5.0",
+ "@shikijs/engine-oniguruma": "2.5.0",
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4",
+ "hast-util-to-html": "^9.0.4"
+ }
+ },
+ "node_modules/@shikijs/engine-javascript": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-2.5.0.tgz",
+ "integrity": "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "oniguruma-to-es": "^3.1.0"
+ }
+ },
+ "node_modules/@shikijs/engine-oniguruma": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-2.5.0.tgz",
+ "integrity": "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0",
+ "@shikijs/vscode-textmate": "^10.0.2"
+ }
+ },
+ "node_modules/@shikijs/langs": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-2.5.0.tgz",
+ "integrity": "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/themes": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-2.5.0.tgz",
+ "integrity": "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/transformers": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/transformers/-/transformers-2.5.0.tgz",
+ "integrity": "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/core": "2.5.0",
+ "@shikijs/types": "2.5.0"
+ }
+ },
+ "node_modules/@shikijs/types": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-2.5.0.tgz",
+ "integrity": "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@shikijs/vscode-textmate": "^10.0.2",
+ "@types/hast": "^3.0.4"
+ }
+ },
+ "node_modules/@shikijs/vscode-textmate": {
+ "version": "10.0.2",
+ "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz",
+ "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/hast": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
+ "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdast": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
+ "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/unist": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
+ "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@vitejs/plugin-vue": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
+ "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0",
+ "vue": "^3.2.25"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
+ "integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "@vue/shared": "3.5.25",
+ "entities": "^4.5.0",
+ "estree-walker": "^2.0.2",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-core/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/@vue/compiler-dom": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
+ "integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-core": "3.5.25",
+ "@vue/shared": "3.5.25"
+ }
+ },
+ "node_modules/@vue/compiler-sfc": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz",
+ "integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "@vue/compiler-core": "3.5.25",
+ "@vue/compiler-dom": "3.5.25",
+ "@vue/compiler-ssr": "3.5.25",
+ "@vue/shared": "3.5.25",
+ "estree-walker": "^2.0.2",
+ "magic-string": "^0.30.21",
+ "postcss": "^8.5.6",
+ "source-map-js": "^1.2.1"
+ }
+ },
+ "node_modules/@vue/compiler-ssr": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz",
+ "integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.25",
+ "@vue/shared": "3.5.25"
+ }
+ },
+ "node_modules/@vue/devtools-api": {
+ "version": "7.7.9",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.7.9.tgz",
+ "integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-kit": "^7.7.9"
+ }
+ },
+ "node_modules/@vue/devtools-kit": {
+ "version": "7.7.9",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz",
+ "integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/devtools-shared": "^7.7.9",
+ "birpc": "^2.3.0",
+ "hookable": "^5.5.3",
+ "mitt": "^3.0.1",
+ "perfect-debounce": "^1.0.0",
+ "speakingurl": "^14.0.1",
+ "superjson": "^2.2.2"
+ }
+ },
+ "node_modules/@vue/devtools-shared": {
+ "version": "7.7.9",
+ "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz",
+ "integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "rfdc": "^1.4.1"
+ }
+ },
+ "node_modules/@vue/reactivity": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.25.tgz",
+ "integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/shared": "3.5.25"
+ }
+ },
+ "node_modules/@vue/runtime-core": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.25.tgz",
+ "integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.25",
+ "@vue/shared": "3.5.25"
+ }
+ },
+ "node_modules/@vue/runtime-dom": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz",
+ "integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/reactivity": "3.5.25",
+ "@vue/runtime-core": "3.5.25",
+ "@vue/shared": "3.5.25",
+ "csstype": "^3.1.3"
+ }
+ },
+ "node_modules/@vue/server-renderer": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.25.tgz",
+ "integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-ssr": "3.5.25",
+ "@vue/shared": "3.5.25"
+ },
+ "peerDependencies": {
+ "vue": "3.5.25"
+ }
+ },
+ "node_modules/@vue/shared": {
+ "version": "3.5.25",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.25.tgz",
+ "integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
+ "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/@xmldom/xmldom": {
+ "version": "0.9.8",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz",
+ "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.6"
+ }
+ },
+ "node_modules/algoliasearch": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.45.0.tgz",
+ "integrity": "sha512-wrj4FGr14heLOYkBKV3Fbq5ZBGuIFeDJkTilYq/G+hH1CSlQBtYvG2X1j67flwv0fUeQJwnWxxRIunSemAZirA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@algolia/abtesting": "1.11.0",
+ "@algolia/client-abtesting": "5.45.0",
+ "@algolia/client-analytics": "5.45.0",
+ "@algolia/client-common": "5.45.0",
+ "@algolia/client-insights": "5.45.0",
+ "@algolia/client-personalization": "5.45.0",
+ "@algolia/client-query-suggestions": "5.45.0",
+ "@algolia/client-search": "5.45.0",
+ "@algolia/ingestion": "1.45.0",
+ "@algolia/monitoring": "1.45.0",
+ "@algolia/recommend": "5.45.0",
+ "@algolia/requester-browser-xhr": "5.45.0",
+ "@algolia/requester-fetch": "5.45.0",
+ "@algolia/requester-node-http": "5.45.0"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/birpc": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.8.0.tgz",
+ "integrity": "sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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/cheerio": {
+ "version": "1.0.0-rc.10",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz",
+ "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^1.5.0",
+ "dom-serializer": "^1.3.2",
+ "domhandler": "^4.2.0",
+ "htmlparser2": "^6.1.0",
+ "parse5": "^6.0.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.1",
+ "tslib": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz",
+ "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "css-select": "^4.3.0",
+ "css-what": "^6.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "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/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/copy-anything": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-4.0.5.tgz",
+ "integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-what": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
+ "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.0.1",
+ "domhandler": "^4.3.1",
+ "domutils": "^2.8.0",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "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/dom-serializer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz",
+ "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.2.0",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
+ "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.2.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
+ "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^1.0.1",
+ "domelementtype": "^2.2.0",
+ "domhandler": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "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": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "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/escape-goat": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz",
+ "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/esm": {
+ "version": "3.2.25",
+ "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz",
+ "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "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.6.6",
+ "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.6.6.tgz",
+ "integrity": "sha512-v/Z8bvMCajtx4mEXmOo7QEsIzlIOqRXTIwgUfsFOF9gEsespdbD0AkPIka1bSXZ8Y8oZ+2IVDQZePkTfEHZl7Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tabbable": "^6.3.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/hast-util-to-html": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz",
+ "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0",
+ "@types/unist": "^3.0.0",
+ "ccount": "^2.0.0",
+ "comma-separated-tokens": "^2.0.0",
+ "hast-util-whitespace": "^3.0.0",
+ "html-void-elements": "^3.0.0",
+ "mdast-util-to-hast": "^13.0.0",
+ "property-information": "^7.0.0",
+ "space-separated-tokens": "^2.0.0",
+ "stringify-entities": "^4.0.0",
+ "zwitch": "^2.0.4"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hast-util-whitespace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz",
+ "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/hast": "^3.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/html-void-elements": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz",
+ "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz",
+ "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==",
+ "dev": true,
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^4.0.0",
+ "domutils": "^2.5.2",
+ "entities": "^2.0.0"
+ }
+ },
+ "node_modules/is-what": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-5.5.0.tgz",
+ "integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/mesqueeb"
+ }
+ },
+ "node_modules/juice": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/juice/-/juice-8.1.0.tgz",
+ "integrity": "sha512-FLzurJrx5Iv1e7CfBSZH68dC04EEvXvvVvPYB7Vx1WAuhCp1ZPIMtqxc+WTWxVkpTIC2Ach/GAv0rQbtGf6YMA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cheerio": "1.0.0-rc.10",
+ "commander": "^6.1.0",
+ "mensch": "^0.3.4",
+ "slick": "^1.12.2",
+ "web-resource-inliner": "^6.0.1"
+ },
+ "bin": {
+ "juice": "bin/juice"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "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/markdown-it-mathjax3": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz",
+ "integrity": "sha512-TX3GW5NjmupgFtMJGRauioMbbkGsOXAAt1DZ/rzzYmTHqzkO1rNAdiMD4NiruurToPApn2kYy76x02QN26qr2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "juice": "^8.0.0",
+ "mathjax-full": "^3.2.0"
+ }
+ },
+ "node_modules/mathjax-full": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/mathjax-full/-/mathjax-full-3.2.1.tgz",
+ "integrity": "sha512-aUz9o16MGZdeiIBwZjAfUBTiJb7LRqzZEl1YOZ8zQMGYIyh1/nxRebxKxjDe9L+xcZCr2OHdzoFBMcd6VnLv9Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esm": "^3.2.25",
+ "mhchemparser": "^4.1.0",
+ "mj-context-menu": "^0.6.1",
+ "speech-rule-engine": "^4.0.6"
+ }
+ },
+ "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/mensch": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz",
+ "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/mhchemparser": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/mhchemparser/-/mhchemparser-4.2.1.tgz",
+ "integrity": "sha512-kYmyrCirqJf3zZ9t/0wGgRZ4/ZJw//VwaRVGA75C4nhE60vtnIzhl9J9ndkX/h6hxSN7pjg/cE0VxbnNM+bnDQ==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/micromark-util-character": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-encode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-sanitize-uri": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-util-symbol": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/micromark-util-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz",
+ "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/unifiedjs"
+ },
+ {
+ "type": "OpenCollective",
+ "url": "https://opencollective.com/unified"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "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/mj-context-menu": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/mj-context-menu/-/mj-context-menu-0.6.1.tgz",
+ "integrity": "sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA==",
+ "dev": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=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/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
+ "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.27.2",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz",
+ "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "node_modules/property-information": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz",
+ "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz",
+ "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==",
+ "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.53.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz",
+ "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.53.3",
+ "@rollup/rollup-android-arm64": "4.53.3",
+ "@rollup/rollup-darwin-arm64": "4.53.3",
+ "@rollup/rollup-darwin-x64": "4.53.3",
+ "@rollup/rollup-freebsd-arm64": "4.53.3",
+ "@rollup/rollup-freebsd-x64": "4.53.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.53.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.53.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.53.3",
+ "@rollup/rollup-linux-arm64-musl": "4.53.3",
+ "@rollup/rollup-linux-loong64-gnu": "4.53.3",
+ "@rollup/rollup-linux-ppc64-gnu": "4.53.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.53.3",
+ "@rollup/rollup-linux-riscv64-musl": "4.53.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.53.3",
+ "@rollup/rollup-linux-x64-gnu": "4.53.3",
+ "@rollup/rollup-linux-x64-musl": "4.53.3",
+ "@rollup/rollup-openharmony-arm64": "4.53.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.53.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.53.3",
+ "@rollup/rollup-win32-x64-gnu": "4.53.3",
+ "@rollup/rollup-win32-x64-msvc": "4.53.3",
+ "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/slick": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz",
+ "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==",
+ "dev": true,
+ "license": "MIT (http://mootools.net/license.txt)",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/space-separated-tokens": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz",
+ "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/speakingurl": {
+ "version": "14.0.1",
+ "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz",
+ "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/speech-rule-engine": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/speech-rule-engine/-/speech-rule-engine-4.1.2.tgz",
+ "integrity": "sha512-S6ji+flMEga+1QU79NDbwZ8Ivf0S/MpupQQiIC0rTpU/ZTKgcajijJJb1OcByBQDjrXCN1/DJtGz4ZJeBMPGJw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@xmldom/xmldom": "0.9.8",
+ "commander": "13.1.0",
+ "wicked-good-xpath": "1.3.0"
+ },
+ "bin": {
+ "sre": "bin/sre"
+ }
+ },
+ "node_modules/speech-rule-engine/node_modules/commander": {
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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.3.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.3.0.tgz",
+ "integrity": "sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "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/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "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.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz",
+ "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0",
+ "unist-util-visit-parents": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/unist-util-visit-parents": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz",
+ "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^3.0.0",
+ "unist-util-is": "^6.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/valid-data-url": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz",
+ "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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.25",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.25.tgz",
+ "integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.25",
+ "@vue/compiler-sfc": "3.5.25",
+ "@vue/runtime-dom": "3.5.25",
+ "@vue/server-renderer": "3.5.25",
+ "@vue/shared": "3.5.25"
+ },
+ "peerDependencies": {
+ "typescript": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/web-resource-inliner": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-6.0.1.tgz",
+ "integrity": "sha512-kfqDxt5dTB1JhqsCUQVFDj0rmY+4HLwGQIsLPbyrsN9y9WV/1oFDSx3BQ4GfCv9X+jVeQ7rouTqwK53rA/7t8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-colors": "^4.1.1",
+ "escape-goat": "^3.0.0",
+ "htmlparser2": "^5.0.0",
+ "mime": "^2.4.6",
+ "node-fetch": "^2.6.0",
+ "valid-data-url": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/domhandler": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz",
+ "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/web-resource-inliner/node_modules/htmlparser2": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-5.0.1.tgz",
+ "integrity": "sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.0.1",
+ "domhandler": "^3.3.0",
+ "domutils": "^2.4.2",
+ "entities": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/htmlparser2?sponsor=1"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/wicked-good-xpath": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz",
+ "integrity": "sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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..cef6f37
--- /dev/null
+++ b/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "learn-ai",
+ "version": "1.0.0",
+ "description": "面向软件工程专业毕业生的中文人工智能入门学习教程网站。",
+ "type": "module",
+ "scripts": {
+ "docs:dev": "vitepress dev docs",
+ "docs:build": "vitepress build docs",
+ "docs:preview": "vitepress preview docs"
+ },
+ "keywords": ["ai", "machine-learning", "deep-learning", "tutorial", "chinese"],
+ "author": "",
+ "license": "MIT",
+ "devDependencies": {
+ "markdown-it-mathjax3": "^4.3.2",
+ "vitepress": "^1.6.4"
+ }
+}