From 613ce02e9ab79f1f901827baebb3731b94e67cff Mon Sep 17 00:00:00 2001
From: wsy182 <2392948297@qq.com>
Date: Fri, 27 Feb 2026 16:16:57 +0800
Subject: [PATCH] =?UTF-8?q?feat(layout):=20=E6=9B=B4=E6=96=B0=E5=BA=94?=
=?UTF-8?q?=E7=94=A8=E5=B8=83=E5=B1=80=E5=92=8CUI=E7=BB=84=E4=BB=B6?=
=?UTF-8?q?=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 重构App.vue中的侧边栏布局,更新Logo设计为带有标识和副标题的新样式
- 调整顶部导航栏,增加标题区域显示当前路由标题和日期
- 修改菜单项配置,更新导航标签为更直观的中文描述
- 在Home.vue中替换原有的仪表板为新的Hero卡片和项目进展展示
- 更新Memory.vue中的学习界面,添加学习计划设置和多阶段学习模式
- 集成新的API端点路径,将baseURL从/api调整为/api/v1
- 调整整体视觉风格,包括颜色主题、字体家族和响应式布局
- 更新数据库模型以支持词库功能,添加相关的数据迁移和种子数据
- 调整认证系统的用户ID类型从整型到字符串的变更
- 更改前端构建工具从npm到pnpm,并更新相应的Dockerfile配置
---
PROTOTYPE.md | 39 +
README.md | 4 +-
REQUIREMENTS.md | 54 +-
memora-api/go.mod | 2 +
memora-api/go.sum | 4 +
memora-api/internal/bootstrap/database.go | 34 +-
memora-api/internal/handler/word.go | 29 +-
memora-api/internal/model/id.go | 36 +
memora-api/internal/model/memory_record.go | 21 +-
memora-api/internal/model/user.go | 15 +-
memora-api/internal/model/word.go | 180 +-
memora-api/internal/model/word_book.go | 32 +
.../internal/repository/memory_repository.go | 10 +-
.../internal/repository/word_repository.go | 8 +
memora-api/internal/request/word.go | 4 +-
memora-api/internal/router/router.go | 43 +-
memora-api/internal/service/auth.go | 24 +-
memora-api/internal/service/word.go | 24 +-
memora-api/sql/en_book.sql | 8 +
memora-api/sql/en_book_word_rel.sql | 11 +
memora-api/sql/en_word.sql | 7 +
memora-api/sql/en_word_phrase.sql | 9 +
memora-api/sql/en_word_pron.sql | 11 +
memora-api/sql/en_word_sentence.sql | 12 +
memora-api/sql/en_word_synonym.sql | 13 +
memora-api/sql/en_word_trans.sql | 13 +
memora-api/sql/init.sql | 150 +-
memora-web/Dockerfile | 6 +-
memora-web/index.html | 5 +-
memora-web/package-lock.json | 2295 -----------------
memora-web/package.json | 4 +-
memora-web/pnpm-lock.yaml | 1456 +++++++++++
memora-web/scripts/enforce-pnpm.cjs | 6 +
memora-web/src/App.vue | 104 +-
memora-web/src/app/routes.ts | 5 +-
memora-web/src/modules/preferences/store.ts | 113 +
memora-web/src/services/api/review.ts | 4 +-
memora-web/src/services/api/stats.ts | 2 +-
memora-web/src/services/api/words.ts | 7 +-
memora-web/src/services/http.ts | 2 +-
memora-web/src/styles/index.scss | 16 +-
memora-web/src/views/Home.vue | 77 +-
memora-web/src/views/Memory.vue | 533 +++-
memora-web/src/views/Review.vue | 9 +-
memora-web/src/views/Settings.vue | 124 +-
memora-web/src/views/Statistics.vue | 124 +-
memora-web/src/views/StatisticsDetail.vue | 54 +
47 files changed, 3164 insertions(+), 2579 deletions(-)
create mode 100644 PROTOTYPE.md
create mode 100644 memora-api/internal/model/id.go
create mode 100644 memora-api/internal/model/word_book.go
create mode 100644 memora-api/sql/en_book.sql
create mode 100644 memora-api/sql/en_book_word_rel.sql
create mode 100644 memora-api/sql/en_word.sql
create mode 100644 memora-api/sql/en_word_phrase.sql
create mode 100644 memora-api/sql/en_word_pron.sql
create mode 100644 memora-api/sql/en_word_sentence.sql
create mode 100644 memora-api/sql/en_word_synonym.sql
create mode 100644 memora-api/sql/en_word_trans.sql
delete mode 100644 memora-web/package-lock.json
create mode 100644 memora-web/pnpm-lock.yaml
create mode 100644 memora-web/scripts/enforce-pnpm.cjs
create mode 100644 memora-web/src/modules/preferences/store.ts
create mode 100644 memora-web/src/views/StatisticsDetail.vue
diff --git a/PROTOTYPE.md b/PROTOTYPE.md
new file mode 100644
index 0000000..0ef359d
--- /dev/null
+++ b/PROTOTYPE.md
@@ -0,0 +1,39 @@
+# Memora 原型说明(基于 REQUIREMENTS.md)
+
+## 1. 信息架构
+- 登录:`/login`
+- 学习概览:`/`
+- 记忆模式(新词学习四阶段):`/memory`
+- 复习模式(今日待复习队列):`/review`
+- 学习统计:`/statistics`
+- 词库管理:`/words`
+- 偏好设置:`/settings`
+
+## 2. 核心流程原型
+1. 用户登录后进入仪表盘,看到今日任务和学习概览。
+2. 在「记忆模式」选择词库、每日目标、提醒时间,启动学习会话。
+3. 每个单词按四阶段完成:
+- 阶段一:英译中四选一(显示英文+例句)
+- 阶段二:中译英四选一(显示中文释义)
+- 阶段三:听音选词(播放音频)
+- 阶段四:听音拼写(输入拼写)
+4. 每题提交会写入学习结果,实时展示正确率、连对和耗时。
+5. 在「复习模式」按 SRS 队列完成当天复习,提交后动态更新掌握度和下次复习时间。
+
+## 3. 需求映射
+- 账户与身份:登录/注册 + JWT 保护路由
+- 学习流程:四阶段学习题型 + 会话统计
+- 复习调度:`GET /review/today` 获取今日队列,`POST /review/submit` 回写结果
+- 统计与反馈:仪表盘和统计页展示学习指标
+- 偏好设置:每日目标、提醒时间、词库选择
+
+## 4. API(已对齐 v1)
+- `POST /api/v1/auth/register`
+- `POST /api/v1/auth/login`
+- `GET /api/v1/words`
+- `GET /api/v1/words/:id`
+- `POST /api/v1/study/sessions`
+- `POST /api/v1/study/answers`
+- `GET /api/v1/review/today`
+- `POST /api/v1/review/submit`
+- `GET /api/v1/stats/overview`
diff --git a/README.md b/README.md
index 63db575..cec6f62 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,6 @@ go run main.go
```bash
cd memora-web
-npm install
-npm run dev
+pnpm install
+pnpm dev
```
diff --git a/REQUIREMENTS.md b/REQUIREMENTS.md
index bed6dd0..a2a8e3c 100644
--- a/REQUIREMENTS.md
+++ b/REQUIREMENTS.md
@@ -10,8 +10,8 @@ Memora 是一个以「长期记忆留存」为目标的背单词系统,面向
---
## 2. 用户角色
-- 普通用户:学习、复习、查看统计
-- 管理员(可选):词库管理、运营配置、异常数据处理
+- 普通用户:学习、复习、查看统计,词库管理
+- 管理员:日志查看、异常数据处理
---
@@ -20,18 +20,29 @@ Memora 是一个以「长期记忆留存」为目标的背单词系统,面向
### 3.1 账户与身份
- 用户注册/登录(邮箱或手机号,后续可扩展 OAuth)
- Token 鉴权(JWT)
-- 个人学习偏好(每日目标、提醒时间、难度偏好)
+- 个人学习偏好(每日目标、提醒时间、词库(四级,雅思,托福等),)
### 3.2 词库与学习内容
- 词书管理:内置词书 + 自定义词书
-- 单词详情:拼写、音标、词性、释义、例句、发音
-- 标签体系:阶段(新词/熟词/难词)、来源、主题
+- 单词详情:单词拼写、音标、词性、释义、例句、发音
### 3.3 学习流程
-- 新词学习:按计划推送
-- 测试模式:拼写题、选择题、释义匹配(可扩展)
+- 首次学习需要选择词库,后续可以更改,设定学习计划,每天多少个,学习计划设定后,不在首页显示,在设置中更改。
+
+- 新词学习:
+
+ 第一阶段:先显示单词和例句,不提示中文,四选一,必须满足四个选项选择正确英译中答案,四个答案都是形近词,近义词等。
+
+ 第二阶段:出中文,选择正确的英文,也是四个选项,都是形近词和近义词。
+
+ 第三阶段:根据读音选单词。
+
+ 第四阶段:拼写,自动播放读音,用户可以点击图标再次播放。
+
- 学习结果记录:正确率、耗时、连续正确次数
+
+
### 3.4 复习调度(核心)
- 基于 SRS(间隔重复)策略生成复习计划
- 每日待复习队列
@@ -41,13 +52,40 @@ Memora 是一个以「长期记忆留存」为目标的背单词系统,面向
- 今日学习量、复习量、正确率
- 连续学习天数
- 周/月趋势图
-- 难词排行与建议复习列表
### 3.6 系统能力
- 统一错误码与错误响应
- 审计日志(关键操作)
- 基础监控(接口耗时、错误率)
+### 3.7页面设计
+
+#### 左侧菜单设计
+
+左侧学习,学习统计,单词列表,设置。四个菜单切换标签。
+
+#### 学习统计页面
+
+今日已学,今日复习,已掌握,总词汇。都可以进入二级页面查看详情。
+
+#### 学习页面
+
+首次进入,学习页面可以设置学习计划,词库,每日新词目标,提醒时间。设置后只显示出来,在设置中才能修改。右侧开始学习按钮和复习按钮,点击学习按钮开始学习,学习新词每日新词目标的目标个数。点击复习按钮开始复习。复习按照遗忘曲线的来,每天和学习目标一致。
+
+点击学习后进入学习,先按照上述的第一阶段过完每日新词目标个单词,再第二阶段每日新词目标个单词,第三阶段每日新词目标个单词。第四阶段过完每日新词目标个单词。(每个阶段不用点确定,点击单词即确定)。
+
+#### 设置页面
+
+设置读音偏好,美音还是英音。重设学习计划。头像,昵称等。修改密码。
+
+
+
+
+
+
+
+
+
---
## 4. 非功能需求
diff --git a/memora-api/go.mod b/memora-api/go.mod
index fdcea9e..eb17aac 100644
--- a/memora-api/go.mod
+++ b/memora-api/go.mod
@@ -10,6 +10,7 @@ require (
)
require (
+ github.com/bwmarrin/snowflake v0.3.0 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
@@ -19,6 +20,7 @@ require (
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
+ github.com/google/uuid v1.6.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
diff --git a/memora-api/go.sum b/memora-api/go.sum
index 3cce4cc..e324d09 100644
--- a/memora-api/go.sum
+++ b/memora-api/go.sum
@@ -1,3 +1,5 @@
+github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
+github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
@@ -29,6 +31,8 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
diff --git a/memora-api/internal/bootstrap/database.go b/memora-api/internal/bootstrap/database.go
index def3eb9..4bb2fcb 100644
--- a/memora-api/internal/bootstrap/database.go
+++ b/memora-api/internal/bootstrap/database.go
@@ -13,5 +13,37 @@ func InitDB(cfg *config.Config) (*gorm.DB, error) {
}
func AutoMigrate(db *gorm.DB) error {
- return db.AutoMigrate(&model.User{}, &model.Word{}, &model.MemoryRecord{})
+ if err := db.AutoMigrate(
+ &model.User{},
+ &model.WordBook{},
+ &model.Word{},
+ &model.WordSentence{},
+ &model.WordTranslation{},
+ &model.WordSynonym{},
+ &model.WordSynonymItem{},
+ &model.WordPhrase{},
+ &model.WordRel{},
+ &model.WordRelItem{},
+ &model.MemoryRecord{},
+ ); err != nil {
+ return err
+ }
+ return seedWordBooks(db)
+}
+
+func seedWordBooks(db *gorm.DB) error {
+ books := []model.WordBook{
+ {ID: model.DefaultWordBookID, Code: "default", Name: "默认词库", SourceBookID: "DEFAULT"},
+ {ID: "00000000000000000000000000000002", Code: "cet4", Name: "四级词库", SourceBookID: "CET4"},
+ {ID: "00000000000000000000000000000003", Code: "ielts", Name: "雅思词库", SourceBookID: "IELTS"},
+ {ID: "00000000000000000000000000000004", Code: "toefl", Name: "托福词库", SourceBookID: "TOEFL"},
+ }
+
+ for i := range books {
+ book := books[i]
+ if err := db.Where("code = ?", book.Code).FirstOrCreate(&book).Error; err != nil {
+ return err
+ }
+ }
+ return nil
}
diff --git a/memora-api/internal/handler/word.go b/memora-api/internal/handler/word.go
index a1ef779..9948334 100644
--- a/memora-api/internal/handler/word.go
+++ b/memora-api/internal/handler/word.go
@@ -16,14 +16,14 @@ type WordHandler struct {
wordService *service.WordService
}
-func userIDFromContext(c *gin.Context) int64 {
+func userIDFromContext(c *gin.Context) string {
v, ok := c.Get("user_id")
if !ok {
- return 1
+ return ""
}
- uid, ok := v.(int64)
- if !ok || uid <= 0 {
- return 1
+ uid, ok := v.(string)
+ if !ok {
+ return ""
}
return uid
}
@@ -40,7 +40,6 @@ func (h *WordHandler) AddWord(c *gin.Context) {
return
}
- // 调用有道API查询
youdaoResp, err := h.wordService.QueryWord(req.Word)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询失败: " + err.Error()})
@@ -52,7 +51,6 @@ func (h *WordHandler) AddWord(c *gin.Context) {
return
}
- // 保存到数据库
word, err := h.wordService.SaveWord(userIDFromContext(c), req.Word, youdaoResp)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存失败: " + err.Error()})
@@ -114,6 +112,22 @@ func (h *WordHandler) GetWords(c *gin.Context) {
})
}
+func (h *WordHandler) GetWordByID(c *gin.Context) {
+ id := strings.TrimSpace(c.Param("id"))
+ if id == "" {
+ c.JSON(http.StatusBadRequest, gin.H{"error": "非法单词ID"})
+ return
+ }
+
+ word, err := h.wordService.GetWordByID(id)
+ if err != nil {
+ c.JSON(http.StatusNotFound, gin.H{"error": "单词不存在"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"data": word})
+}
+
// 获取统计信息
func (h *WordHandler) GetStatistics(c *gin.Context) {
stats, err := h.wordService.GetStatistics(userIDFromContext(c))
@@ -135,7 +149,6 @@ func (h *WordHandler) GetAudio(c *gin.Context) {
return
}
- // very small sanitization
word = strings.TrimSpace(word)
if word == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "word为空"})
diff --git a/memora-api/internal/model/id.go b/memora-api/internal/model/id.go
new file mode 100644
index 0000000..0b4ae3f
--- /dev/null
+++ b/memora-api/internal/model/id.go
@@ -0,0 +1,36 @@
+package model
+
+import (
+ "log"
+ "os"
+ "strconv"
+ "sync"
+
+ "github.com/bwmarrin/snowflake"
+)
+
+var (
+ snowflakeNode *snowflake.Node
+ snowflakeOnce sync.Once
+)
+
+func getSnowflakeNode() *snowflake.Node {
+ snowflakeOnce.Do(func() {
+ nodeID := int64(1)
+ if raw := os.Getenv("MEMORA_SNOWFLAKE_NODE"); raw != "" {
+ if parsed, err := strconv.ParseInt(raw, 10, 64); err == nil {
+ nodeID = parsed
+ }
+ }
+ node, err := snowflake.NewNode(nodeID)
+ if err != nil {
+ log.Panicf("init snowflake node failed: %v", err)
+ }
+ snowflakeNode = node
+ })
+ return snowflakeNode
+}
+
+func NewID() string {
+ return getSnowflakeNode().Generate().String()
+}
diff --git a/memora-api/internal/model/memory_record.go b/memora-api/internal/model/memory_record.go
index 5884ec5..7ffe84d 100644
--- a/memora-api/internal/model/memory_record.go
+++ b/memora-api/internal/model/memory_record.go
@@ -1,11 +1,15 @@
package model
-import "time"
+import (
+ "time"
+
+ "gorm.io/gorm"
+)
type MemoryRecord struct {
- ID int64 `json:"id" gorm:"primaryKey"`
- WordID int64 `json:"word_id" gorm:"index;not null"`
- UserID int64 `json:"user_id" gorm:"index;default:1"`
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ WordID string `json:"word_id" gorm:"size:32;index;not null"`
+ UserID string `json:"user_id" gorm:"size:32;index;not null"`
CorrectCount int `json:"correct_count" gorm:"default:0"`
TotalCount int `json:"total_count" gorm:"default:0"`
MasteryLevel int `json:"mastery_level" gorm:"default:0"`
@@ -13,9 +17,16 @@ type MemoryRecord struct {
NextReviewAt *time.Time `json:"next_review_at" gorm:"index"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
- Word *Word `json:"word,omitempty" gorm:"foreignKey:WordID"`
+ Word *Word `json:"word,omitempty" gorm:"foreignKey:WordID;references:ID"`
}
func (MemoryRecord) TableName() string {
return "memory_records"
}
+
+func (m *MemoryRecord) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
diff --git a/memora-api/internal/model/user.go b/memora-api/internal/model/user.go
index 63ecfd4..344d9a8 100644
--- a/memora-api/internal/model/user.go
+++ b/memora-api/internal/model/user.go
@@ -1,9 +1,13 @@
package model
-import "time"
+import (
+ "time"
+
+ "gorm.io/gorm"
+)
type User struct {
- ID int64 `json:"id" gorm:"primaryKey"`
+ ID string `json:"id" gorm:"primaryKey;size:32"`
Email string `json:"email" gorm:"size:120;uniqueIndex;not null"`
Name string `json:"name" gorm:"size:80;not null"`
PasswordHash string `json:"-" gorm:"size:255;not null"`
@@ -14,3 +18,10 @@ type User struct {
func (User) TableName() string {
return "users"
}
+
+func (u *User) BeforeCreate(tx *gorm.DB) error {
+ if u.ID == "" {
+ u.ID = NewID()
+ }
+ return nil
+}
diff --git a/memora-api/internal/model/word.go b/memora-api/internal/model/word.go
index 352e138..3c24103 100644
--- a/memora-api/internal/model/word.go
+++ b/memora-api/internal/model/word.go
@@ -1,21 +1,195 @@
package model
-import "time"
+import (
+ "time"
+
+ "gorm.io/gorm"
+)
type Word struct {
- ID int64 `json:"id" gorm:"primaryKey"`
- Word string `json:"word" gorm:"size:100;uniqueIndex;not null"`
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ BookID string `json:"book_id" gorm:"size:32;index;not null"`
+ WordRank int `json:"word_rank" gorm:"index;default:0"`
+ HeadWord string `json:"head_word" gorm:"size:120;index"`
+ Word string `json:"word" gorm:"size:120;uniqueIndex;not null"`
+ SourceWordID string `json:"source_word_id" gorm:"size:64;index"`
PhoneticUK string `json:"phonetic_uk" gorm:"size:255"`
PhoneticUS string `json:"phonetic_us" gorm:"size:255"`
AudioUK string `json:"audio_uk" gorm:"size:500"`
AudioUS string `json:"audio_us" gorm:"size:500"`
+ UKSpeech string `json:"uk_speech" gorm:"size:255"`
+ USSpeech string `json:"us_speech" gorm:"size:255"`
PartOfSpeech string `json:"part_of_speech" gorm:"size:50"`
Definition string `json:"definition" gorm:"type:text"`
ExampleSentence string `json:"example_sentence" gorm:"type:text"`
+ RawPayload string `json:"raw_payload,omitempty" gorm:"type:longtext"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
+ Book *WordBook `json:"book.sql,omitempty" gorm:"foreignKey:BookID;references:ID"`
}
func (Word) TableName() string {
return "words"
}
+
+func (w *Word) BeforeCreate(tx *gorm.DB) error {
+ if w.ID == "" {
+ w.ID = NewID()
+ }
+ return nil
+}
+
+// WordSentence 对应 content.word.content.sentence.sentences
+// sContent/sCn 以原字段命名映射。
+type WordSentence struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ WordID string `json:"word_id" gorm:"size:32;index;not null"`
+ SortOrder int `json:"sort_order" gorm:"index;default:0"`
+ SContent string `json:"s_content" gorm:"type:text"`
+ SCn string `json:"s_cn" gorm:"type:text"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordSentence) TableName() string {
+ return "word_sentences"
+}
+
+func (m *WordSentence) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
+
+// WordTranslation 对应 content.word.content.trans
+// 保存中英释义及词性信息。
+type WordTranslation struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ WordID string `json:"word_id" gorm:"size:32;index;not null"`
+ SortOrder int `json:"sort_order" gorm:"index;default:0"`
+ Pos string `json:"pos" gorm:"size:32"`
+ TranCn string `json:"tran_cn" gorm:"type:text"`
+ TranOther string `json:"tran_other" gorm:"type:text"`
+ DescCn string `json:"desc_cn" gorm:"size:64"`
+ DescOther string `json:"desc_other" gorm:"size:64"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordTranslation) TableName() string {
+ return "word_translations"
+}
+
+func (m *WordTranslation) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
+
+// WordSynonym + WordSynonymItem 对应 content.word.content.syno.synos[*].hwds[*]
+type WordSynonym struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ WordID string `json:"word_id" gorm:"size:32;index;not null"`
+ SortOrder int `json:"sort_order" gorm:"index;default:0"`
+ Pos string `json:"pos" gorm:"size:32"`
+ Tran string `json:"tran" gorm:"type:text"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordSynonym) TableName() string {
+ return "word_synonyms"
+}
+
+func (m *WordSynonym) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
+
+type WordSynonymItem struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ SynonymID string `json:"synonym_id" gorm:"size:32;index;not null"`
+ SortOrder int `json:"sort_order" gorm:"index;default:0"`
+ Word string `json:"word" gorm:"size:120;not null"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordSynonymItem) TableName() string {
+ return "word_synonym_items"
+}
+
+func (m *WordSynonymItem) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
+
+// WordPhrase 对应 content.word.content.phrase.phrases
+type WordPhrase struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ WordID string `json:"word_id" gorm:"size:32;index;not null"`
+ SortOrder int `json:"sort_order" gorm:"index;default:0"`
+ PContent string `json:"p_content" gorm:"type:text"`
+ PCn string `json:"p_cn" gorm:"type:text"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordPhrase) TableName() string {
+ return "word_phrases"
+}
+
+func (m *WordPhrase) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
+
+// WordRel + WordRelItem 对应 content.word.content.relWord.rels[*].words[*]
+type WordRel struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ WordID string `json:"word_id" gorm:"size:32;index;not null"`
+ SortOrder int `json:"sort_order" gorm:"index;default:0"`
+ Pos string `json:"pos" gorm:"size:32"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordRel) TableName() string {
+ return "word_rels"
+}
+
+func (m *WordRel) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
+
+type WordRelItem struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ RelID string `json:"rel_id" gorm:"size:32;index;not null"`
+ SortOrder int `json:"sort_order" gorm:"index;default:0"`
+ Hwd string `json:"hwd" gorm:"size:120"`
+ Tran string `json:"tran" gorm:"type:text"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordRelItem) TableName() string {
+ return "word_rel_items"
+}
+
+func (m *WordRelItem) BeforeCreate(tx *gorm.DB) error {
+ if m.ID == "" {
+ m.ID = NewID()
+ }
+ return nil
+}
diff --git a/memora-api/internal/model/word_book.go b/memora-api/internal/model/word_book.go
new file mode 100644
index 0000000..51ac0c1
--- /dev/null
+++ b/memora-api/internal/model/word_book.go
@@ -0,0 +1,32 @@
+package model
+
+import (
+ "time"
+
+ "gorm.io/gorm"
+)
+
+const (
+ DefaultWordBookID = "00000000000000000000000000000001"
+ DefaultWordBookCode = "default"
+)
+
+type WordBook struct {
+ ID string `json:"id" gorm:"primaryKey;size:32"`
+ Code string `json:"code" gorm:"size:64;uniqueIndex;not null"`
+ Name string `json:"name" gorm:"size:120;not null"`
+ SourceBookID string `json:"source_book_id" gorm:"size:64;uniqueIndex"`
+ CreatedAt time.Time `json:"created_at"`
+ UpdatedAt time.Time `json:"updated_at"`
+}
+
+func (WordBook) TableName() string {
+ return "word_books"
+}
+
+func (b *WordBook) BeforeCreate(tx *gorm.DB) error {
+ if b.ID == "" {
+ b.ID = NewID()
+ }
+ return nil
+}
diff --git a/memora-api/internal/repository/memory_repository.go b/memora-api/internal/repository/memory_repository.go
index 8b6fd20..f48b7e7 100644
--- a/memora-api/internal/repository/memory_repository.go
+++ b/memora-api/internal/repository/memory_repository.go
@@ -20,7 +20,7 @@ func (r *MemoryRepository) Create(record *model.MemoryRecord) error {
return r.db.Create(record).Error
}
-func (r *MemoryRepository) FindByWord(userID, wordID int64) (*model.MemoryRecord, error) {
+func (r *MemoryRepository) FindByWord(userID, wordID string) (*model.MemoryRecord, error) {
var record model.MemoryRecord
if err := r.db.Where("word_id = ? AND user_id = ?", wordID, userID).First(&record).Error; err != nil {
return nil, err
@@ -28,7 +28,7 @@ func (r *MemoryRepository) FindByWord(userID, wordID int64) (*model.MemoryRecord
return &record, nil
}
-func (r *MemoryRepository) FindByID(userID, recordID int64) (*model.MemoryRecord, error) {
+func (r *MemoryRepository) FindByID(userID, recordID string) (*model.MemoryRecord, error) {
var record model.MemoryRecord
if err := r.db.Preload("Word").Where("id = ? AND user_id = ?", recordID, userID).First(&record).Error; err != nil {
return nil, err
@@ -40,7 +40,7 @@ func (r *MemoryRepository) Save(record *model.MemoryRecord) error {
return r.db.Save(record).Error
}
-func (r *MemoryRepository) Due(userID int64, limit int) ([]model.MemoryRecord, error) {
+func (r *MemoryRepository) Due(userID string, limit int) ([]model.MemoryRecord, error) {
var records []model.MemoryRecord
if err := r.db.Preload("Word").Where("user_id = ? AND (next_review_at <= ? OR next_review_at IS NULL)", userID, time.Now()).Limit(limit).Find(&records).Error; err != nil {
return nil, err
@@ -48,7 +48,7 @@ func (r *MemoryRepository) Due(userID int64, limit int) ([]model.MemoryRecord, e
return records, nil
}
-func (r *MemoryRepository) ListByUser(userID int64, limit int) ([]model.MemoryRecord, error) {
+func (r *MemoryRepository) ListByUser(userID string, limit int) ([]model.MemoryRecord, error) {
var records []model.MemoryRecord
if err := r.db.Preload("Word").Where("user_id = ?", userID).Limit(limit).Find(&records).Error; err != nil {
return nil, err
@@ -56,7 +56,7 @@ func (r *MemoryRepository) ListByUser(userID int64, limit int) ([]model.MemoryRe
return records, nil
}
-func (r *MemoryRepository) CountOverview(userID int64) (total, mastered, needReview, todayReviewed int64) {
+func (r *MemoryRepository) CountOverview(userID string) (total, mastered, needReview, todayReviewed int64) {
r.db.Model(&model.MemoryRecord{}).Where("user_id = ?", userID).Count(&total)
r.db.Model(&model.MemoryRecord{}).Where("user_id = ? AND mastery_level >= 4", userID).Count(&mastered)
r.db.Model(&model.MemoryRecord{}).Where("user_id = ? AND next_review_at <= ?", userID, time.Now()).Count(&needReview)
diff --git a/memora-api/internal/repository/word_repository.go b/memora-api/internal/repository/word_repository.go
index 978f587..f84466f 100644
--- a/memora-api/internal/repository/word_repository.go
+++ b/memora-api/internal/repository/word_repository.go
@@ -22,6 +22,14 @@ func (r *WordRepository) FindByWord(word string) (*model.Word, error) {
return &w, nil
}
+func (r *WordRepository) FindByID(id string) (*model.Word, error) {
+ var w model.Word
+ if err := r.db.Where("id = ?", id).First(&w).Error; err != nil {
+ return nil, err
+ }
+ return &w, nil
+}
+
func (r *WordRepository) Create(word *model.Word) error {
return r.db.Create(word).Error
}
diff --git a/memora-api/internal/request/word.go b/memora-api/internal/request/word.go
index 976c5e2..98dd5e3 100644
--- a/memora-api/internal/request/word.go
+++ b/memora-api/internal/request/word.go
@@ -5,7 +5,7 @@ type AddWordRequest struct {
}
type ReviewAnswerRequest struct {
- RecordID int64 `json:"record_id" binding:"required"`
+ RecordID string `json:"record_id" binding:"required"`
Answer string `json:"answer" binding:"required"`
Mode string `json:"mode" binding:"required"` // spelling, en2cn, cn2en
}
@@ -15,7 +15,7 @@ type CreateStudySessionRequest struct {
}
type SubmitStudyAnswerRequest struct {
- WordID int64 `json:"word_id" binding:"required"`
+ WordID string `json:"word_id" binding:"required"`
Answer string `json:"answer" binding:"required"`
Mode string `json:"mode" binding:"required"` // spelling, en2cn, cn2en
}
diff --git a/memora-api/internal/router/router.go b/memora-api/internal/router/router.go
index 866a40a..0840c85 100644
--- a/memora-api/internal/router/router.go
+++ b/memora-api/internal/router/router.go
@@ -12,24 +12,31 @@ func New(wordHandler *handler.WordHandler, authHandler *handler.AuthHandler) *gi
r.Use(middleware.CORS())
api := r.Group("/api")
- {
- api.POST("/auth/register", authHandler.Register)
- api.POST("/auth/login", authHandler.Login)
- api.GET("/auth/me", authHandler.Me)
-
- protected := api.Group("")
- protected.Use(middleware.AuthRequired())
- {
- protected.POST("/words", wordHandler.AddWord)
- protected.GET("/words", wordHandler.GetWords)
- protected.POST("/study/sessions", wordHandler.CreateStudySession)
- protected.POST("/study/answers", wordHandler.SubmitStudyAnswer)
- protected.GET("/review", wordHandler.GetReviewWords)
- protected.POST("/review", wordHandler.SubmitReview)
- protected.GET("/stats", wordHandler.GetStatistics)
- protected.GET("/audio", wordHandler.GetAudio)
- }
- }
+ registerRoutes(api, wordHandler, authHandler)
+ registerRoutes(api.Group("/v1"), wordHandler, authHandler)
return r
}
+
+func registerRoutes(group *gin.RouterGroup, wordHandler *handler.WordHandler, authHandler *handler.AuthHandler) {
+ group.POST("/auth/register", authHandler.Register)
+ group.POST("/auth/login", authHandler.Login)
+ group.GET("/auth/me", authHandler.Me)
+
+ protected := group.Group("")
+ protected.Use(middleware.AuthRequired())
+ {
+ protected.POST("/words", wordHandler.AddWord)
+ protected.GET("/words", wordHandler.GetWords)
+ protected.GET("/words/:id", wordHandler.GetWordByID)
+ protected.POST("/study/sessions", wordHandler.CreateStudySession)
+ protected.POST("/study/answers", wordHandler.SubmitStudyAnswer)
+ protected.GET("/review", wordHandler.GetReviewWords)
+ protected.POST("/review", wordHandler.SubmitReview)
+ protected.GET("/review/today", wordHandler.GetReviewWords)
+ protected.POST("/review/submit", wordHandler.SubmitReview)
+ protected.GET("/stats", wordHandler.GetStatistics)
+ protected.GET("/stats/overview", wordHandler.GetStatistics)
+ protected.GET("/audio", wordHandler.GetAudio)
+ }
+}
diff --git a/memora-api/internal/service/auth.go b/memora-api/internal/service/auth.go
index 245c9b9..a516a1b 100644
--- a/memora-api/internal/service/auth.go
+++ b/memora-api/internal/service/auth.go
@@ -63,9 +63,9 @@ func sign(data string) string {
return base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
}
-func makeToken(uid int64) string {
+func makeToken(uid string) string {
exp := time.Now().Add(7 * 24 * time.Hour).Unix()
- payload := fmt.Sprintf("%d:%d", uid, exp)
+ payload := fmt.Sprintf("%s:%d", uid, exp)
encPayload := base64.RawURLEncoding.EncodeToString([]byte(payload))
sig := sign(encPayload)
return encPayload + "." + sig
@@ -84,35 +84,35 @@ func (s *AuthService) Login(req request.LoginRequest) (string, *model.User, erro
return makeToken(user.ID), &user, nil
}
-func ParseToken(tokenString string) (int64, error) {
+func ParseToken(tokenString string) (string, error) {
parts := strings.Split(tokenString, ".")
if len(parts) != 2 {
- return 0, errors.New("token无效")
+ return "", errors.New("token无效")
}
encPayload, gotSig := parts[0], parts[1]
if sign(encPayload) != gotSig {
- return 0, errors.New("token无效")
+ return "", errors.New("token无效")
}
payloadBytes, err := base64.RawURLEncoding.DecodeString(encPayload)
if err != nil {
- return 0, errors.New("token无效")
+ return "", errors.New("token无效")
}
payloadParts := strings.Split(string(payloadBytes), ":")
if len(payloadParts) != 2 {
- return 0, errors.New("token无效")
+ return "", errors.New("token无效")
}
- uid, err := strconv.ParseInt(payloadParts[0], 10, 64)
- if err != nil {
- return 0, errors.New("token无效")
+ uid := payloadParts[0]
+ if uid == "" {
+ return "", errors.New("token无效")
}
exp, err := strconv.ParseInt(payloadParts[1], 10, 64)
if err != nil {
- return 0, errors.New("token无效")
+ return "", errors.New("token无效")
}
if time.Now().Unix() > exp {
- return 0, errors.New("token已过期")
+ return "", errors.New("token已过期")
}
return uid, nil
diff --git a/memora-api/internal/service/word.go b/memora-api/internal/service/word.go
index 18f21e0..185b16e 100644
--- a/memora-api/internal/service/word.go
+++ b/memora-api/internal/service/word.go
@@ -176,7 +176,7 @@ func (s *WordService) DownloadAudio(url, filePath string) error {
}
// 保存单词到数据库
-func (s *WordService) SaveWord(userID int64, word string, youdaoResp *model.YoudaoResponse) (*model.Word, error) {
+func (s *WordService) SaveWord(userID string, word string, youdaoResp *model.YoudaoResponse) (*model.Word, error) {
// 检查单词是否已存在
if w, err := s.wordRepo.FindByWord(word); err == nil {
// 单词已存在,更新记忆记录
@@ -262,6 +262,8 @@ func (s *WordService) SaveWord(userID int64, word string, youdaoResp *model.Youd
// 创建新单词
newWord := model.Word{
+ BookID: model.DefaultWordBookID,
+ HeadWord: word,
Word: word,
PhoneticUK: phoneticUK,
PhoneticUS: phoneticUS,
@@ -284,7 +286,7 @@ func (s *WordService) SaveWord(userID int64, word string, youdaoResp *model.Youd
}
// 创建记忆记录
-func (s *WordService) createMemoryRecord(userID, wordID int64) error {
+func (s *WordService) createMemoryRecord(userID, wordID string) error {
record := model.MemoryRecord{
WordID: wordID,
UserID: userID,
@@ -296,7 +298,7 @@ func (s *WordService) createMemoryRecord(userID, wordID int64) error {
}
// 更新记忆记录
-func (s *WordService) updateMemoryRecord(userID, wordID int64, correct bool) error {
+func (s *WordService) updateMemoryRecord(userID, wordID string, correct bool) error {
record, err := s.memoryRepo.FindByWord(userID, wordID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
@@ -333,7 +335,7 @@ func (s *WordService) updateMemoryRecord(userID, wordID int64, correct bool) err
}
// 获取待复习单词
-func (s *WordService) GetReviewWords(userID int64, mode string, limit int) ([]model.MemoryRecord, error) {
+func (s *WordService) GetReviewWords(userID string, mode string, limit int) ([]model.MemoryRecord, error) {
records, err := s.memoryRepo.Due(userID, limit)
if err != nil {
return nil, err
@@ -375,7 +377,7 @@ func containsAny(def string, ans string) bool {
}
// 提交复习答案
-func (s *WordService) SubmitReviewAnswer(userID int64, req request.ReviewAnswerRequest) (*response.ReviewResult, error) {
+func (s *WordService) SubmitReviewAnswer(userID string, req request.ReviewAnswerRequest) (*response.ReviewResult, error) {
record, err := s.memoryRepo.FindByID(userID, req.RecordID)
if err != nil {
return nil, err
@@ -416,8 +418,12 @@ func (s *WordService) GetAllWords(limit, offset int, query string) ([]model.Word
return s.wordRepo.List(limit, offset, strings.TrimSpace(query))
}
+func (s *WordService) GetWordByID(id string) (*model.Word, error) {
+ return s.wordRepo.FindByID(id)
+}
+
// 获取记忆统计
-func (s *WordService) GetStatistics(userID int64) (map[string]interface{}, error) {
+func (s *WordService) GetStatistics(userID string) (map[string]interface{}, error) {
totalWords, masteredWords, needReview, todayReviewed := s.memoryRepo.CountOverview(userID)
return map[string]interface{}{
@@ -428,7 +434,7 @@ func (s *WordService) GetStatistics(userID int64) (map[string]interface{}, error
}, nil
}
-func (s *WordService) CreateStudySession(userID int64, limit int) ([]model.Word, error) {
+func (s *WordService) CreateStudySession(userID string, limit int) ([]model.Word, error) {
if limit <= 0 || limit > 50 {
limit = 10
}
@@ -442,9 +448,9 @@ func (s *WordService) CreateStudySession(userID int64, limit int) ([]model.Word,
return words, nil
}
-func (s *WordService) SubmitStudyAnswer(userID int64, req request.SubmitStudyAnswerRequest) (*response.ReviewResult, error) {
+func (s *WordService) SubmitStudyAnswer(userID string, req request.SubmitStudyAnswerRequest) (*response.ReviewResult, error) {
reviewReq := request.ReviewAnswerRequest{
- RecordID: 0,
+ RecordID: "",
Answer: req.Answer,
Mode: req.Mode,
}
diff --git a/memora-api/sql/en_book.sql b/memora-api/sql/en_book.sql
new file mode 100644
index 0000000..584afde
--- /dev/null
+++ b/memora-api/sql/en_book.sql
@@ -0,0 +1,8 @@
+CREATE TABLE IF NOT EXISTS `en_book` (
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '词书主键ID',
+ `book_name` VARCHAR(100) NOT NULL COMMENT '词书名称,如雅思核心词',
+ `exam_type` VARCHAR(50) NOT NULL COMMENT '考试类型,如 IELTS/TOEFL/CET4',
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='英语词书表';
diff --git a/memora-api/sql/en_book_word_rel.sql b/memora-api/sql/en_book_word_rel.sql
new file mode 100644
index 0000000..4f4ff5d
--- /dev/null
+++ b/memora-api/sql/en_book_word_rel.sql
@@ -0,0 +1,11 @@
+CREATE TABLE IF NOT EXISTS `en_book_word_rl`
+(
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '词书单词关联主键ID',
+ `book_id` BIGINT NOT NULL COMMENT '词书ID,关联 en_book.id',
+ `word_id` BIGINT NOT NULL COMMENT '单词ID,关联 en_word.id',
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='词书单词关联表';
\ No newline at end of file
diff --git a/memora-api/sql/en_word.sql b/memora-api/sql/en_word.sql
new file mode 100644
index 0000000..d24b6a5
--- /dev/null
+++ b/memora-api/sql/en_word.sql
@@ -0,0 +1,7 @@
+CREATE TABLE IF NOT EXISTS `en_word` (
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '单词主键ID',
+ `word` VARCHAR(100) NOT NULL COMMENT '单词词头,如 cancel',
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='英语单词主表';
diff --git a/memora-api/sql/en_word_phrase.sql b/memora-api/sql/en_word_phrase.sql
new file mode 100644
index 0000000..80fd967
--- /dev/null
+++ b/memora-api/sql/en_word_phrase.sql
@@ -0,0 +1,9 @@
+CREATE TABLE IF NOT EXISTS `en_word_phrase` (
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '短语记录主键ID',
+ `word_id` BIGINT NOT NULL COMMENT '单词ID,关联 en_word.id',
+ `phrase_en` VARCHAR(200) NOT NULL COMMENT '英文短语',
+ `phrase_cn` VARCHAR(200) COMMENT '中文释义'
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='英语单词短语表';
diff --git a/memora-api/sql/en_word_pron.sql b/memora-api/sql/en_word_pron.sql
new file mode 100644
index 0000000..00d125f
--- /dev/null
+++ b/memora-api/sql/en_word_pron.sql
@@ -0,0 +1,11 @@
+CREATE TABLE IF NOT EXISTS `en_word_pron` (
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '发音记录主键ID',
+ `word_id` BIGINT NOT NULL COMMENT '单词ID,关联 en_word.id',
+ `uk_phone` VARCHAR(100) COMMENT '英式音标',
+ `us_phone` VARCHAR(100) COMMENT '美式音标',
+ `uk_speech` VARCHAR(200) COMMENT '英式发音资源地址或参数',
+ `us_speech` VARCHAR(200) COMMENT '美式发音资源地址或参数',
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='英语单词发音表';
diff --git a/memora-api/sql/en_word_sentence.sql b/memora-api/sql/en_word_sentence.sql
new file mode 100644
index 0000000..56e5e17
--- /dev/null
+++ b/memora-api/sql/en_word_sentence.sql
@@ -0,0 +1,12 @@
+CREATE TABLE IF NOT EXISTS `en_word_sentence`
+(
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '例句记录主键ID',
+ `word_id` BIGINT NOT NULL COMMENT '单词ID,关联 en_word.id',
+ `sentence_en` TEXT COMMENT '英文例句',
+ `sentence_cn` TEXT COMMENT '中文例句',
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='英语单词例句表';
diff --git a/memora-api/sql/en_word_synonym.sql b/memora-api/sql/en_word_synonym.sql
new file mode 100644
index 0000000..2dd1261
--- /dev/null
+++ b/memora-api/sql/en_word_synonym.sql
@@ -0,0 +1,13 @@
+CREATE TABLE IF NOT EXISTS `en_word_synonym`
+(
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '同义词记录主键ID',
+ `word_id` BIGINT NOT NULL COMMENT '单词ID,关联 en_word.id',
+ `pos` VARCHAR(20) COMMENT '词性,如 vt/vi/n',
+ `tran` TEXT COMMENT '同义词组释义',
+ `synonym_word` VARCHAR(100) NOT NULL COMMENT '同义词词头',
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='英语单词同义词表';
diff --git a/memora-api/sql/en_word_trans.sql b/memora-api/sql/en_word_trans.sql
new file mode 100644
index 0000000..3535861
--- /dev/null
+++ b/memora-api/sql/en_word_trans.sql
@@ -0,0 +1,13 @@
+CREATE TABLE IF NOT EXISTS `en_word_trans`
+(
+ `id` BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '释义记录主键ID',
+ `word_id` BIGINT NOT NULL COMMENT '单词ID,关联 en_word.id',
+ `pos` VARCHAR(20) COMMENT '词性,如 v/n/adj',
+ `tran_cn` TEXT COMMENT '中文释义',
+ `tran_en` TEXT COMMENT '英文释义',
+ `delete_flag` TINYINT(1) DEFAULT 0 COMMENT '删除标志,0-正常,1-删除',
+ `create_at` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+ `update_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci COMMENT ='英语单词释义表';
diff --git a/memora-api/sql/init.sql b/memora-api/sql/init.sql
index f91bb59..52b8905 100644
--- a/memora-api/sql/init.sql
+++ b/memora-api/sql/init.sql
@@ -2,20 +2,150 @@
CREATE DATABASE IF NOT EXISTS memora DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE memora;
--- 标准单词表
+-- 词库表(对应 JSON 顶层 bookId)
+CREATE TABLE IF NOT EXISTS word_books (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ code VARCHAR(64) NOT NULL UNIQUE COMMENT '系统词库编码',
+ name VARCHAR(120) NOT NULL COMMENT '词库名称',
+ source_json_filename VARCHAR(255) NULL UNIQUE COMMENT '来源词库json文件名,如 IELTS_3',
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+INSERT INTO word_books (id, code, name, source_book_id)
+VALUES
+ (1, 'default', '默认词库', 'DEFAULT'),
+ (2, 'cet4', '四级词库', 'CET4'),
+ (3, 'ielts', '雅思词库', 'IELTS'),
+ (4, 'toefl', '托福词库', 'TOEFL')
+ON DUPLICATE KEY UPDATE
+ name = VALUES(name),
+ source_book_id = VALUES(source_book_id);
+
+-- 主单词表(覆盖 JSON 顶层与 content.word 核心字段)
CREATE TABLE IF NOT EXISTS words (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
- word VARCHAR(100) NOT NULL UNIQUE COMMENT '单词',
- phonetic_uk VARCHAR(255) COMMENT '英式音标',
- phonetic_us VARCHAR(255) COMMENT '美式音标',
- audio_uk VARCHAR(500) COMMENT '英式音频文件路径',
- audio_us VARCHAR(500) COMMENT '美式音频文件路径',
- part_of_speech VARCHAR(50) COMMENT '词性',
- definition TEXT COMMENT '标准释义',
- example_sentence TEXT COMMENT '例句',
+ book_id BIGINT NOT NULL DEFAULT 1 COMMENT '关联词库ID',
+ word_rank INT DEFAULT 0 COMMENT 'JSON: wordRank',
+ head_word VARCHAR(120) COMMENT 'JSON: headWord',
+ word VARCHAR(120) NOT NULL UNIQUE COMMENT 'JSON: content.word.wordHead',
+ source_word_id VARCHAR(64) COMMENT 'JSON: content.word.wordId',
+ phonetic_uk VARCHAR(255) COMMENT 'JSON: ukphone',
+ phonetic_us VARCHAR(255) COMMENT 'JSON: usphone',
+ audio_uk VARCHAR(500) COMMENT '英式音频文件路径(本地缓存)',
+ audio_us VARCHAR(500) COMMENT '美式音频文件路径(本地缓存)',
+ uk_speech VARCHAR(255) COMMENT 'JSON: ukspeech',
+ us_speech VARCHAR(255) COMMENT 'JSON: usspeech',
+ part_of_speech VARCHAR(50) COMMENT '兼容旧结构',
+ definition TEXT COMMENT '兼容旧结构(可由 trans 聚合)',
+ example_sentence TEXT COMMENT '兼容旧结构(可由 sentence 聚合)',
+ raw_payload LONGTEXT COMMENT '完整原始JSON',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- INDEX idx_word (word)
+ INDEX idx_word (word),
+ INDEX idx_book_id (book_id),
+ INDEX idx_word_rank (word_rank),
+ INDEX idx_source_word_id (source_word_id),
+ FOREIGN KEY (book_id) REFERENCES word_books(id) ON DELETE RESTRICT ON UPDATE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- 例句表:content.word.content.sentence.sentences
+CREATE TABLE IF NOT EXISTS word_sentences (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ word_id BIGINT NOT NULL,
+ sort_order INT DEFAULT 0,
+ s_content TEXT COMMENT 'JSON: sContent',
+ s_cn TEXT COMMENT 'JSON: sCn',
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_word_sentence_word_id (word_id),
+ INDEX idx_word_sentence_sort (sort_order),
+ FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- 释义表:content.word.content.trans
+CREATE TABLE IF NOT EXISTS word_translations (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ word_id BIGINT NOT NULL,
+ sort_order INT DEFAULT 0,
+ pos VARCHAR(32),
+ tran_cn TEXT,
+ tran_other TEXT,
+ desc_cn VARCHAR(64),
+ desc_other VARCHAR(64),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_word_trans_word_id (word_id),
+ INDEX idx_word_trans_sort (sort_order),
+ FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- 同近组表:content.word.content.syno.synos
+CREATE TABLE IF NOT EXISTS word_synonyms (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ word_id BIGINT NOT NULL,
+ sort_order INT DEFAULT 0,
+ pos VARCHAR(32),
+ tran TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_word_syn_word_id (word_id),
+ INDEX idx_word_syn_sort (sort_order),
+ FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- 同近词项表:content.word.content.syno.synos[*].hwds[*]
+CREATE TABLE IF NOT EXISTS word_synonym_items (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ synonym_id BIGINT NOT NULL,
+ sort_order INT DEFAULT 0,
+ word VARCHAR(120) NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_word_syn_item_syn_id (synonym_id),
+ INDEX idx_word_syn_item_sort (sort_order),
+ FOREIGN KEY (synonym_id) REFERENCES word_synonyms(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- 短语表:content.word.content.phrase.phrases
+CREATE TABLE IF NOT EXISTS word_phrases (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ word_id BIGINT NOT NULL,
+ sort_order INT DEFAULT 0,
+ p_content TEXT,
+ p_cn TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_word_phrase_word_id (word_id),
+ INDEX idx_word_phrase_sort (sort_order),
+ FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- 同根组表:content.word.content.relWord.rels
+CREATE TABLE IF NOT EXISTS word_rels (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ word_id BIGINT NOT NULL,
+ sort_order INT DEFAULT 0,
+ pos VARCHAR(32),
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_word_rel_word_id (word_id),
+ INDEX idx_word_rel_sort (sort_order),
+ FOREIGN KEY (word_id) REFERENCES words(id) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
+
+-- 同根词项表:content.word.content.relWord.rels[*].words[*]
+CREATE TABLE IF NOT EXISTS word_rel_items (
+ id BIGINT PRIMARY KEY AUTO_INCREMENT,
+ rel_id BIGINT NOT NULL,
+ sort_order INT DEFAULT 0,
+ hwd VARCHAR(120),
+ tran TEXT,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ INDEX idx_word_rel_item_rel_id (rel_id),
+ INDEX idx_word_rel_item_sort (sort_order),
+ FOREIGN KEY (rel_id) REFERENCES word_rels(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- 记忆记录表
diff --git a/memora-web/Dockerfile b/memora-web/Dockerfile
index aad2002..1a83194 100644
--- a/memora-web/Dockerfile
+++ b/memora-web/Dockerfile
@@ -1,7 +1,7 @@
FROM node:20-alpine
WORKDIR /app
-COPY package.json package-lock.json* ./
-RUN npm install
+COPY package.json pnpm-lock.yaml* ./
+RUN corepack enable && pnpm install
COPY . .
EXPOSE 3000
-CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "3000"]
+CMD ["pnpm", "dev", "--host", "0.0.0.0", "--port", "3000"]
diff --git a/memora-web/index.html b/memora-web/index.html
index e6f29fa..0cceda7 100644
--- a/memora-web/index.html
+++ b/memora-web/index.html
@@ -3,8 +3,11 @@
+
+
+
Memora 背单词
-
+
diff --git a/memora-web/package-lock.json b/memora-web/package-lock.json
deleted file mode 100644
index 5c51af7..0000000
--- a/memora-web/package-lock.json
+++ /dev/null
@@ -1,2295 +0,0 @@
-{
- "name": "memora-web",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "memora-web",
- "version": "1.0.0",
- "dependencies": {
- "axios": "^1.6.8",
- "element-plus": "^2.7.2",
- "vue": "^3.4.21",
- "vue-router": "^4.3.0"
- },
- "devDependencies": {
- "@types/node": "^25.3.1",
- "@vitejs/plugin-vue": "^5.0.4",
- "sass": "^1.97.3",
- "typescript": "^5.9.3",
- "vite": "^5.1.6",
- "vue-tsc": "^3.2.5"
- }
- },
- "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==",
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
- "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.0"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.0",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
- "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.28.5"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@ctrl/tinycolor": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
- "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@element-plus/icons-vue": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/@element-plus/icons-vue/-/icons-vue-2.3.2.tgz",
- "integrity": "sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==",
- "license": "MIT",
- "peerDependencies": {
- "vue": "^3.2.0"
- }
- },
- "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/@floating-ui/core": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz",
- "integrity": "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/utils": "^0.2.10"
- }
- },
- "node_modules/@floating-ui/dom": {
- "version": "1.7.5",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.5.tgz",
- "integrity": "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==",
- "license": "MIT",
- "dependencies": {
- "@floating-ui/core": "^1.7.4",
- "@floating-ui/utils": "^0.2.10"
- }
- },
- "node_modules/@floating-ui/utils": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
- "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
- "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==",
- "license": "MIT"
- },
- "node_modules/@parcel/watcher": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
- "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "detect-libc": "^2.0.3",
- "is-glob": "^4.0.3",
- "node-addon-api": "^7.0.0",
- "picomatch": "^4.0.3"
- },
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "@parcel/watcher-android-arm64": "2.5.6",
- "@parcel/watcher-darwin-arm64": "2.5.6",
- "@parcel/watcher-darwin-x64": "2.5.6",
- "@parcel/watcher-freebsd-x64": "2.5.6",
- "@parcel/watcher-linux-arm-glibc": "2.5.6",
- "@parcel/watcher-linux-arm-musl": "2.5.6",
- "@parcel/watcher-linux-arm64-glibc": "2.5.6",
- "@parcel/watcher-linux-arm64-musl": "2.5.6",
- "@parcel/watcher-linux-x64-glibc": "2.5.6",
- "@parcel/watcher-linux-x64-musl": "2.5.6",
- "@parcel/watcher-win32-arm64": "2.5.6",
- "@parcel/watcher-win32-ia32": "2.5.6",
- "@parcel/watcher-win32-x64": "2.5.6"
- }
- },
- "node_modules/@parcel/watcher-android-arm64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
- "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-arm64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
- "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-darwin-x64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
- "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-freebsd-x64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
- "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-glibc": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
- "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm-musl": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
- "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-glibc": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
- "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-arm64-musl": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
- "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-glibc": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
- "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-linux-x64-musl": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
- "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-arm64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
- "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-ia32": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
- "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@parcel/watcher-win32-x64": {
- "version": "2.5.6",
- "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
- "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/@popperjs/core": {
- "name": "@sxzz/popperjs-es",
- "version": "2.11.8",
- "resolved": "https://registry.npmjs.org/@sxzz/popperjs-es/-/popperjs-es-2.11.8.tgz",
- "integrity": "sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==",
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/popperjs"
- }
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz",
- "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz",
- "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz",
- "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz",
- "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz",
- "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz",
- "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz",
- "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz",
- "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz",
- "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz",
- "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz",
- "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz",
- "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz",
- "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz",
- "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz",
- "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz",
- "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz",
- "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz",
- "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz",
- "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz",
- "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz",
- "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz",
- "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz",
- "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz",
- "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz",
- "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@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/lodash": {
- "version": "4.17.24",
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz",
- "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==",
- "license": "MIT"
- },
- "node_modules/@types/lodash-es": {
- "version": "4.17.12",
- "resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
- "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
- "license": "MIT",
- "dependencies": {
- "@types/lodash": "*"
- }
- },
- "node_modules/@types/node": {
- "version": "25.3.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.1.tgz",
- "integrity": "sha512-hj9YIJimBCipHVfHKRMnvmHg+wfhKc0o4mTtXh9pKBjC8TLJzz0nzGmLi5UJsYAUgSvXFHgb0V2oY10DUFtImw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~7.18.0"
- }
- },
- "node_modules/@types/web-bluetooth": {
- "version": "0.0.20",
- "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
- "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==",
- "license": "MIT"
- },
- "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/@volar/language-core": {
- "version": "2.4.28",
- "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz",
- "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@volar/source-map": "2.4.28"
- }
- },
- "node_modules/@volar/source-map": {
- "version": "2.4.28",
- "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz",
- "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@volar/typescript": {
- "version": "2.4.28",
- "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz",
- "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@volar/language-core": "2.4.28",
- "path-browserify": "^1.0.1",
- "vscode-uri": "^3.0.8"
- }
- },
- "node_modules/@vue/compiler-core": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.29.tgz",
- "integrity": "sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.29.0",
- "@vue/shared": "3.5.29",
- "entities": "^7.0.1",
- "estree-walker": "^2.0.2",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/@vue/compiler-dom": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.29.tgz",
- "integrity": "sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-core": "3.5.29",
- "@vue/shared": "3.5.29"
- }
- },
- "node_modules/@vue/compiler-sfc": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.29.tgz",
- "integrity": "sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.29.0",
- "@vue/compiler-core": "3.5.29",
- "@vue/compiler-dom": "3.5.29",
- "@vue/compiler-ssr": "3.5.29",
- "@vue/shared": "3.5.29",
- "estree-walker": "^2.0.2",
- "magic-string": "^0.30.21",
- "postcss": "^8.5.6",
- "source-map-js": "^1.2.1"
- }
- },
- "node_modules/@vue/compiler-ssr": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.29.tgz",
- "integrity": "sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-dom": "3.5.29",
- "@vue/shared": "3.5.29"
- }
- },
- "node_modules/@vue/devtools-api": {
- "version": "6.6.4",
- "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
- "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
- "license": "MIT"
- },
- "node_modules/@vue/language-core": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.2.5.tgz",
- "integrity": "sha512-d3OIxN/+KRedeM5wQ6H6NIpwS3P5gC9nmyaHgBk+rO6dIsjY+tOh4UlPpiZbAh3YtLdCGEX4M16RmsBqPmJV+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@volar/language-core": "2.4.28",
- "@vue/compiler-dom": "^3.5.0",
- "@vue/shared": "^3.5.0",
- "alien-signals": "^3.0.0",
- "muggle-string": "^0.4.1",
- "path-browserify": "^1.0.1",
- "picomatch": "^4.0.2"
- }
- },
- "node_modules/@vue/reactivity": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.29.tgz",
- "integrity": "sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA==",
- "license": "MIT",
- "dependencies": {
- "@vue/shared": "3.5.29"
- }
- },
- "node_modules/@vue/runtime-core": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.29.tgz",
- "integrity": "sha512-8DpW2QfdwIWOLqtsNcds4s+QgwSaHSJY/SUe04LptianUQ/0xi6KVsu/pYVh+HO3NTVvVJjIPL2t6GdeKbS4Lg==",
- "license": "MIT",
- "dependencies": {
- "@vue/reactivity": "3.5.29",
- "@vue/shared": "3.5.29"
- }
- },
- "node_modules/@vue/runtime-dom": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.29.tgz",
- "integrity": "sha512-AHvvJEtcY9tw/uk+s/YRLSlxxQnqnAkjqvK25ZiM4CllCZWzElRAoQnCM42m9AHRLNJ6oe2kC5DCgD4AUdlvXg==",
- "license": "MIT",
- "dependencies": {
- "@vue/reactivity": "3.5.29",
- "@vue/runtime-core": "3.5.29",
- "@vue/shared": "3.5.29",
- "csstype": "^3.2.3"
- }
- },
- "node_modules/@vue/server-renderer": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.29.tgz",
- "integrity": "sha512-G/1k6WK5MusLlbxSE2YTcqAAezS+VuwHhOvLx2KnQU7G2zCH6KIb+5Wyt6UjMq7a3qPzNEjJXs1hvAxDclQH+g==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-ssr": "3.5.29",
- "@vue/shared": "3.5.29"
- },
- "peerDependencies": {
- "vue": "3.5.29"
- }
- },
- "node_modules/@vue/shared": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.29.tgz",
- "integrity": "sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg==",
- "license": "MIT"
- },
- "node_modules/@vueuse/core": {
- "version": "10.11.1",
- "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz",
- "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==",
- "license": "MIT",
- "dependencies": {
- "@types/web-bluetooth": "^0.0.20",
- "@vueuse/metadata": "10.11.1",
- "@vueuse/shared": "10.11.1",
- "vue-demi": ">=0.14.8"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "node_modules/@vueuse/core/node_modules/vue-demi": {
- "version": "0.14.10",
- "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
- "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "vue-demi-fix": "bin/vue-demi-fix.js",
- "vue-demi-switch": "bin/vue-demi-switch.js"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- },
- "peerDependencies": {
- "@vue/composition-api": "^1.0.0-rc.1",
- "vue": "^3.0.0-0 || ^2.6.0"
- },
- "peerDependenciesMeta": {
- "@vue/composition-api": {
- "optional": true
- }
- }
- },
- "node_modules/@vueuse/metadata": {
- "version": "10.11.1",
- "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.1.tgz",
- "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "node_modules/@vueuse/shared": {
- "version": "10.11.1",
- "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.11.1.tgz",
- "integrity": "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==",
- "license": "MIT",
- "dependencies": {
- "vue-demi": ">=0.14.8"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
- "node_modules/@vueuse/shared/node_modules/vue-demi": {
- "version": "0.14.10",
- "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
- "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "vue-demi-fix": "bin/vue-demi-fix.js",
- "vue-demi-switch": "bin/vue-demi-switch.js"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- },
- "peerDependencies": {
- "@vue/composition-api": "^1.0.0-rc.1",
- "vue": "^3.0.0-0 || ^2.6.0"
- },
- "peerDependenciesMeta": {
- "@vue/composition-api": {
- "optional": true
- }
- }
- },
- "node_modules/alien-signals": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.1.2.tgz",
- "integrity": "sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/async-validator": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
- "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
- "license": "MIT"
- },
- "node_modules/asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
- "license": "MIT"
- },
- "node_modules/axios": {
- "version": "1.13.5",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
- "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
- "license": "MIT",
- "dependencies": {
- "follow-redirects": "^1.15.11",
- "form-data": "^4.0.5",
- "proxy-from-env": "^1.1.0"
- }
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/chokidar": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
- "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "readdirp": "^4.0.1"
- },
- "engines": {
- "node": ">= 14.16.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- }
- },
- "node_modules/combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "license": "MIT",
- "dependencies": {
- "delayed-stream": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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==",
- "license": "MIT"
- },
- "node_modules/dayjs": {
- "version": "1.11.19",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz",
- "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==",
- "license": "MIT"
- },
- "node_modules/delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/detect-libc": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
- "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
- "dev": true,
- "license": "Apache-2.0",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/element-plus": {
- "version": "2.13.2",
- "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.13.2.tgz",
- "integrity": "sha512-Zjzm1NnFXGhV4LYZ6Ze9skPlYi2B4KAmN18FL63A3PZcjhDfroHwhtM6RE8BonlOPHXUnPQynH0BgaoEfvhrGw==",
- "license": "MIT",
- "dependencies": {
- "@ctrl/tinycolor": "^3.4.1",
- "@element-plus/icons-vue": "^2.3.2",
- "@floating-ui/dom": "^1.0.1",
- "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7",
- "@types/lodash": "^4.17.20",
- "@types/lodash-es": "^4.17.12",
- "@vueuse/core": "^10.11.0",
- "async-validator": "^4.2.5",
- "dayjs": "^1.11.19",
- "lodash": "^4.17.23",
- "lodash-es": "^4.17.23",
- "lodash-unified": "^1.0.3",
- "memoize-one": "^6.0.0",
- "normalize-wheel-es": "^1.2.0"
- },
- "peerDependencies": {
- "vue": "^3.3.0"
- }
- },
- "node_modules/entities": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
- "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
- "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-set-tostringtag": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
- "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/esbuild": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
- "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.21.5",
- "@esbuild/android-arm": "0.21.5",
- "@esbuild/android-arm64": "0.21.5",
- "@esbuild/android-x64": "0.21.5",
- "@esbuild/darwin-arm64": "0.21.5",
- "@esbuild/darwin-x64": "0.21.5",
- "@esbuild/freebsd-arm64": "0.21.5",
- "@esbuild/freebsd-x64": "0.21.5",
- "@esbuild/linux-arm": "0.21.5",
- "@esbuild/linux-arm64": "0.21.5",
- "@esbuild/linux-ia32": "0.21.5",
- "@esbuild/linux-loong64": "0.21.5",
- "@esbuild/linux-mips64el": "0.21.5",
- "@esbuild/linux-ppc64": "0.21.5",
- "@esbuild/linux-riscv64": "0.21.5",
- "@esbuild/linux-s390x": "0.21.5",
- "@esbuild/linux-x64": "0.21.5",
- "@esbuild/netbsd-x64": "0.21.5",
- "@esbuild/openbsd-x64": "0.21.5",
- "@esbuild/sunos-x64": "0.21.5",
- "@esbuild/win32-arm64": "0.21.5",
- "@esbuild/win32-ia32": "0.21.5",
- "@esbuild/win32-x64": "0.21.5"
- }
- },
- "node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "license": "MIT"
- },
- "node_modules/follow-redirects": {
- "version": "1.15.11",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
- "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
- "funding": [
- {
- "type": "individual",
- "url": "https://github.com/sponsors/RubenVerborgh"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=4.0"
- },
- "peerDependenciesMeta": {
- "debug": {
- "optional": true
- }
- }
- },
- "node_modules/form-data": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
- "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
- "license": "MIT",
- "dependencies": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "es-set-tostringtag": "^2.1.0",
- "hasown": "^2.0.2",
- "mime-types": "^2.1.12"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "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/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
- "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/immutable": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
- "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/lodash": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
- "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
- "license": "MIT"
- },
- "node_modules/lodash-es": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
- "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
- "license": "MIT"
- },
- "node_modules/lodash-unified": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/lodash-unified/-/lodash-unified-1.0.3.tgz",
- "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==",
- "license": "MIT",
- "peerDependencies": {
- "@types/lodash-es": "*",
- "lodash": "*",
- "lodash-es": "*"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/memoize-one": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
- "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
- "license": "MIT"
- },
- "node_modules/mime-db": {
- "version": "1.52.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
- "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "2.1.35",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
- "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
- "license": "MIT",
- "dependencies": {
- "mime-db": "1.52.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/muggle-string": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
- "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/nanoid": {
- "version": "3.3.11",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
- "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
- "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-addon-api": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
- "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
- "dev": true,
- "license": "MIT",
- "optional": true
- },
- "node_modules/normalize-wheel-es": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
- "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/path-browserify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz",
- "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
- "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==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
- "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
- "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
- "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/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "license": "MIT"
- },
- "node_modules/readdirp": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
- "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 14.18.0"
- },
- "funding": {
- "type": "individual",
- "url": "https://paulmillr.com/funding/"
- }
- },
- "node_modules/rollup": {
- "version": "4.59.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz",
- "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "1.0.8"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.59.0",
- "@rollup/rollup-android-arm64": "4.59.0",
- "@rollup/rollup-darwin-arm64": "4.59.0",
- "@rollup/rollup-darwin-x64": "4.59.0",
- "@rollup/rollup-freebsd-arm64": "4.59.0",
- "@rollup/rollup-freebsd-x64": "4.59.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.59.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.59.0",
- "@rollup/rollup-linux-arm64-gnu": "4.59.0",
- "@rollup/rollup-linux-arm64-musl": "4.59.0",
- "@rollup/rollup-linux-loong64-gnu": "4.59.0",
- "@rollup/rollup-linux-loong64-musl": "4.59.0",
- "@rollup/rollup-linux-ppc64-gnu": "4.59.0",
- "@rollup/rollup-linux-ppc64-musl": "4.59.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.59.0",
- "@rollup/rollup-linux-riscv64-musl": "4.59.0",
- "@rollup/rollup-linux-s390x-gnu": "4.59.0",
- "@rollup/rollup-linux-x64-gnu": "4.59.0",
- "@rollup/rollup-linux-x64-musl": "4.59.0",
- "@rollup/rollup-openbsd-x64": "4.59.0",
- "@rollup/rollup-openharmony-arm64": "4.59.0",
- "@rollup/rollup-win32-arm64-msvc": "4.59.0",
- "@rollup/rollup-win32-ia32-msvc": "4.59.0",
- "@rollup/rollup-win32-x64-gnu": "4.59.0",
- "@rollup/rollup-win32-x64-msvc": "4.59.0",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/sass": {
- "version": "1.97.3",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.3.tgz",
- "integrity": "sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "chokidar": "^4.0.0",
- "immutable": "^5.0.2",
- "source-map-js": ">=0.6.2 <2.0.0"
- },
- "bin": {
- "sass": "sass.js"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "optionalDependencies": {
- "@parcel/watcher": "^2.4.1"
- }
- },
- "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==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/typescript": {
- "version": "5.9.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
- "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
- "devOptional": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/undici-types": {
- "version": "7.18.2",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz",
- "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==",
- "dev": true,
- "license": "MIT"
- },
- "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/vscode-uri": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
- "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/vue": {
- "version": "3.5.29",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.29.tgz",
- "integrity": "sha512-BZqN4Ze6mDQVNAni0IHeMJ5mwr8VAJ3MQC9FmprRhcBYENw+wOAAjRj8jfmN6FLl0j96OXbR+CjWhmAmM+QGnA==",
- "license": "MIT",
- "dependencies": {
- "@vue/compiler-dom": "3.5.29",
- "@vue/compiler-sfc": "3.5.29",
- "@vue/runtime-dom": "3.5.29",
- "@vue/server-renderer": "3.5.29",
- "@vue/shared": "3.5.29"
- },
- "peerDependencies": {
- "typescript": "*"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/vue-router": {
- "version": "4.6.4",
- "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
- "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==",
- "license": "MIT",
- "dependencies": {
- "@vue/devtools-api": "^6.6.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/posva"
- },
- "peerDependencies": {
- "vue": "^3.5.0"
- }
- },
- "node_modules/vue-tsc": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.2.5.tgz",
- "integrity": "sha512-/htfTCMluQ+P2FISGAooul8kO4JMheOTCbCy4M6dYnYYjqLe3BExZudAua6MSIKSFYQtFOYAll7XobYwcpokGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@volar/typescript": "2.4.28",
- "@vue/language-core": "3.2.5"
- },
- "bin": {
- "vue-tsc": "bin/vue-tsc.js"
- },
- "peerDependencies": {
- "typescript": ">=5.0.0"
- }
- }
- }
-}
diff --git a/memora-web/package.json b/memora-web/package.json
index 4483580..1f03bb1 100644
--- a/memora-web/package.json
+++ b/memora-web/package.json
@@ -4,6 +4,7 @@
"private": true,
"type": "module",
"scripts": {
+ "preinstall": "node scripts/enforce-pnpm.cjs",
"dev": "vite",
"typecheck": "vue-tsc --noEmit",
"build": "vite build",
@@ -22,5 +23,6 @@
"typescript": "^5.9.3",
"vite": "^5.1.6",
"vue-tsc": "^3.2.5"
- }
+ },
+ "packageManager": "pnpm@10.28.2"
}
diff --git a/memora-web/pnpm-lock.yaml b/memora-web/pnpm-lock.yaml
new file mode 100644
index 0000000..db439c7
--- /dev/null
+++ b/memora-web/pnpm-lock.yaml
@@ -0,0 +1,1456 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ axios:
+ specifier: ^1.6.8
+ version: 1.13.5
+ element-plus:
+ specifier: ^2.7.2
+ version: 2.13.2(vue@3.5.29(typescript@5.9.3))
+ vue:
+ specifier: ^3.4.21
+ version: 3.5.29(typescript@5.9.3)
+ vue-router:
+ specifier: ^4.3.0
+ version: 4.6.4(vue@3.5.29(typescript@5.9.3))
+ devDependencies:
+ '@types/node':
+ specifier: ^25.3.1
+ version: 25.3.2
+ '@vitejs/plugin-vue':
+ specifier: ^5.0.4
+ version: 5.2.4(vite@5.4.21(@types/node@25.3.2)(sass@1.97.3))(vue@3.5.29(typescript@5.9.3))
+ sass:
+ specifier: ^1.97.3
+ version: 1.97.3
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+ vite:
+ specifier: ^5.1.6
+ version: 5.4.21(@types/node@25.3.2)(sass@1.97.3)
+ vue-tsc:
+ specifier: ^3.2.5
+ version: 3.2.5(typescript@5.9.3)
+
+packages:
+
+ '@babel/helper-string-parser@7.27.1':
+ resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.28.5':
+ resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.29.0':
+ resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/types@7.29.0':
+ resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
+ engines: {node: '>=6.9.0'}
+
+ '@ctrl/tinycolor@3.6.1':
+ resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==}
+ engines: {node: '>=10'}
+
+ '@element-plus/icons-vue@2.3.2':
+ resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==}
+ peerDependencies:
+ vue: ^3.2.0
+
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
+ '@floating-ui/core@1.7.4':
+ resolution: {integrity: sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==}
+
+ '@floating-ui/dom@1.7.5':
+ resolution: {integrity: sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==}
+
+ '@floating-ui/utils@0.2.10':
+ resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@parcel/watcher-android-arm64@2.5.6':
+ resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ '@parcel/watcher-darwin-arm64@2.5.6':
+ resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@parcel/watcher-darwin-x64@2.5.6':
+ resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@parcel/watcher-freebsd-x64@2.5.6':
+ resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@parcel/watcher-linux-arm-glibc@2.5.6':
+ resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@parcel/watcher-linux-arm-musl@2.5.6':
+ resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
+
+ '@parcel/watcher-linux-arm64-glibc@2.5.6':
+ resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@parcel/watcher-linux-arm64-musl@2.5.6':
+ resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@parcel/watcher-linux-x64-glibc@2.5.6':
+ resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@parcel/watcher-linux-x64-musl@2.5.6':
+ resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@parcel/watcher-win32-arm64@2.5.6':
+ resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@parcel/watcher-win32-ia32@2.5.6':
+ resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@parcel/watcher-win32-x64@2.5.6':
+ resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==}
+ engines: {node: '>= 10.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ '@parcel/watcher@2.5.6':
+ resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==}
+ engines: {node: '>= 10.0.0'}
+
+ '@rollup/rollup-android-arm-eabi@4.59.0':
+ resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.59.0':
+ resolution: {integrity: sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.59.0':
+ resolution: {integrity: sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.59.0':
+ resolution: {integrity: sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.59.0':
+ resolution: {integrity: sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.59.0':
+ resolution: {integrity: sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.59.0':
+ resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.59.0':
+ resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-arm64-gnu@4.59.0':
+ resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm64-musl@4.59.0':
+ resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-loong64-gnu@4.59.0':
+ resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-loong64-musl@4.59.0':
+ resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.59.0':
+ resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-ppc64-musl@4.59.0':
+ resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.59.0':
+ resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-riscv64-musl@4.59.0':
+ resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-s390x-gnu@4.59.0':
+ resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-gnu@4.59.0':
+ resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-musl@4.59.0':
+ resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-openbsd-x64@4.59.0':
+ resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.59.0':
+ resolution: {integrity: sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.59.0':
+ resolution: {integrity: sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.59.0':
+ resolution: {integrity: sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.59.0':
+ resolution: {integrity: sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.59.0':
+ resolution: {integrity: sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@sxzz/popperjs-es@2.11.8':
+ resolution: {integrity: sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==}
+
+ '@types/estree@1.0.8':
+ resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
+
+ '@types/lodash-es@4.17.12':
+ resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==}
+
+ '@types/lodash@4.17.24':
+ resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==}
+
+ '@types/node@25.3.2':
+ resolution: {integrity: sha512-RpV6r/ij22zRRdyBPcxDeKAzH43phWVKEjL2iksqo1Vz3CuBUrgmPpPhALKiRfU7OMCmeeO9vECBMsV0hMTG8Q==}
+
+ '@types/web-bluetooth@0.0.20':
+ resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+
+ '@vitejs/plugin-vue@5.2.4':
+ resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: ^5.0.0 || ^6.0.0
+ vue: ^3.2.25
+
+ '@volar/language-core@2.4.28':
+ resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==}
+
+ '@volar/source-map@2.4.28':
+ resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==}
+
+ '@volar/typescript@2.4.28':
+ resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==}
+
+ '@vue/compiler-core@3.5.29':
+ resolution: {integrity: sha512-cuzPhD8fwRHk8IGfmYaR4eEe4cAyJEL66Ove/WZL7yWNL134nqLddSLwNRIsFlnnW1kK+p8Ck3viFnC0chXCXw==}
+
+ '@vue/compiler-dom@3.5.29':
+ resolution: {integrity: sha512-n0G5o7R3uBVmVxjTIYcz7ovr8sy7QObFG8OQJ3xGCDNhbG60biP/P5KnyY8NLd81OuT1WJflG7N4KWYHaeeaIg==}
+
+ '@vue/compiler-sfc@3.5.29':
+ resolution: {integrity: sha512-oJZhN5XJs35Gzr50E82jg2cYdZQ78wEwvRO6Y63TvLVTc+6xICzJHP1UIecdSPPYIbkautNBanDiWYa64QSFIA==}
+
+ '@vue/compiler-ssr@3.5.29':
+ resolution: {integrity: sha512-Y/ARJZE6fpjzL5GH/phJmsFwx3g6t2KmHKHx5q+MLl2kencADKIrhH5MLF6HHpRMmlRAYBRSvv347Mepf1zVNw==}
+
+ '@vue/devtools-api@6.6.4':
+ resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==}
+
+ '@vue/language-core@3.2.5':
+ resolution: {integrity: sha512-d3OIxN/+KRedeM5wQ6H6NIpwS3P5gC9nmyaHgBk+rO6dIsjY+tOh4UlPpiZbAh3YtLdCGEX4M16RmsBqPmJV+g==}
+
+ '@vue/reactivity@3.5.29':
+ resolution: {integrity: sha512-zcrANcrRdcLtmGZETBxWqIkoQei8HaFpZWx/GHKxx79JZsiZ8j1du0VUJtu4eJjgFvU/iKL5lRXFXksVmI+5DA==}
+
+ '@vue/runtime-core@3.5.29':
+ resolution: {integrity: sha512-8DpW2QfdwIWOLqtsNcds4s+QgwSaHSJY/SUe04LptianUQ/0xi6KVsu/pYVh+HO3NTVvVJjIPL2t6GdeKbS4Lg==}
+
+ '@vue/runtime-dom@3.5.29':
+ resolution: {integrity: sha512-AHvvJEtcY9tw/uk+s/YRLSlxxQnqnAkjqvK25ZiM4CllCZWzElRAoQnCM42m9AHRLNJ6oe2kC5DCgD4AUdlvXg==}
+
+ '@vue/server-renderer@3.5.29':
+ resolution: {integrity: sha512-G/1k6WK5MusLlbxSE2YTcqAAezS+VuwHhOvLx2KnQU7G2zCH6KIb+5Wyt6UjMq7a3qPzNEjJXs1hvAxDclQH+g==}
+ peerDependencies:
+ vue: 3.5.29
+
+ '@vue/shared@3.5.29':
+ resolution: {integrity: sha512-w7SR0A5zyRByL9XUkCfdLs7t9XOHUyJ67qPGQjOou3p6GvBeBW+AVjUUmlxtZ4PIYaRvE+1LmK44O4uajlZwcg==}
+
+ '@vueuse/core@10.11.1':
+ resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
+
+ '@vueuse/metadata@10.11.1':
+ resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
+
+ '@vueuse/shared@10.11.1':
+ resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
+
+ alien-signals@3.1.2:
+ resolution: {integrity: sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==}
+
+ async-validator@4.2.5:
+ resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ axios@1.13.5:
+ resolution: {integrity: sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ csstype@3.2.3:
+ resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
+
+ dayjs@1.11.19:
+ resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ element-plus@2.13.2:
+ resolution: {integrity: sha512-Zjzm1NnFXGhV4LYZ6Ze9skPlYi2B4KAmN18FL63A3PZcjhDfroHwhtM6RE8BonlOPHXUnPQynH0BgaoEfvhrGw==}
+ peerDependencies:
+ vue: ^3.3.0
+
+ entities@7.0.1:
+ resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
+ engines: {node: '>=0.12'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-object-atoms@1.1.1:
+ resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ follow-redirects@1.15.11:
+ resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ form-data@4.0.5:
+ resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
+ engines: {node: '>= 6'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ immutable@5.1.4:
+ resolution: {integrity: sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ lodash-es@4.17.23:
+ resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==}
+
+ lodash-unified@1.0.3:
+ resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==}
+ peerDependencies:
+ '@types/lodash-es': '*'
+ lodash: '*'
+ lodash-es: '*'
+
+ lodash@4.17.23:
+ resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ memoize-one@6.0.0:
+ resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.11:
+ resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ node-addon-api@7.1.1:
+ resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
+
+ normalize-wheel-es@1.2.0:
+ resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.3:
+ resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
+ engines: {node: '>=12'}
+
+ postcss@8.5.6:
+ resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ rollup@4.59.0:
+ resolution: {integrity: sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ sass@1.97.3:
+ resolution: {integrity: sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@7.18.2:
+ resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
+
+ vite@5.4.21:
+ resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ 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
+
+ vscode-uri@3.1.0:
+ resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-router@4.6.4:
+ resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==}
+ peerDependencies:
+ vue: ^3.5.0
+
+ vue-tsc@3.2.5:
+ resolution: {integrity: sha512-/htfTCMluQ+P2FISGAooul8kO4JMheOTCbCy4M6dYnYYjqLe3BExZudAua6MSIKSFYQtFOYAll7XobYwcpokGA==}
+ hasBin: true
+ peerDependencies:
+ typescript: '>=5.0.0'
+
+ vue@3.5.29:
+ resolution: {integrity: sha512-BZqN4Ze6mDQVNAni0IHeMJ5mwr8VAJ3MQC9FmprRhcBYENw+wOAAjRj8jfmN6FLl0j96OXbR+CjWhmAmM+QGnA==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+snapshots:
+
+ '@babel/helper-string-parser@7.27.1': {}
+
+ '@babel/helper-validator-identifier@7.28.5': {}
+
+ '@babel/parser@7.29.0':
+ dependencies:
+ '@babel/types': 7.29.0
+
+ '@babel/types@7.29.0':
+ dependencies:
+ '@babel/helper-string-parser': 7.27.1
+ '@babel/helper-validator-identifier': 7.28.5
+
+ '@ctrl/tinycolor@3.6.1': {}
+
+ '@element-plus/icons-vue@2.3.2(vue@3.5.29(typescript@5.9.3))':
+ dependencies:
+ vue: 3.5.29(typescript@5.9.3)
+
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@floating-ui/core@1.7.4':
+ dependencies:
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/dom@1.7.5':
+ dependencies:
+ '@floating-ui/core': 1.7.4
+ '@floating-ui/utils': 0.2.10
+
+ '@floating-ui/utils@0.2.10': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@parcel/watcher-android-arm64@2.5.6':
+ optional: true
+
+ '@parcel/watcher-darwin-arm64@2.5.6':
+ optional: true
+
+ '@parcel/watcher-darwin-x64@2.5.6':
+ optional: true
+
+ '@parcel/watcher-freebsd-x64@2.5.6':
+ optional: true
+
+ '@parcel/watcher-linux-arm-glibc@2.5.6':
+ optional: true
+
+ '@parcel/watcher-linux-arm-musl@2.5.6':
+ optional: true
+
+ '@parcel/watcher-linux-arm64-glibc@2.5.6':
+ optional: true
+
+ '@parcel/watcher-linux-arm64-musl@2.5.6':
+ optional: true
+
+ '@parcel/watcher-linux-x64-glibc@2.5.6':
+ optional: true
+
+ '@parcel/watcher-linux-x64-musl@2.5.6':
+ optional: true
+
+ '@parcel/watcher-win32-arm64@2.5.6':
+ optional: true
+
+ '@parcel/watcher-win32-ia32@2.5.6':
+ optional: true
+
+ '@parcel/watcher-win32-x64@2.5.6':
+ optional: true
+
+ '@parcel/watcher@2.5.6':
+ dependencies:
+ detect-libc: 2.1.2
+ is-glob: 4.0.3
+ node-addon-api: 7.1.1
+ picomatch: 4.0.3
+ optionalDependencies:
+ '@parcel/watcher-android-arm64': 2.5.6
+ '@parcel/watcher-darwin-arm64': 2.5.6
+ '@parcel/watcher-darwin-x64': 2.5.6
+ '@parcel/watcher-freebsd-x64': 2.5.6
+ '@parcel/watcher-linux-arm-glibc': 2.5.6
+ '@parcel/watcher-linux-arm-musl': 2.5.6
+ '@parcel/watcher-linux-arm64-glibc': 2.5.6
+ '@parcel/watcher-linux-arm64-musl': 2.5.6
+ '@parcel/watcher-linux-x64-glibc': 2.5.6
+ '@parcel/watcher-linux-x64-musl': 2.5.6
+ '@parcel/watcher-win32-arm64': 2.5.6
+ '@parcel/watcher-win32-ia32': 2.5.6
+ '@parcel/watcher-win32-x64': 2.5.6
+ optional: true
+
+ '@rollup/rollup-android-arm-eabi@4.59.0':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.59.0':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.59.0':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.59.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.59.0':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.59.0':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.59.0':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.59.0':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.59.0':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.59.0':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.59.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.59.0':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.59.0':
+ optional: true
+
+ '@sxzz/popperjs-es@2.11.8': {}
+
+ '@types/estree@1.0.8': {}
+
+ '@types/lodash-es@4.17.12':
+ dependencies:
+ '@types/lodash': 4.17.24
+
+ '@types/lodash@4.17.24': {}
+
+ '@types/node@25.3.2':
+ dependencies:
+ undici-types: 7.18.2
+
+ '@types/web-bluetooth@0.0.20': {}
+
+ '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@25.3.2)(sass@1.97.3))(vue@3.5.29(typescript@5.9.3))':
+ dependencies:
+ vite: 5.4.21(@types/node@25.3.2)(sass@1.97.3)
+ vue: 3.5.29(typescript@5.9.3)
+
+ '@volar/language-core@2.4.28':
+ dependencies:
+ '@volar/source-map': 2.4.28
+
+ '@volar/source-map@2.4.28': {}
+
+ '@volar/typescript@2.4.28':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ path-browserify: 1.0.1
+ vscode-uri: 3.1.0
+
+ '@vue/compiler-core@3.5.29':
+ dependencies:
+ '@babel/parser': 7.29.0
+ '@vue/shared': 3.5.29
+ entities: 7.0.1
+ estree-walker: 2.0.2
+ source-map-js: 1.2.1
+
+ '@vue/compiler-dom@3.5.29':
+ dependencies:
+ '@vue/compiler-core': 3.5.29
+ '@vue/shared': 3.5.29
+
+ '@vue/compiler-sfc@3.5.29':
+ dependencies:
+ '@babel/parser': 7.29.0
+ '@vue/compiler-core': 3.5.29
+ '@vue/compiler-dom': 3.5.29
+ '@vue/compiler-ssr': 3.5.29
+ '@vue/shared': 3.5.29
+ estree-walker: 2.0.2
+ magic-string: 0.30.21
+ postcss: 8.5.6
+ source-map-js: 1.2.1
+
+ '@vue/compiler-ssr@3.5.29':
+ dependencies:
+ '@vue/compiler-dom': 3.5.29
+ '@vue/shared': 3.5.29
+
+ '@vue/devtools-api@6.6.4': {}
+
+ '@vue/language-core@3.2.5':
+ dependencies:
+ '@volar/language-core': 2.4.28
+ '@vue/compiler-dom': 3.5.29
+ '@vue/shared': 3.5.29
+ alien-signals: 3.1.2
+ muggle-string: 0.4.1
+ path-browserify: 1.0.1
+ picomatch: 4.0.3
+
+ '@vue/reactivity@3.5.29':
+ dependencies:
+ '@vue/shared': 3.5.29
+
+ '@vue/runtime-core@3.5.29':
+ dependencies:
+ '@vue/reactivity': 3.5.29
+ '@vue/shared': 3.5.29
+
+ '@vue/runtime-dom@3.5.29':
+ dependencies:
+ '@vue/reactivity': 3.5.29
+ '@vue/runtime-core': 3.5.29
+ '@vue/shared': 3.5.29
+ csstype: 3.2.3
+
+ '@vue/server-renderer@3.5.29(vue@3.5.29(typescript@5.9.3))':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.29
+ '@vue/shared': 3.5.29
+ vue: 3.5.29(typescript@5.9.3)
+
+ '@vue/shared@3.5.29': {}
+
+ '@vueuse/core@10.11.1(vue@3.5.29(typescript@5.9.3))':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 10.11.1
+ '@vueuse/shared': 10.11.1(vue@3.5.29(typescript@5.9.3))
+ vue-demi: 0.14.10(vue@3.5.29(typescript@5.9.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/metadata@10.11.1': {}
+
+ '@vueuse/shared@10.11.1(vue@3.5.29(typescript@5.9.3))':
+ dependencies:
+ vue-demi: 0.14.10(vue@3.5.29(typescript@5.9.3))
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ alien-signals@3.1.2: {}
+
+ async-validator@4.2.5: {}
+
+ asynckit@0.4.0: {}
+
+ axios@1.13.5:
+ dependencies:
+ follow-redirects: 1.15.11
+ form-data: 4.0.5
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ csstype@3.2.3: {}
+
+ dayjs@1.11.19: {}
+
+ delayed-stream@1.0.0: {}
+
+ detect-libc@2.1.2:
+ optional: true
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ element-plus@2.13.2(vue@3.5.29(typescript@5.9.3)):
+ dependencies:
+ '@ctrl/tinycolor': 3.6.1
+ '@element-plus/icons-vue': 2.3.2(vue@3.5.29(typescript@5.9.3))
+ '@floating-ui/dom': 1.7.5
+ '@popperjs/core': '@sxzz/popperjs-es@2.11.8'
+ '@types/lodash': 4.17.24
+ '@types/lodash-es': 4.17.12
+ '@vueuse/core': 10.11.1(vue@3.5.29(typescript@5.9.3))
+ async-validator: 4.2.5
+ dayjs: 1.11.19
+ lodash: 4.17.23
+ lodash-es: 4.17.23
+ lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.23)(lodash@4.17.23)
+ memoize-one: 6.0.0
+ normalize-wheel-es: 1.2.0
+ vue: 3.5.29(typescript@5.9.3)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+
+ entities@7.0.1: {}
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-object-atoms@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.2
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ estree-walker@2.0.2: {}
+
+ follow-redirects@1.15.11: {}
+
+ form-data@4.0.5:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ es-set-tostringtag: 2.1.0
+ hasown: 2.0.2
+ mime-types: 2.1.35
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.1
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.2
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.1
+
+ gopd@1.2.0: {}
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ immutable@5.1.4: {}
+
+ is-extglob@2.1.1:
+ optional: true
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+ optional: true
+
+ lodash-es@4.17.23: {}
+
+ lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.23)(lodash@4.17.23):
+ dependencies:
+ '@types/lodash-es': 4.17.12
+ lodash: 4.17.23
+ lodash-es: 4.17.23
+
+ lodash@4.17.23: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ math-intrinsics@1.1.0: {}
+
+ memoize-one@6.0.0: {}
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.11: {}
+
+ node-addon-api@7.1.1:
+ optional: true
+
+ normalize-wheel-es@1.2.0: {}
+
+ path-browserify@1.0.1: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.3: {}
+
+ postcss@8.5.6:
+ dependencies:
+ nanoid: 3.3.11
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ proxy-from-env@1.1.0: {}
+
+ readdirp@4.1.2: {}
+
+ rollup@4.59.0:
+ dependencies:
+ '@types/estree': 1.0.8
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.59.0
+ '@rollup/rollup-android-arm64': 4.59.0
+ '@rollup/rollup-darwin-arm64': 4.59.0
+ '@rollup/rollup-darwin-x64': 4.59.0
+ '@rollup/rollup-freebsd-arm64': 4.59.0
+ '@rollup/rollup-freebsd-x64': 4.59.0
+ '@rollup/rollup-linux-arm-gnueabihf': 4.59.0
+ '@rollup/rollup-linux-arm-musleabihf': 4.59.0
+ '@rollup/rollup-linux-arm64-gnu': 4.59.0
+ '@rollup/rollup-linux-arm64-musl': 4.59.0
+ '@rollup/rollup-linux-loong64-gnu': 4.59.0
+ '@rollup/rollup-linux-loong64-musl': 4.59.0
+ '@rollup/rollup-linux-ppc64-gnu': 4.59.0
+ '@rollup/rollup-linux-ppc64-musl': 4.59.0
+ '@rollup/rollup-linux-riscv64-gnu': 4.59.0
+ '@rollup/rollup-linux-riscv64-musl': 4.59.0
+ '@rollup/rollup-linux-s390x-gnu': 4.59.0
+ '@rollup/rollup-linux-x64-gnu': 4.59.0
+ '@rollup/rollup-linux-x64-musl': 4.59.0
+ '@rollup/rollup-openbsd-x64': 4.59.0
+ '@rollup/rollup-openharmony-arm64': 4.59.0
+ '@rollup/rollup-win32-arm64-msvc': 4.59.0
+ '@rollup/rollup-win32-ia32-msvc': 4.59.0
+ '@rollup/rollup-win32-x64-gnu': 4.59.0
+ '@rollup/rollup-win32-x64-msvc': 4.59.0
+ fsevents: 2.3.3
+
+ sass@1.97.3:
+ dependencies:
+ chokidar: 4.0.3
+ immutable: 5.1.4
+ source-map-js: 1.2.1
+ optionalDependencies:
+ '@parcel/watcher': 2.5.6
+
+ source-map-js@1.2.1: {}
+
+ typescript@5.9.3: {}
+
+ undici-types@7.18.2: {}
+
+ vite@5.4.21(@types/node@25.3.2)(sass@1.97.3):
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.5.6
+ rollup: 4.59.0
+ optionalDependencies:
+ '@types/node': 25.3.2
+ fsevents: 2.3.3
+ sass: 1.97.3
+
+ vscode-uri@3.1.0: {}
+
+ vue-demi@0.14.10(vue@3.5.29(typescript@5.9.3)):
+ dependencies:
+ vue: 3.5.29(typescript@5.9.3)
+
+ vue-router@4.6.4(vue@3.5.29(typescript@5.9.3)):
+ dependencies:
+ '@vue/devtools-api': 6.6.4
+ vue: 3.5.29(typescript@5.9.3)
+
+ vue-tsc@3.2.5(typescript@5.9.3):
+ dependencies:
+ '@volar/typescript': 2.4.28
+ '@vue/language-core': 3.2.5
+ typescript: 5.9.3
+
+ vue@3.5.29(typescript@5.9.3):
+ dependencies:
+ '@vue/compiler-dom': 3.5.29
+ '@vue/compiler-sfc': 3.5.29
+ '@vue/runtime-dom': 3.5.29
+ '@vue/server-renderer': 3.5.29(vue@3.5.29(typescript@5.9.3))
+ '@vue/shared': 3.5.29
+ optionalDependencies:
+ typescript: 5.9.3
diff --git a/memora-web/scripts/enforce-pnpm.cjs b/memora-web/scripts/enforce-pnpm.cjs
new file mode 100644
index 0000000..336933d
--- /dev/null
+++ b/memora-web/scripts/enforce-pnpm.cjs
@@ -0,0 +1,6 @@
+const userAgent = process.env.npm_config_user_agent || "";
+
+if (!userAgent.includes("pnpm")) {
+ console.error("This project requires pnpm. Please run: pnpm install");
+ process.exit(1);
+}
diff --git a/memora-web/src/App.vue b/memora-web/src/App.vue
index a32f81f..3c7d693 100644
--- a/memora-web/src/App.vue
+++ b/memora-web/src/App.vue
@@ -2,22 +2,30 @@
-
+
+ {{ routeTitle }}
+ {{ todayText }}
+
@@ -26,41 +34,97 @@
diff --git a/memora-web/src/app/routes.ts b/memora-web/src/app/routes.ts
index 8cd39fe..d345d90 100644
--- a/memora-web/src/app/routes.ts
+++ b/memora-web/src/app/routes.ts
@@ -1,17 +1,18 @@
-import Dashboard from '../views/Home.vue'
import Memory from '../views/Memory.vue'
import Review from '../views/Review.vue'
import Statistics from '../views/Statistics.vue'
+import StatisticsDetail from '../views/StatisticsDetail.vue'
import Words from '../views/Words.vue'
import Settings from '../views/Settings.vue'
import Login from '../views/Login.vue'
export const routes = [
{ path: '/login', name: 'login', component: Login, meta: { public: true, fullPage: true } },
- { path: '/', name: 'dashboard', component: Dashboard },
+ { path: '/', redirect: '/memory' },
{ path: '/memory', name: 'memory', component: Memory },
{ path: '/review', name: 'review', component: Review },
{ path: '/statistics', name: 'statistics', component: Statistics },
+ { path: '/statistics/:metric', name: 'statistics-detail', component: StatisticsDetail },
{ path: '/words', name: 'words', component: Words },
{ path: '/settings', name: 'settings', component: Settings }
]
diff --git a/memora-web/src/modules/preferences/store.ts b/memora-web/src/modules/preferences/store.ts
new file mode 100644
index 0000000..236f959
--- /dev/null
+++ b/memora-web/src/modules/preferences/store.ts
@@ -0,0 +1,113 @@
+export type WordBook = 'cet4' | 'ielts' | 'toefl' | 'custom'
+export type Pronunciation = 'uk' | 'us'
+
+export interface StudyPlan {
+ wordBook: WordBook
+ dailyTarget: number
+ remindAt: string
+ locked: boolean
+}
+
+export interface UserProfile {
+ nickname: string
+ avatar: string
+}
+
+export interface Preferences {
+ plan: StudyPlan
+ pronunciation: Pronunciation
+ profile: UserProfile
+}
+
+const PREF_KEY = 'memora.preferences'
+const LEARNED_KEY = 'memora.today.learned'
+const DATE_KEY = 'memora.today.date'
+const LEARNED_WORD_IDS_KEY = 'memora.today.learned.word_ids'
+
+function todayKey() {
+ const now = new Date()
+ return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`
+}
+
+export function defaultPreferences(): Preferences {
+ return {
+ plan: {
+ wordBook: 'cet4',
+ dailyTarget: 20,
+ remindAt: '21:00',
+ locked: false
+ },
+ pronunciation: 'uk',
+ profile: {
+ nickname: 'Memora 用户',
+ avatar: ''
+ }
+ }
+}
+
+export function loadPreferences(): Preferences {
+ try {
+ const raw = localStorage.getItem(PREF_KEY)
+ if (!raw) return defaultPreferences()
+ const parsed = JSON.parse(raw) as Preferences
+ const defaults = defaultPreferences()
+ return {
+ plan: {
+ ...defaults.plan,
+ ...(parsed.plan || {})
+ },
+ pronunciation: parsed.pronunciation || defaults.pronunciation,
+ profile: {
+ ...defaults.profile,
+ ...(parsed.profile || {})
+ }
+ }
+ } catch {
+ return defaultPreferences()
+ }
+}
+
+export function savePreferences(pref: Preferences) {
+ localStorage.setItem(PREF_KEY, JSON.stringify(pref))
+}
+
+export function recordTodayLearned(count: number) {
+ const today = todayKey()
+ const oldDate = localStorage.getItem(DATE_KEY)
+ const oldCount = Number(localStorage.getItem(LEARNED_KEY) || '0')
+ const nextCount = oldDate === today ? oldCount + count : count
+ localStorage.setItem(DATE_KEY, today)
+ localStorage.setItem(LEARNED_KEY, String(nextCount))
+}
+
+export function getTodayLearned() {
+ return getTodayLearnedWordIds().length
+}
+
+export function getTodayLearnedWordIds(): number[] {
+ const today = todayKey()
+ const oldDate = localStorage.getItem(DATE_KEY)
+ if (oldDate !== today) {
+ localStorage.setItem(DATE_KEY, today)
+ localStorage.setItem(LEARNED_WORD_IDS_KEY, '[]')
+ localStorage.setItem(LEARNED_KEY, '0')
+ return []
+ }
+
+ try {
+ const raw = localStorage.getItem(LEARNED_WORD_IDS_KEY)
+ if (!raw) return []
+ const ids = JSON.parse(raw) as number[]
+ return Array.isArray(ids) ? ids.filter((id) => Number.isFinite(id)) : []
+ } catch {
+ return []
+ }
+}
+
+export function markTodayLearnedWord(wordID: number) {
+ const ids = getTodayLearnedWordIds()
+ if (ids.includes(wordID)) return
+ const next = [...ids, wordID]
+ localStorage.setItem(LEARNED_WORD_IDS_KEY, JSON.stringify(next))
+ localStorage.setItem(LEARNED_KEY, String(next.length))
+}
diff --git a/memora-web/src/services/api/review.ts b/memora-web/src/services/api/review.ts
index 65a3c21..2f98a14 100644
--- a/memora-web/src/services/api/review.ts
+++ b/memora-web/src/services/api/review.ts
@@ -2,12 +2,12 @@ import { http } from '../http'
import type { MemoryRecord, ReviewMode, ReviewResult } from './types'
export async function getReviewWords(params: { mode?: ReviewMode; limit?: number } = {}) {
- const res = await http.get<{ data: MemoryRecord[] }>('/review', { params })
+ const res = await http.get<{ data: MemoryRecord[] }>('/review/today', { params })
return res.data
}
export async function submitReview(payload: { recordId: number; answer: string; mode: ReviewMode }) {
- const res = await http.post<{ data: ReviewResult }>('/review', {
+ const res = await http.post<{ data: ReviewResult }>('/review/submit', {
record_id: payload.recordId,
answer: payload.answer,
mode: payload.mode
diff --git a/memora-web/src/services/api/stats.ts b/memora-web/src/services/api/stats.ts
index 1177641..4395710 100644
--- a/memora-web/src/services/api/stats.ts
+++ b/memora-web/src/services/api/stats.ts
@@ -2,6 +2,6 @@ import { http } from '../http'
import type { Stats } from './types'
export async function getStatistics() {
- const res = await http.get<{ data: Stats }>('/stats')
+ const res = await http.get<{ data: Stats }>('/stats/overview')
return res.data
}
diff --git a/memora-web/src/services/api/words.ts b/memora-web/src/services/api/words.ts
index 4c5314a..acbec9f 100644
--- a/memora-web/src/services/api/words.ts
+++ b/memora-web/src/services/api/words.ts
@@ -11,7 +11,12 @@ export async function getWords(params: { limit?: number; offset?: number; q?: st
return res.data
}
+export async function getWordById(id: number) {
+ const res = await http.get<{ data: Word }>(`/words/${id}`)
+ return res.data
+}
+
export function audioUrl(word: string, type: 'uk' | 'us' = 'uk') {
const q = new URLSearchParams({ word, type })
- return `/api/audio?${q.toString()}`
+ return `/api/v1/audio?${q.toString()}`
}
diff --git a/memora-web/src/services/http.ts b/memora-web/src/services/http.ts
index 84819fb..a00524a 100644
--- a/memora-web/src/services/http.ts
+++ b/memora-web/src/services/http.ts
@@ -2,7 +2,7 @@ import axios from 'axios'
import { clearToken, getToken } from '../modules/auth/auth'
export const http = axios.create({
- baseURL: '/api',
+ baseURL: '/api/v1',
timeout: 15000
})
diff --git a/memora-web/src/styles/index.scss b/memora-web/src/styles/index.scss
index cbfe7ab..d0f67f2 100644
--- a/memora-web/src/styles/index.scss
+++ b/memora-web/src/styles/index.scss
@@ -1,9 +1,9 @@
:root {
- --memora-bg: #f4f5fb;
- --memora-border: #eceef3;
- --memora-text: #111827;
- --memora-sub: #6b7280;
- --memora-primary: #2f7d32;
+ --memora-bg: #eef2fb;
+ --memora-border: #e4ebf7;
+ --memora-text: #101828;
+ --memora-sub: #667085;
+ --memora-primary: #2447d6;
}
html, body {
@@ -14,5 +14,9 @@ body {
margin: 0;
background: var(--memora-bg);
color: var(--memora-text);
- font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji";
+ font-family: "Manrope", "Noto Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
+}
+
+#app {
+ min-height: 100vh;
}
diff --git a/memora-web/src/views/Home.vue b/memora-web/src/views/Home.vue
index 0fc36f0..ac6389f 100644
--- a/memora-web/src/views/Home.vue
+++ b/memora-web/src/views/Home.vue
@@ -1,19 +1,31 @@
-
-
仪表盘
-
欢迎回来,继续你的学习之旅
+
+
+ 长期记忆留存学习系统
+ 学习 → 测试 → 复习闭环,基于 SRS 调度今日任务
+
+ 开始新词学习
+ 进入今日复习
+
+
-
-
-
-
+
+
+
+
-
- 开始复习
- 添加单词
-
+
+
+ 当前阶段验收项
+
+
+ 注册/登录 + 受保护接口
+ 学习会话 + 复习提交 + 今日任务
+ 统计面板 + 体验优化
+
+
@@ -21,7 +33,6 @@
import { onMounted, ref } from 'vue'
import { getStatistics } from '../services/api'
import MetricCard from '../components/base/MetricCard.vue'
-
import type { Stats } from '../services/api'
const stats = ref
({
@@ -37,13 +48,43 @@ async function refresh() {
}
onMounted(() => refresh().catch(console.error))
-
-
diff --git a/memora-web/src/views/Memory.vue b/memora-web/src/views/Memory.vue
index dbacda9..c0708c3 100644
--- a/memora-web/src/views/Memory.vue
+++ b/memora-web/src/views/Memory.vue
@@ -1,164 +1,491 @@
-
-
-
-
-
-
学习会话
-
系统按最新单词生成学习队列,完成后自动计入复习数据
-
-
开始学习
-
-
-
-
-
-
-
-
- 提交
- 下一个
-
-
-
- 正确答案:{{ sessionResult.correct_ans || sessionWord.word }}
+
-
-
-
-
-
-
记忆模式
-
输入单词并回车,会调用后端(后端再调用有道)校验并入库
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 确认学习计划
+
+
+
+
+
+ {{ wordBookLabel(preferences.plan.wordBook) }}
+ {{ preferences.plan.dailyTarget }}
+ {{ preferences.plan.remindAt }}
+ {{ preferences.pronunciation === 'us' ? '美音' : '英音' }}
+
+ 去设置页修改
+
+
+
+
+
+
+
+
+
+
学习与复习
+
学习按四阶段推进;复习按当日队列执行,目标与学习计划一致
+
+
+ 开始学习
+ 开始复习
+
+
+
+
+
+
+
+
+ {{ currentPhase.title }}
+ 阶段进度:{{ currentWordIndex + 1 }} / {{ sessionWords.length }}
+ 总进度:{{ phaseIndex + 1 }} / {{ phases.length }}
+
+
+
+
+
+ 正确率{{ accuracyText }}
+ 连续正确{{ stats.streak }}
+ 累计耗时{{ stats.spentSec }}s
+ 已完成{{ completedWords }}
+
+
+
+
+ 四阶段已全部完成,已记录今日学习量。
+
+
+
+
+
{{ currentPhase.description }}
+
+
+ {{ currentWord?.word }}
+ {{ currentWord?.example_sentence || '暂无例句' }}
+
+
+
+ {{ currentWord?.definition || '暂无释义' }}
+
+
+
+
+ 播放读音
+ 根据读音作答
+
+
+
+
+
+ {{ option }}
+
+
+
+
+
+ 提交
+
+
+
+
+
+
+
+
+
+
+
+ 新词入库
- 确认
+ 确认入库
-
+
{{ saved.word }}
- {{ saved.part_of_speech }}
{{ saved.definition }}
- {{ saved.phonetic_uk || '暂无' }}
- {{ saved.phonetic_us || '暂无' }}
{{ saved.example_sentence || '暂无' }}
-
- 播放英音
- 播放美音
-
diff --git a/memora-web/src/views/Review.vue b/memora-web/src/views/Review.vue
index dcc6ab3..127523e 100644
--- a/memora-web/src/views/Review.vue
+++ b/memora-web/src/views/Review.vue
@@ -68,11 +68,15 @@
+
+
diff --git a/memora-web/src/views/Statistics.vue b/memora-web/src/views/Statistics.vue
index f26858f..0f96b37 100644
--- a/memora-web/src/views/Statistics.vue
+++ b/memora-web/src/views/Statistics.vue
@@ -1,45 +1,117 @@
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
今日已学
+
{{ todayLearned }}
+
点击查看详情
+
+
+
+
+
今日复习
+
{{ stats.today_reviewed }}
+
点击查看详情
+
+
+
+
+
已掌握
+
{{ stats.mastered_words }}
+
点击查看详情
+
+
+
+
+
总词汇
+
{{ stats.total_words }}
+
点击查看详情
+
+
+
+
diff --git a/memora-web/src/views/StatisticsDetail.vue b/memora-web/src/views/StatisticsDetail.vue
new file mode 100644
index 0000000..7d68816
--- /dev/null
+++ b/memora-web/src/views/StatisticsDetail.vue
@@ -0,0 +1,54 @@
+
+
+
+
+
{{ config.title }}详情
+
返回统计
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+