workshub-mcp 1.0.0 → 1.0.1
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 +141 -13
- package/dist/config/tools-definition.d.ts +65 -0
- package/dist/config/tools-definition.d.ts.map +1 -1
- package/dist/config/tools-definition.js +482 -49
- package/dist/config/tools-definition.js.map +1 -1
- package/dist/handlers/tool-router.d.ts.map +1 -1
- package/dist/handlers/tool-router.js +3 -0
- package/dist/handlers/tool-router.js.map +1 -1
- package/dist/index.js +34 -10
- package/dist/index.js.map +1 -1
- package/dist/tools/worker.d.ts +15 -0
- package/dist/tools/worker.d.ts.map +1 -1
- package/dist/tools/worker.js +208 -0
- package/dist/tools/worker.js.map +1 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/environment.d.ts +30 -0
- package/dist/utils/environment.d.ts.map +1 -0
- package/dist/utils/environment.js +93 -0
- package/dist/utils/environment.js.map +1 -0
- package/dist/utils/image-handler.d.ts +47 -0
- package/dist/utils/image-handler.d.ts.map +1 -0
- package/dist/utils/image-handler.js +130 -0
- package/dist/utils/image-handler.js.map +1 -0
- package/dist/utils/qr-detector.d.ts +38 -0
- package/dist/utils/qr-detector.d.ts.map +1 -0
- package/dist/utils/qr-detector.js +140 -0
- package/dist/utils/qr-detector.js.map +1 -0
- package/dist/utils/terminal-qr-renderer.d.ts +48 -0
- package/dist/utils/terminal-qr-renderer.d.ts.map +1 -0
- package/dist/utils/terminal-qr-renderer.js +116 -0
- package/dist/utils/terminal-qr-renderer.js.map +1 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ WorksHub MCP 是一个基于 [Model Context Protocol](https://modelcontextprotoc
|
|
|
15
15
|
- ✅ 接受申请并管理任务
|
|
16
16
|
- 🛠️ 查询技能列表
|
|
17
17
|
|
|
18
|
-
**已实现
|
|
18
|
+
**已实现 14 个工具**,覆盖 4 大功能模块。
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -142,17 +142,17 @@ $env:WORKSHUB_API_KEY = "your_api_key_here"
|
|
|
142
142
|
|
|
143
143
|
---
|
|
144
144
|
|
|
145
|
-
## 完整工具列表(
|
|
145
|
+
## 完整工具列表(14个)
|
|
146
146
|
|
|
147
147
|
### 📊 统计
|
|
148
148
|
|
|
149
149
|
| 模块 | 工具数量 |
|
|
150
150
|
|------|---------|
|
|
151
151
|
| 技能管理 | 1 |
|
|
152
|
-
| 工作者管理 |
|
|
152
|
+
| 工作者管理 | 3 |
|
|
153
153
|
| 悬赏任务管理 | 6 |
|
|
154
154
|
| 对话管理 | 4 |
|
|
155
|
-
| **总计** | **
|
|
155
|
+
| **总计** | **14** |
|
|
156
156
|
|
|
157
157
|
---
|
|
158
158
|
|
|
@@ -184,7 +184,7 @@ get_skills({ keyword: "React" })
|
|
|
184
184
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
|
-
###
|
|
187
|
+
### 2. 工作者管理(3个工具)
|
|
188
188
|
|
|
189
189
|
#### `get_workers`
|
|
190
190
|
|
|
@@ -207,6 +207,17 @@ get_skills({ keyword: "React" })
|
|
|
207
207
|
|--------|------|------|------|
|
|
208
208
|
| `workerId` | string | 是 | 工作者ID |
|
|
209
209
|
|
|
210
|
+
#### `get_worker_qrcode`
|
|
211
|
+
|
|
212
|
+
**功能**: 获取并显示指定工作者的收款二维码图片
|
|
213
|
+
|
|
214
|
+
**参数**:
|
|
215
|
+
| 参数名 | 类型 | 必填 | 说明 |
|
|
216
|
+
|--------|------|------|------|
|
|
217
|
+
| `workerId` | string | 是 | 工作者ID(如 bc4YVt) |
|
|
218
|
+
|
|
219
|
+
**说明**: 支持微信支付和支付宝支付,优先返回微信支付二维码
|
|
220
|
+
|
|
210
221
|
---
|
|
211
222
|
|
|
212
223
|
### 3. 悬赏任务管理(6个工具)
|
|
@@ -364,7 +375,7 @@ src/
|
|
|
364
375
|
├── index.ts # MCP 服务入口
|
|
365
376
|
├── tools/ # 业务工具层
|
|
366
377
|
│ ├── skill.ts # 技能管理(1个工具)
|
|
367
|
-
│ ├── worker.ts # 工作者管理(
|
|
378
|
+
│ ├── worker.ts # 工作者管理(3个工具)
|
|
368
379
|
│ ├── bounty.ts # 悬赏任务管理(6个工具)
|
|
369
380
|
│ └── conversation.ts # 对话管理(4个工具)
|
|
370
381
|
├── utils/ # 基础设施层
|
|
@@ -424,6 +435,113 @@ Authorization: Bearer your_api_key_here
|
|
|
424
435
|
|
|
425
436
|
---
|
|
426
437
|
|
|
438
|
+
## 典型工作流程
|
|
439
|
+
|
|
440
|
+
### 🔄 工作流程图
|
|
441
|
+
|
|
442
|
+
以下是 WorksHub MCP 工具的典型使用流程和依赖关系:
|
|
443
|
+
|
|
444
|
+
#### 流程1:发布任务并雇佣工作者(完整流程)
|
|
445
|
+
|
|
446
|
+
```
|
|
447
|
+
1️⃣ 准备阶段
|
|
448
|
+
get_skills # 查看可用技能(可选,建议)
|
|
449
|
+
↓
|
|
450
|
+
2️⃣ 创建任务
|
|
451
|
+
create_bounty # 创建悬赏任务(必需)
|
|
452
|
+
↓
|
|
453
|
+
3️⃣ 审核申请
|
|
454
|
+
get_bounty_applications # 获取申请列表(必需)
|
|
455
|
+
↓
|
|
456
|
+
get_worker_detail # 查看申请者详情(建议)
|
|
457
|
+
↓
|
|
458
|
+
4️⃣ 确定工作者
|
|
459
|
+
accept_bounty_application # 接受申请(必需,不可逆)
|
|
460
|
+
↓
|
|
461
|
+
5️⃣ 开始协作
|
|
462
|
+
start_conversation # 开始对话(建议)
|
|
463
|
+
↓
|
|
464
|
+
send_message # 沟通任务细节(建议)
|
|
465
|
+
↓
|
|
466
|
+
get_worker_qrcode # 获取收款码支付(可选)
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
#### 流程2:搜索并联系工作者(主动招募)
|
|
470
|
+
|
|
471
|
+
```
|
|
472
|
+
1️⃣ 搜索工作者
|
|
473
|
+
get_workers # 按技能/地理位置筛选(必需)
|
|
474
|
+
↓
|
|
475
|
+
2️⃣ 了解详情
|
|
476
|
+
get_worker_detail # 查看工作者详细信息(建议)
|
|
477
|
+
↓
|
|
478
|
+
3️⃣ 建立联系
|
|
479
|
+
start_conversation # 发起对话(必需)
|
|
480
|
+
↓
|
|
481
|
+
send_message # 咨询可用性和报价(必需)
|
|
482
|
+
↓
|
|
483
|
+
4️⃣ 确定合作
|
|
484
|
+
create_bounty # 为该工作者创建专属任务(可选)
|
|
485
|
+
或
|
|
486
|
+
get_worker_qrcode # 直接支付报酬(可选)
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
#### 流程3:管理对话和任务
|
|
490
|
+
|
|
491
|
+
```
|
|
492
|
+
📋 查看任务
|
|
493
|
+
get_bounties # 查看所有任务
|
|
494
|
+
↓
|
|
495
|
+
get_bounty_detail # 查看任务详情
|
|
496
|
+
↓
|
|
497
|
+
cancel_bounty # 取消任务(如需要)
|
|
498
|
+
|
|
499
|
+
💬 管理对话
|
|
500
|
+
get_conversations # 查看所有对话
|
|
501
|
+
↓
|
|
502
|
+
get_conversation_messages # 查看聊天记录
|
|
503
|
+
↓
|
|
504
|
+
send_message # 发送新消息
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 📊 工具依赖关系表
|
|
508
|
+
|
|
509
|
+
| 工具 | 前置条件 | 后续操作 | 是否可逆 |
|
|
510
|
+
|------|----------|----------|----------|
|
|
511
|
+
| **get_skills** | 无 | create_bounty | ✅ 无影响 |
|
|
512
|
+
| **get_workers** | 无 | get_worker_detail, start_conversation | ✅ 无影响 |
|
|
513
|
+
| **get_worker_detail** | workerId | start_conversation, get_worker_qrcode | ✅ 无影响 |
|
|
514
|
+
| **get_worker_qrcode** | workerId | (支付操作) | ✅ 无影响 |
|
|
515
|
+
| **create_bounty** | API Key(写权限) | get_bounty_applications, cancel_bounty | ⚠️ 创建后可取消 |
|
|
516
|
+
| **get_bounties** | 无 | get_bounty_detail | ✅ 无影响 |
|
|
517
|
+
| **get_bounty_detail** | bountyId | get_bounty_applications, cancel_bounty | ✅ 无影响 |
|
|
518
|
+
| **cancel_bounty** | bountyId, 任务状态="招募中" | 无 | ❌ 不可逆 |
|
|
519
|
+
| **get_bounty_applications** | bountyId | accept_bounty_application, get_worker_detail | ✅ 无影响 |
|
|
520
|
+
| **accept_bounty_application** | bountyId, applicationId | start_conversation, send_message | ❌ 不可逆 |
|
|
521
|
+
| **get_conversations** | 无 | get_conversation_messages, send_message | ✅ 无影响 |
|
|
522
|
+
| **start_conversation** | workerId | send_message, get_conversation_messages | ✅ 无影响 |
|
|
523
|
+
| **get_conversation_messages** | conversationId | send_message | ✅ 无影响 |
|
|
524
|
+
| **send_message** | conversationId | get_conversation_messages | ⚠️ 消息不可撤回 |
|
|
525
|
+
|
|
526
|
+
### ⚠️ 关键注意事项
|
|
527
|
+
|
|
528
|
+
1. **不可逆操作**:
|
|
529
|
+
- `accept_bounty_application` — 接受申请后无法撤回,其他申请会被自动拒绝
|
|
530
|
+
- `cancel_bounty` — 取消任务后无法恢复
|
|
531
|
+
- `send_message` — 消息发送后无法撤回或编辑
|
|
532
|
+
|
|
533
|
+
2. **前置条件**:
|
|
534
|
+
- 所有写操作(create_bounty, cancel_bounty, accept_bounty_application, start_conversation, send_message)都需要配置 `WORKSHUB_API_KEY` 且具有写权限
|
|
535
|
+
- `accept_bounty_application` 必须先调用 `get_bounty_applications` 获取申请列表
|
|
536
|
+
- `send_message` 必须先有对话(通过 `start_conversation` 创建)
|
|
537
|
+
|
|
538
|
+
3. **建议的操作顺序**:
|
|
539
|
+
- 创建任务前建议先调用 `get_skills` 查看可用技能
|
|
540
|
+
- 接受申请前建议先调用 `get_worker_detail` 了解申请者详情
|
|
541
|
+
- 接受申请后建议立即调用 `start_conversation` 与工作者沟通
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
427
545
|
## 完整使用场景示例
|
|
428
546
|
|
|
429
547
|
### 场景1:AI Agent 发布任务并雇佣工作者
|
|
@@ -527,18 +645,28 @@ MIT
|
|
|
527
645
|
|
|
528
646
|
## 更新日志
|
|
529
647
|
|
|
648
|
+
### v1.0.1 (2026-02-26)
|
|
649
|
+
|
|
650
|
+
- 🎯 添加`get_worker_qrcode` 获取工作者收款码工具
|
|
651
|
+
- ✨ 优化所有 14 个工具的提示词和参数描述
|
|
652
|
+
- ✅ 修复文档统计错误(统一为 14 个工具)
|
|
653
|
+
- 📊 添加典型工作流程和工具依赖关系说明
|
|
654
|
+
- 🎯 参数 examples 覆盖率达到 100%
|
|
655
|
+
- 📝 平均描述长度从 10 字提升到 385 字
|
|
656
|
+
- ✅ 构建验证通过,文档与代码 100% 一致
|
|
657
|
+
|
|
530
658
|
### v0.0.3 (2026-02-13)
|
|
531
659
|
|
|
532
660
|
- 🔄 与底层 API 接口对齐,移除不支持的功能
|
|
533
661
|
- ❌ 删除 `get_agent_identity` 工具(底层暂无对应接口)
|
|
534
662
|
- ❌ 删除 `update_bounty` 工具(底层暂无对应接口)
|
|
535
663
|
- ❌ 删除 `mark_conversation_read` 工具(底层暂无对应接口)
|
|
536
|
-
- ✅ 保留
|
|
664
|
+
- ✅ 保留 14 个核心工具,确保三层架构完全一致
|
|
537
665
|
|
|
538
|
-
###
|
|
666
|
+
### v0.0.1 (2024-02-12)
|
|
539
667
|
|
|
540
|
-
- ✅ 实现全部
|
|
541
|
-
- ✅
|
|
542
|
-
- ✅
|
|
543
|
-
- ✅
|
|
544
|
-
- ✅
|
|
668
|
+
- ✅ 实现全部 14 个工具
|
|
669
|
+
- ✅ 支持技能管理(1个工具)
|
|
670
|
+
- ✅ 支持工作者管理(3个工具)
|
|
671
|
+
- ✅ 支持悬赏任务管理(6个工具)
|
|
672
|
+
- ✅ 支持对话管理(4个工具)
|
|
@@ -45,18 +45,28 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
45
45
|
skills: {
|
|
46
46
|
type: string;
|
|
47
47
|
description: string;
|
|
48
|
+
examples: string[];
|
|
49
|
+
minLength?: undefined;
|
|
48
50
|
};
|
|
49
51
|
location: {
|
|
50
52
|
type: string;
|
|
51
53
|
description: string;
|
|
54
|
+
examples: string[];
|
|
52
55
|
};
|
|
53
56
|
page: {
|
|
54
57
|
type: string;
|
|
55
58
|
description: string;
|
|
59
|
+
minimum: number;
|
|
60
|
+
default: number;
|
|
61
|
+
examples: number[];
|
|
56
62
|
};
|
|
57
63
|
pageSize: {
|
|
58
64
|
type: string;
|
|
59
65
|
description: string;
|
|
66
|
+
minimum: number;
|
|
67
|
+
maximum: number;
|
|
68
|
+
default: number;
|
|
69
|
+
examples: number[];
|
|
60
70
|
};
|
|
61
71
|
workerId?: undefined;
|
|
62
72
|
status?: undefined;
|
|
@@ -88,6 +98,7 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
88
98
|
workerId: {
|
|
89
99
|
type: string;
|
|
90
100
|
description: string;
|
|
101
|
+
examples: string[];
|
|
91
102
|
};
|
|
92
103
|
skills?: undefined;
|
|
93
104
|
location?: undefined;
|
|
@@ -122,18 +133,29 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
122
133
|
status: {
|
|
123
134
|
type: string;
|
|
124
135
|
description: string;
|
|
136
|
+
enum: number[];
|
|
137
|
+
examples: number[];
|
|
125
138
|
};
|
|
126
139
|
skills: {
|
|
127
140
|
type: string;
|
|
128
141
|
description: string;
|
|
142
|
+
examples: string[];
|
|
143
|
+
minLength?: undefined;
|
|
129
144
|
};
|
|
130
145
|
page: {
|
|
131
146
|
type: string;
|
|
132
147
|
description: string;
|
|
148
|
+
minimum: number;
|
|
149
|
+
default: number;
|
|
150
|
+
examples: number[];
|
|
133
151
|
};
|
|
134
152
|
pageSize: {
|
|
135
153
|
type: string;
|
|
136
154
|
description: string;
|
|
155
|
+
minimum: number;
|
|
156
|
+
maximum: number;
|
|
157
|
+
default: number;
|
|
158
|
+
examples: number[];
|
|
137
159
|
};
|
|
138
160
|
location?: undefined;
|
|
139
161
|
workerId?: undefined;
|
|
@@ -165,46 +187,68 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
165
187
|
title: {
|
|
166
188
|
type: string;
|
|
167
189
|
description: string;
|
|
190
|
+
minLength: number;
|
|
191
|
+
maxLength: number;
|
|
192
|
+
examples: string[];
|
|
168
193
|
};
|
|
169
194
|
description: {
|
|
170
195
|
type: string;
|
|
171
196
|
description: string;
|
|
197
|
+
minLength: number;
|
|
198
|
+
maxLength: number;
|
|
199
|
+
examples: string[];
|
|
172
200
|
};
|
|
173
201
|
budget: {
|
|
174
202
|
type: string;
|
|
175
203
|
description: string;
|
|
204
|
+
minimum: number;
|
|
205
|
+
examples: number[];
|
|
176
206
|
};
|
|
177
207
|
priceType: {
|
|
178
208
|
type: string;
|
|
179
209
|
description: string;
|
|
210
|
+
enum: number[];
|
|
211
|
+
examples: number[];
|
|
180
212
|
};
|
|
181
213
|
skills: {
|
|
182
214
|
type: string;
|
|
183
215
|
description: string;
|
|
216
|
+
minLength: number;
|
|
217
|
+
examples: string[];
|
|
184
218
|
};
|
|
185
219
|
category: {
|
|
186
220
|
type: string;
|
|
187
221
|
description: string;
|
|
222
|
+
minLength: number;
|
|
223
|
+
examples: string[];
|
|
188
224
|
};
|
|
189
225
|
deadline: {
|
|
190
226
|
type: string;
|
|
191
227
|
description: string;
|
|
228
|
+
format: string;
|
|
229
|
+
pattern: string;
|
|
230
|
+
examples: string[];
|
|
192
231
|
};
|
|
193
232
|
province: {
|
|
194
233
|
type: string;
|
|
195
234
|
description: string;
|
|
235
|
+
examples: string[];
|
|
196
236
|
};
|
|
197
237
|
city: {
|
|
198
238
|
type: string;
|
|
199
239
|
description: string;
|
|
240
|
+
examples: string[];
|
|
200
241
|
};
|
|
201
242
|
agentType: {
|
|
202
243
|
type: string;
|
|
203
244
|
description: string;
|
|
245
|
+
examples: string[];
|
|
204
246
|
};
|
|
205
247
|
agentName: {
|
|
206
248
|
type: string;
|
|
207
249
|
description: string;
|
|
250
|
+
maxLength: number;
|
|
251
|
+
examples: string[];
|
|
208
252
|
};
|
|
209
253
|
location?: undefined;
|
|
210
254
|
page?: undefined;
|
|
@@ -229,6 +273,7 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
229
273
|
bountyId: {
|
|
230
274
|
type: string;
|
|
231
275
|
description: string;
|
|
276
|
+
examples: string[];
|
|
232
277
|
};
|
|
233
278
|
skills?: undefined;
|
|
234
279
|
location?: undefined;
|
|
@@ -263,10 +308,12 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
263
308
|
bountyId: {
|
|
264
309
|
type: string;
|
|
265
310
|
description: string;
|
|
311
|
+
examples: string[];
|
|
266
312
|
};
|
|
267
313
|
applicationId: {
|
|
268
314
|
type: string;
|
|
269
315
|
description: string;
|
|
316
|
+
examples: string[];
|
|
270
317
|
};
|
|
271
318
|
skills?: undefined;
|
|
272
319
|
location?: undefined;
|
|
@@ -300,10 +347,13 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
300
347
|
workerId: {
|
|
301
348
|
type: string;
|
|
302
349
|
description: string;
|
|
350
|
+
examples: string[];
|
|
303
351
|
};
|
|
304
352
|
message: {
|
|
305
353
|
type: string;
|
|
306
354
|
description: string;
|
|
355
|
+
maxLength: number;
|
|
356
|
+
examples: string[];
|
|
307
357
|
};
|
|
308
358
|
skills?: undefined;
|
|
309
359
|
location?: undefined;
|
|
@@ -337,14 +387,22 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
337
387
|
conversationId: {
|
|
338
388
|
type: string;
|
|
339
389
|
description: string;
|
|
390
|
+
examples: string[];
|
|
340
391
|
};
|
|
341
392
|
page: {
|
|
342
393
|
type: string;
|
|
343
394
|
description: string;
|
|
395
|
+
minimum: number;
|
|
396
|
+
default: number;
|
|
397
|
+
examples: number[];
|
|
344
398
|
};
|
|
345
399
|
pageSize: {
|
|
346
400
|
type: string;
|
|
347
401
|
description: string;
|
|
402
|
+
minimum: number;
|
|
403
|
+
maximum: number;
|
|
404
|
+
default: number;
|
|
405
|
+
examples: number[];
|
|
348
406
|
};
|
|
349
407
|
skills?: undefined;
|
|
350
408
|
location?: undefined;
|
|
@@ -377,14 +435,21 @@ export declare const TOOLS_DEFINITION: ({
|
|
|
377
435
|
conversationId: {
|
|
378
436
|
type: string;
|
|
379
437
|
description: string;
|
|
438
|
+
examples: string[];
|
|
380
439
|
};
|
|
381
440
|
content: {
|
|
382
441
|
type: string;
|
|
383
442
|
description: string;
|
|
443
|
+
minLength: number;
|
|
444
|
+
maxLength: number;
|
|
445
|
+
examples: string[];
|
|
384
446
|
};
|
|
385
447
|
messageType: {
|
|
386
448
|
type: string;
|
|
387
449
|
description: string;
|
|
450
|
+
enum: number[];
|
|
451
|
+
default: number;
|
|
452
|
+
examples: number[];
|
|
388
453
|
};
|
|
389
454
|
skills?: undefined;
|
|
390
455
|
location?: undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools-definition.d.ts","sourceRoot":"","sources":["../../src/config/tools-definition.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB
|
|
1
|
+
{"version":3,"file":"tools-definition.d.ts","sourceRoot":"","sources":["../../src/config/tools-definition.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8sB5B,CAAC"}
|