dsh-completion-reminder 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -61
- package/install.md +17 -20
- package/lib/client.d.ts +24 -16
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +517 -361
- package/lib/client.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -4,103 +4,114 @@
|
|
|
4
4
|
当 agent 停止生成(成功 / 主动停止 / 出错)时,弹一个通知给用户。
|
|
5
5
|
|
|
6
6
|
- 🌐 默认走 **浏览器原生通知**(`window.Notification`,首次使用需要用户授权)
|
|
7
|
-
- ⚙️
|
|
7
|
+
- ⚙️ 直接在 DSH 自己的 **「设置 → 插件 → 🔔 完成提醒」** 里配置(与「可配置」同级 tab)
|
|
8
|
+
- 🔒 **凭证按渠道筛选**:选 Telegram 只显示 2 项,选 Bark 只显示 1–2 项,不会一下子蹦出 11 个无关字段
|
|
9
|
+
- 🎨 **暗色 / 亮色主题都正常**(`color-scheme: light dark` + 显式前景色,再无「白底白字」)
|
|
8
10
|
- 💾 配置保存在本浏览器 `localStorage`,不会上传任何服务器
|
|
9
11
|
- 🧪 配置面板自带 **「发送测试通知」** 按钮,方便验证渠道是否通
|
|
10
12
|
- 🪟 标签页可见时默认静默(不打断工作),可通过开关关闭
|
|
11
13
|
- ⏱ 内置 5 秒冷却,避免连续 agent 完成时刷屏
|
|
12
|
-
- 🎨 标题/正文可定制,匹配 `success` / `stopped` / `error` 三种状态
|
|
13
14
|
|
|
14
15
|
## 9 种通知渠道
|
|
15
16
|
|
|
16
|
-
| 渠道 | 适用人群 |
|
|
17
|
-
|
|
18
|
-
| 🌐 **browser**(默认) | 任何浏览器 |
|
|
19
|
-
| ✈️ **Telegram** | Telegram 重度用户 |
|
|
20
|
-
| 🍎 **Bark** | iPhone 用户 |
|
|
21
|
-
| 📲 **Pushover** | 跨平台推送服务 |
|
|
22
|
-
| 🐦 **Server酱** | 国内微信推送 |
|
|
23
|
-
| 🎮 **Discord** | Discord 玩家 / 团队 |
|
|
24
|
-
| 💼 **Slack** | 团队工作区 |
|
|
25
|
-
| 🔗 **Webhook** | 自建服务 |
|
|
26
|
-
| 🛠 **Custom** | 完全自定义 |
|
|
17
|
+
| 渠道 | 适用人群 | 配置字段(按当前渠道只显示需要的) |
|
|
18
|
+
|------|----------|--------------------|
|
|
19
|
+
| 🌐 **browser**(默认) | 任何浏览器 | 无 |
|
|
20
|
+
| ✈️ **Telegram** | Telegram 重度用户 | Bot Token / Chat ID |
|
|
21
|
+
| 🍎 **Bark** | iPhone 用户 | Bark Key / Bark Server(可选) |
|
|
22
|
+
| 📲 **Pushover** | 跨平台推送服务 | App Token / User Key / Device(可选) |
|
|
23
|
+
| 🐦 **Server酱** | 国内微信推送 | SendKey |
|
|
24
|
+
| 🎮 **Discord** | Discord 玩家 / 团队 | Webhook URL |
|
|
25
|
+
| 💼 **Slack** | 团队工作区 | Webhook URL |
|
|
26
|
+
| 🔗 **Webhook** | 自建服务 | URL |
|
|
27
|
+
| 🛠 **Custom** | 完全自定义 | 占位(`customSend(payload)`) |
|
|
27
28
|
|
|
28
|
-
## 工作原理(v1.
|
|
29
|
+
## 工作原理(v1.3)
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
### 1. 完成检测
|
|
32
|
+
|
|
33
|
+
DSH composer 卡片 `<div data-composer-card="true">` 内的主按钮 `aria-label` 会在
|
|
34
|
+
`"Stop generating"` / `"Send message"`(中文 UI 是 `"停止生成"` / `"发送消息"`)之间切换。
|
|
35
|
+
插件用 `MutationObserver` 监听这个属性变化:
|
|
33
36
|
|
|
34
37
|
- 检测到 `Stop generating` → 记录开始时间
|
|
35
38
|
- 检测到 `Send message` → 触发完成事件
|
|
36
|
-
- 根据 `data-phase
|
|
39
|
+
- 根据 `data-phase`(`active` / `settling` / `hero`)和最后一条 `data-role="assistant"`
|
|
37
40
|
消息的文本/类名,判断 `success` / `stopped` / `error`
|
|
38
41
|
- 派发到当前渠道,调用 `Notification` / `fetch` 发送
|
|
39
42
|
|
|
40
|
-
所有匹配都用 **稳定属性**(`data-*`、`aria-label`、`type
|
|
41
|
-
哈希改变的 class 名(`uV2eYG_primary` 这类),跨 DSH 版本更稳。
|
|
43
|
+
所有匹配都用 **稳定属性**(`data-*`、`aria-label`、`type`),不依赖 CSS-modules 哈希后的 class 名。
|
|
42
44
|
|
|
43
|
-
|
|
45
|
+
### 2. 设置面板
|
|
44
46
|
|
|
45
|
-
|
|
47
|
+
通过 DSH 的 `ctx.slots.inject('settings.plugins.tab', ...)` API,插件把自己注册成
|
|
48
|
+
DSH 「插件」section 里与「可配置」**同级**的一个 tab:
|
|
46
49
|
|
|
47
|
-
```
|
|
48
|
-
|
|
50
|
+
```
|
|
51
|
+
DSH 设置弹窗 → 插件
|
|
52
|
+
├─ 可配置 ← DSH 自带(编辑插件配置)
|
|
53
|
+
├─ 🔔 完成提醒 ← 本插件
|
|
49
54
|
```
|
|
50
55
|
|
|
51
|
-
|
|
52
|
-
`dsh plugin add` 完成依赖安装后,DSH 会自动把插件加入 profile 的 bundles 层堆栈,重启后即生效。
|
|
56
|
+
`settings.section` 同样被注册作为兜底(旧版本或非标准 host 仍能找到入口)。
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
- 通知渠道下拉(切换渠道时,凭证区**实时刷新**)
|
|
59
|
+
- 当前渠道**只显示需要的字段**(不需要在 11 个无关字段里翻找)
|
|
60
|
+
- 行为开关(成功 / 停止 / 出错 / 焦点抑制 / 自动请求权限 / 冷却)
|
|
61
|
+
- 「发送测试通知」 / 「重置」 / 「请求权限」三个动作
|
|
55
62
|
|
|
56
|
-
|
|
57
|
-
dsh plugin --profile web add -w dsh-completion-reminder
|
|
58
|
-
```
|
|
63
|
+
**没多出任何悬浮按钮**,UI 与 DSH 原生设置完全一致。
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
### 3. 降级
|
|
66
|
+
|
|
67
|
+
如果加载时 DSH host 不支持 `ctx.slots`(极旧版本或非标准 host),
|
|
68
|
+
插件会退回到「DOM 检测 + 浏览器通知」基础模式,
|
|
69
|
+
并显示一条底部提示引导用户去设置面板。
|
|
70
|
+
|
|
71
|
+
## 快速开始
|
|
72
|
+
|
|
73
|
+
### 安装 / 升级
|
|
61
74
|
|
|
62
75
|
```bash
|
|
63
|
-
dsh web
|
|
76
|
+
dsh plugin --profile web update dsh-completion-reminder
|
|
77
|
+
dsh web # 重启
|
|
64
78
|
```
|
|
65
79
|
|
|
66
|
-
|
|
80
|
+
### 配置
|
|
67
81
|
|
|
68
|
-
1.
|
|
69
|
-
2.
|
|
70
|
-
3.
|
|
71
|
-
4.
|
|
82
|
+
1. 打开 DSH → 点击左上角「⚙ 设置」→ 进入「插件」section
|
|
83
|
+
2. 在 tab 栏里点击「🔔 完成提醒」
|
|
84
|
+
3. 选择通知渠道(如 `Telegram`)
|
|
85
|
+
4. 填入对应的 token / id(凭证区只显示当前渠道需要的字段)
|
|
86
|
+
5. 点击「发送测试通知」验证渠道通不通
|
|
87
|
+
6. 关闭弹窗 → 自动保存到 localStorage
|
|
72
88
|
|
|
73
|
-
|
|
89
|
+
### 程序化 API
|
|
74
90
|
|
|
75
91
|
```javascript
|
|
76
92
|
DSHCompletionReminder.configure({
|
|
77
93
|
provider: 'telegram',
|
|
78
|
-
providers: {
|
|
79
|
-
telegramBotToken: '123456:ABC...',
|
|
80
|
-
telegramChatId: '987654321',
|
|
81
|
-
},
|
|
94
|
+
providers: { telegramBotToken: '...', telegramChatId: '...' },
|
|
82
95
|
suppressWhenFocused: false,
|
|
83
96
|
cooldownMs: 3000,
|
|
84
97
|
onNotify: (payload, provider) => console.log('delivered via', provider, payload),
|
|
85
98
|
onError: (err, provider) => console.warn('failed via', provider, err),
|
|
86
99
|
});
|
|
87
|
-
|
|
88
100
|
DSHCompletionReminder.activate();
|
|
89
101
|
DSHCompletionReminder.deactivate();
|
|
90
102
|
DSHCompletionReminder.requestBrowserPermission();
|
|
91
103
|
```
|
|
92
104
|
|
|
93
|
-
`apply(ctx, opts)` 是 DSH Cordis Loader 调用的入口,等价于 `configure(opts); activate()`。
|
|
94
|
-
|
|
95
105
|
## 公开 API
|
|
96
106
|
|
|
97
107
|
| 方法 / 属性 | 说明 |
|
|
98
108
|
|------|------|
|
|
99
109
|
| `DSHCompletionReminder.configure(opts)` | 合并配置(与 localStorage 持久值叠加) |
|
|
100
|
-
| `DSHCompletionReminder.activate()` | 启动 DOM 观察 +
|
|
101
|
-
| `DSHCompletionReminder.deactivate()` |
|
|
110
|
+
| `DSHCompletionReminder.activate()` | 启动 DOM 观察 + 注册设置入口 |
|
|
111
|
+
| `DSHCompletionReminder.deactivate()` | 停止一切,清理 UI |
|
|
102
112
|
| `DSHCompletionReminder.requestBrowserPermission()` | 手动触发浏览器通知权限请求 |
|
|
103
113
|
| `DSHCompletionReminder.apply(ctx, opts)` | DSH Cordis Loader 入口 |
|
|
114
|
+
| `DSHCompletionReminder.renderPanelInto(hostEl)` | 把配置面板渲染到任意 DOM 容器(主要用于测试) |
|
|
104
115
|
| `DSHCompletionReminder.DEFAULTS` | 默认配置(只读) |
|
|
105
116
|
|
|
106
117
|
## 项目结构
|
|
@@ -108,23 +119,22 @@ DSHCompletionReminder.requestBrowserPermission();
|
|
|
108
119
|
```
|
|
109
120
|
dsh-completion-reminder/
|
|
110
121
|
├── package.json # npm 包配置,含 dsh.bundle.patch 与 dsh.client 声明
|
|
111
|
-
├── cordis.patch.yml # 包自带的 loader 注册 patch
|
|
122
|
+
├── cordis.patch.yml # 包自带的 loader 注册 patch
|
|
112
123
|
├── tsconfig.json # TypeScript 配置
|
|
113
124
|
├── src/
|
|
114
125
|
│ ├── index.ts # 服务端入口(桩)
|
|
115
|
-
│ ├── client.ts #
|
|
126
|
+
│ ├── client.ts # 客户端插件(DOM 检测 + 9 渠道 + 设置面板)
|
|
127
|
+
│ ├── react.d.ts # 极简 React 类型(运行时通过 DSH module 系统 require('react'))
|
|
116
128
|
│ └── types.ts # 类型定义 & 默认值
|
|
117
129
|
├── lib/
|
|
118
|
-
│ ├── index.js #
|
|
130
|
+
│ ├── index.js # 服务端入口
|
|
119
131
|
│ └── client.js # DSH __ModuleLoader__ 格式的客户端插件
|
|
120
132
|
├── dist/
|
|
121
133
|
│ └── dsh-completion-reminder.js # 独立脚本(可直接 <script> 加载)
|
|
122
134
|
├── scripts/
|
|
123
|
-
│ ├── build-plugin.js # 构建脚本(tsc
|
|
135
|
+
│ ├── build-plugin.js # 构建脚本(tsc + import 转换为 require + ModuleLoader 包装)
|
|
124
136
|
│ └── clean.js # 清理 lib/ 和 dist/
|
|
125
|
-
|
|
126
|
-
└── .github/workflows/
|
|
127
|
-
└── publish.yml # tag 推送 → 构建 → npm 发布 → GitHub Release
|
|
137
|
+
└── probes/ # 离线 smoke test(jsdom)
|
|
128
138
|
```
|
|
129
139
|
|
|
130
140
|
## 发布流程
|
|
@@ -134,16 +144,16 @@ npm version patch # 或 minor / major
|
|
|
134
144
|
git push origin main --tags
|
|
135
145
|
```
|
|
136
146
|
|
|
137
|
-
|
|
138
|
-
`NPM_TOKEN` 与 `GITHUB_TOKEN` 在仓库 Settings → Secrets 中配置。
|
|
147
|
+
CI 自动完成构建、npm 发布、GitHub Release。
|
|
139
148
|
|
|
140
149
|
## 版本历史
|
|
141
150
|
|
|
142
|
-
- **v1.
|
|
143
|
-
-
|
|
144
|
-
-
|
|
145
|
-
-
|
|
146
|
-
|
|
151
|
+
- **v1.3.0** — 设置面板进入「DSH 设置 → 插件」section 的 tab 栏(与「可配置」同级):
|
|
152
|
+
- 改为 `ctx.slots.inject('settings.plugins.tab', ...)`,id=reminder, order=100, label='🔔 完成提醒'
|
|
153
|
+
- `settings.section` 保留为兜底(旧 host 仍能找到入口)
|
|
154
|
+
- jsdom smoke test 验证 tab 注入路径
|
|
155
|
+
- **v1.2.0** — 设置面板进入 DSH 设置弹窗 + 凭证按渠道筛选 + 暗色主题修复
|
|
156
|
+
- **v1.1.0** — 真实 DSH DOM 锚点 + 浮动按钮 + 11 凭证字段全显示
|
|
147
157
|
- **v1.0.0** — 初始版本(class 名匹配,实际 DSH 上不可用)
|
|
148
158
|
|
|
149
159
|
## 许可
|
package/install.md
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
- DeepSeek Harness (DSH) 已安装
|
|
6
6
|
- 浏览器允许 `http://127.0.0.1:3080` 发送通知(首次使用时会弹权限请求)
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## 安装 / 升级
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
|
-
dsh plugin --profile web
|
|
11
|
+
dsh plugin --profile web update dsh-completion-reminder
|
|
12
12
|
```
|
|
13
13
|
|
|
14
14
|
> 如果报 `ERR_PNPM_ADDING_TO_ROOT`,说明 profile 目录是 pnpm workspace root,补一个 `-w`:
|
|
@@ -17,26 +17,21 @@ dsh plugin --profile web add dsh-completion-reminder
|
|
|
17
17
|
> dsh plugin --profile web add -w dsh-completion-reminder
|
|
18
18
|
> ```
|
|
19
19
|
|
|
20
|
-
插件包内自带 `cordis.patch.yml` 并声明 `dsh.bundle.patch`,
|
|
21
|
-
`dsh plugin add` 时 DSH 会**自动**把插件加入 profile 的 bundles 层——无需手动编辑任何配置文件。
|
|
22
|
-
|
|
23
20
|
然后重启:
|
|
24
21
|
|
|
25
22
|
```bash
|
|
26
23
|
dsh web
|
|
27
24
|
```
|
|
28
25
|
|
|
29
|
-
启动后,DSH 右下角会出现一个 **🔔** 浮动按钮。点击它打开设置面板。
|
|
30
|
-
|
|
31
26
|
## 配置通知渠道
|
|
32
27
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
1. 打开 DSH → 点击左上角「⚙ 设置」→ 进入「**插件**」section
|
|
29
|
+
2. 在 tab 栏里点击「**🔔 完成提醒**」(与「可配置」同级)
|
|
30
|
+
3. 选择通知渠道(默认 `🌐 浏览器通知`)
|
|
31
|
+
4. 填入对应凭证(**凭证区只显示当前渠道需要的字段**)
|
|
32
|
+
5. 调整「行为」选项(成功 / 主动停止 / 出错 是否通知、是否在标签页可见时静默、冷却时长)
|
|
33
|
+
6. 点击「发送测试通知」验证渠道
|
|
34
|
+
7. 关闭弹窗 → 自动保存到 localStorage
|
|
40
35
|
|
|
41
36
|
如果使用浏览器原生通知,第一次会弹权限询问;如果拒绝,插件会自动改用页面内浮动 toast,**不会**完全失效。
|
|
42
37
|
|
|
@@ -46,29 +41,31 @@ dsh web
|
|
|
46
41
|
|
|
47
42
|
1. 在 Telegram 中 `@BotFather` 创建 bot,拿到 `telegramBotToken`
|
|
48
43
|
2. 给自己发一条消息,访问 `https://api.telegram.org/bot<TOKEN>/getUpdates` 拿到 `chat.id`
|
|
49
|
-
3.
|
|
44
|
+
3. 设置面板选 `Telegram`,凭证区出现 2 个字段,填入
|
|
50
45
|
|
|
51
46
|
### Bark (iPhone)
|
|
52
47
|
|
|
53
|
-
1. App Store 装 Bark
|
|
48
|
+
1. App Store 装 Bark
|
|
54
49
|
2. 打开 Bark,记下你的设备 Key
|
|
55
|
-
3. 面板里选 `Bark
|
|
50
|
+
3. 面板里选 `Bark`,凭证区出现 2 个字段(Key + 可选 Server),填入 Key
|
|
56
51
|
|
|
57
52
|
### Server酱 (微信)
|
|
58
53
|
|
|
59
54
|
1. 微信扫码登录 [sct.ftqq.com](https://sct.ftqq.com)
|
|
60
55
|
2. 拿到 SendKey(以 `SCT` 开头)
|
|
61
|
-
3. 面板里选 `Server
|
|
56
|
+
3. 面板里选 `Server酱`,凭证区出现 1 个字段
|
|
62
57
|
|
|
63
58
|
## 故障排除
|
|
64
59
|
|
|
65
60
|
| 问题 | 原因 | 解决方法 |
|
|
66
61
|
|------|------|----------|
|
|
67
62
|
| 安装报 `ERR_PNPM_ADDING_TO_ROOT` | profile 是 pnpm workspace root | 加 `-w` 标志重新执行 |
|
|
68
|
-
|
|
|
63
|
+
| 找不到「🔔 完成提醒」tab | 装的是 < v1.3.0 | `dsh plugin --profile web update dsh-completion-reminder && dsh web` |
|
|
64
|
+
| 「插件」section 里只有「可配置」 | DSH 主机 < v1.2 | 升级 DSH 主机;或翻 v1.2 之前的版本 |
|
|
65
|
+
| 凭证区看不到字段 | 切到对应渠道才会出现 | 在下拉里选 Telegram / Bark / 其他 |
|
|
69
66
|
| 浏览器没弹权限询问 | 之前已「阻止」该网站 | 浏览器地址栏左侧锁形图标 → 通知 → 允许 |
|
|
70
67
|
| Telegram 报 401/400 | `telegramBotToken` / `telegramChatId` 配错 | 用 `@BotFather` 重新获取 token;用 `getUpdates` 找 chat id |
|
|
71
|
-
| 测试按钮提示「Telegram provider requires…」 | 凭证未填 |
|
|
68
|
+
| 测试按钮提示「Telegram provider requires…」 | 凭证未填 | 凭证区填入对应字段 |
|
|
72
69
|
| 通知频率太高 | 多个 agent 接连完成 | 调大「冷却(ms)」,默认 5000 |
|
|
73
70
|
| 切回浏览器通知 | 想撤销 Telegram 配置 | 面板顶部下拉切回 `浏览器通知` |
|
|
74
71
|
| 完全停用 | — | `DSHCompletionReminder.deactivate()` |
|
package/lib/client.d.ts
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DSH Completion Reminder — client half (v1.
|
|
2
|
+
* DSH Completion Reminder — client half (v1.2).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* "
|
|
8
|
-
*
|
|
4
|
+
* Strategy:
|
|
5
|
+
* 1. Detect agent-completion lifecycle by watching the DSH composer
|
|
6
|
+
* primary button's `aria-label` (which flips between "Stop
|
|
7
|
+
* generating" / "停止生成" and "Send message" / "发送消息") inside
|
|
8
|
+
* `[data-composer-card]`. The `data-phase` attribute on the
|
|
9
|
+
* conversation root helps disambiguate active / settling / hero.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
11
|
+
* 2. Register a settings section in DSH's own settings dialog via
|
|
12
|
+
* `ctx.slots.inject('settings.section', ...)` so the user finds the
|
|
13
|
+
* configuration alongside General / Models / Plugins rather than as
|
|
14
|
+
* an extra floating widget.
|
|
15
|
+
*
|
|
16
|
+
* 3. Filter credential fields by the currently selected provider so the
|
|
17
|
+
* panel stays compact (Telegram shows 2 fields, Bark shows 1, etc.).
|
|
18
|
+
*
|
|
19
|
+
* 4. Persist configuration to `localStorage` and re-load on activation.
|
|
17
20
|
*
|
|
18
21
|
* The plugin is packaged as a DSH client plugin (`dsh.client` in
|
|
19
22
|
* package.json) and loaded through `window.__ModuleLoader__`.
|
|
@@ -25,8 +28,13 @@ declare function activate(): void;
|
|
|
25
28
|
declare function deactivate(): void;
|
|
26
29
|
declare function requestBrowserPermission(): Promise<NotificationPermission | 'unsupported'>;
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
31
|
+
* Plugin entry point invoked by the DSH Cordis Loader.
|
|
32
|
+
*
|
|
33
|
+
* In DSH v1.x the host invokes the plugin's exported `apply(ctx, opts)`
|
|
34
|
+
* after the module system has been bootstrapped. We use the context
|
|
35
|
+
* to register a settings section.
|
|
29
36
|
*/
|
|
30
|
-
declare function apply(ctx:
|
|
31
|
-
|
|
37
|
+
declare function apply(ctx: any, opts?: CompletionReminderOptions): void;
|
|
38
|
+
declare function renderPanelInto(host: HTMLElement): void;
|
|
39
|
+
export { configure, activate, deactivate, apply, requestBrowserPermission, DEFAULT_OPTIONS, renderPanelInto };
|
|
32
40
|
//# sourceMappingURL=client.d.ts.map
|
package/lib/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAEV,yBAAyB,EAM1B,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,eAAe,EAIhB,MAAM,YAAY,CAAC;AAsDpB,iBAAS,SAAS,CAAC,IAAI,CAAC,EAAE,yBAAyB,GAAG,IAAI,CAezD;AAED,iBAAS,QAAQ,IAAI,IAAI,CAexB;AAED,iBAAS,UAAU,IAAI,IAAI,CAe1B;AA4CD,iBAAe,wBAAwB,IAAI,OAAO,CAAC,sBAAsB,GAAG,aAAa,CAAC,CAczF;AAqjBD;;;;;;GAMG;AACH,iBAAS,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,yBAAyB,GAAG,IAAI,CA+F/D;AAoGD,iBAAS,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAIhD;AA+WD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,wBAAwB,EAAE,eAAe,EAAE,eAAe,EAAE,CAAA"}
|