@zhin.js/mcp 1.0.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.
@@ -0,0 +1,374 @@
1
+ import path from "node:path";
2
+ import fs from "node:fs/promises";
3
+ import { useApp } from "zhin.js";
4
+ const app = useApp();
5
+ /**
6
+ * 创建插件文件
7
+ */
8
+ export async function createPlugin(args) {
9
+ const { name, description, features = [], directory = "src/plugins" } = args;
10
+ const pluginCode = generatePluginCode(name, description, features);
11
+ const filename = `${name}.ts`;
12
+ const fullPath = path.join(process.cwd(), directory, filename);
13
+ try {
14
+ await fs.mkdir(path.dirname(fullPath), { recursive: true });
15
+ await fs.writeFile(fullPath, pluginCode, "utf-8");
16
+ return `✅ 插件 ${name} 已创建: ${fullPath}`;
17
+ }
18
+ catch (error) {
19
+ throw new Error(`创建插件失败: ${error.message}`);
20
+ }
21
+ }
22
+ function generatePluginCode(name, description, features) {
23
+ const imports = ["usePlugin"];
24
+ if (features.includes("command")) {
25
+ imports.push("addCommand", "MessageCommand");
26
+ }
27
+ if (features.includes("middleware")) {
28
+ imports.push("addMiddleware");
29
+ }
30
+ if (features.includes("component")) {
31
+ imports.push("addComponent", "defineComponent");
32
+ }
33
+ if (features.includes("context")) {
34
+ imports.push("useContext");
35
+ }
36
+ if (features.includes("database")) {
37
+ imports.push("defineModel", "onDatabaseReady");
38
+ }
39
+ let result = `/**
40
+ * ${description}
41
+ * @name ${name}
42
+ */
43
+ import { ${imports.join(", ")} } from "zhin.js";
44
+
45
+ const plugin = usePlugin();
46
+ plugin.logger.info("插件 ${name} 已加载");
47
+
48
+ `;
49
+ if (features.includes("command")) {
50
+ result += `// 示例命令
51
+ addCommand(
52
+ new MessageCommand("${name} <content:text>")
53
+ .description("${description}")
54
+ .action(async (message, result) => {
55
+ const content = result.params.content;
56
+ plugin.logger.info(\`收到命令: \${content}\`);
57
+ return \`你说: \${content}\`;
58
+ })
59
+ );
60
+
61
+ `;
62
+ }
63
+ if (features.includes("middleware")) {
64
+ result += `// 示例中间件
65
+ addMiddleware(async (message, next) => {
66
+ plugin.logger.info(\`消息来自: \${message.$sender.name}\`);
67
+ await next();
68
+ });
69
+
70
+ `;
71
+ }
72
+ if (features.includes("component")) {
73
+ result += `// 示例组件
74
+ const MyComponent = defineComponent({
75
+ name: "my-comp",
76
+ props: {
77
+ title: String,
78
+ content: String,
79
+ },
80
+ render(props) {
81
+ return \`【\${props.title}】\${props.content}\`;
82
+ },
83
+ });
84
+
85
+ addComponent(MyComponent);
86
+
87
+ `;
88
+ }
89
+ if (features.includes("database")) {
90
+ result += `// 示例数据模型
91
+ declare module "@zhin.js/types" {
92
+ interface Models {
93
+ ${name}_data: {
94
+ id?: number;
95
+ name: string;
96
+ created_at?: Date;
97
+ };
98
+ }
99
+ }
100
+
101
+ defineModel("${name}_data", {
102
+ name: { type: "text", nullable: false },
103
+ created_at: { type: "timestamp", default: () => new Date() },
104
+ });
105
+
106
+ onDatabaseReady(async (db) => {
107
+ const model = db.model("${name}_data");
108
+ plugin.logger.info("数据库已就绪");
109
+ });
110
+
111
+ `;
112
+ }
113
+ return result;
114
+ }
115
+ /**
116
+ * 生成命令代码
117
+ */
118
+ export function createCommandCode(args) {
119
+ const { pattern, description, hasPermission = false } = args;
120
+ let code = `import { addCommand, MessageCommand } from "zhin.js";
121
+
122
+ addCommand(
123
+ new MessageCommand("${pattern}")
124
+ .description("${description}")`;
125
+ if (hasPermission) {
126
+ code += `
127
+ .permit((message) => {
128
+ // 权限检查逻辑
129
+ return message.$sender.role === "admin";
130
+ })`;
131
+ }
132
+ code += `
133
+ .action(async (message, result) => {
134
+ // 命令处理逻辑
135
+ const args = result.params;
136
+ return "处理结果";
137
+ })
138
+ );
139
+ `;
140
+ return code;
141
+ }
142
+ /**
143
+ * 生成组件代码
144
+ */
145
+ export function createComponentCode(args) {
146
+ const { name, props, usesJsx = false } = args;
147
+ const propsObj = Object.entries(props)
148
+ .map(([key, type]) => ` ${key}: ${type},`)
149
+ .join("\n");
150
+ if (usesJsx) {
151
+ return `import { defineComponent } from "zhin.js";
152
+
153
+ const ${name} = defineComponent({
154
+ name: "${name}",
155
+ props: {
156
+ ${propsObj}
157
+ },
158
+ render(props) {
159
+ return (
160
+ <text>
161
+ {/* 在这里使用 props 渲染内容 */}
162
+ </text>
163
+ );
164
+ },
165
+ });
166
+
167
+ export default ${name};
168
+ `;
169
+ }
170
+ return `import { defineComponent } from "zhin.js";
171
+
172
+ const ${name} = defineComponent({
173
+ name: "${name}",
174
+ props: {
175
+ ${propsObj}
176
+ },
177
+ render(props) {
178
+ return \`\${props.title}: \${props.content}\`;
179
+ },
180
+ });
181
+
182
+ export default ${name};
183
+ `;
184
+ }
185
+ /**
186
+ * 查询插件信息
187
+ */
188
+ export function queryPlugin(args) {
189
+ const { pluginName } = args;
190
+ const targetPlugin = app.findPluginByName(pluginName);
191
+ if (!targetPlugin) {
192
+ throw new Error(`插件 ${pluginName} 不存在`);
193
+ }
194
+ return {
195
+ name: targetPlugin.name,
196
+ filename: targetPlugin.filename,
197
+ status: targetPlugin.mounted ? "active" : "inactive",
198
+ commands: targetPlugin.commands.map((cmd) => ({
199
+ pattern: cmd.pattern,
200
+ description: cmd.description || "无描述",
201
+ })),
202
+ components: Array.from(targetPlugin.components.keys()),
203
+ middlewares: targetPlugin.middlewares.length,
204
+ contexts: Array.from(targetPlugin.contexts.keys()),
205
+ crons: targetPlugin.crons.length,
206
+ models: Array.from(targetPlugin.definitions.keys()),
207
+ };
208
+ }
209
+ /**
210
+ * 列出所有插件
211
+ */
212
+ export function listPlugins() {
213
+ return app.dependencyList.map((dep) => ({
214
+ name: dep.name,
215
+ status: dep.mounted ? "active" : "inactive",
216
+ commandCount: dep.commands.length,
217
+ componentCount: dep.components.size,
218
+ }));
219
+ }
220
+ /**
221
+ * 生成适配器代码
222
+ */
223
+ export function createAdapterCode(args) {
224
+ const { name, description, hasWebhook = false } = args;
225
+ const className = name
226
+ .split("-")
227
+ .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
228
+ .join("");
229
+ let code = `/**
230
+ * ${description}
231
+ */
232
+ import {
233
+ Bot,
234
+ Adapter,
235
+ registerAdapter,
236
+ Message,
237
+ SendOptions,
238
+ segment,
239
+ usePlugin,
240
+ } from "zhin.js";
241
+
242
+ declare module "@zhin.js/types" {
243
+ interface RegisteredAdapters {
244
+ "${name}": Adapter<${className}Bot>;
245
+ }
246
+ }
247
+
248
+ export interface ${className}Config extends Bot.Config {
249
+ context: "${name}";
250
+ name: string;
251
+ apiKey?: string;
252
+ }
253
+
254
+ export class ${className}Bot implements Bot<any, ${className}Config> {
255
+ $config: ${className}Config;
256
+ $connected: boolean = false;
257
+
258
+ constructor(config: ${className}Config) {
259
+ this.$config = config;
260
+ }
261
+
262
+ async $connect(): Promise<void> {
263
+ this.$connected = true;
264
+ }
265
+
266
+ async $disconnect(): Promise<void> {
267
+ this.$connected = false;
268
+ }
269
+
270
+ $formatMessage(raw: any): Message<any> {
271
+ return Message.from({
272
+ id: raw.id,
273
+ type: "private",
274
+ content: raw.text,
275
+ $sender: {
276
+ id: raw.userId,
277
+ name: raw.userName,
278
+ },
279
+ $reply: async (content) => {
280
+ return await this.$sendMessage({
281
+ context: this.$config.context,
282
+ bot: this.$config.name,
283
+ id: raw.userId,
284
+ type: "private",
285
+ content,
286
+ });
287
+ },
288
+ });
289
+ }
290
+
291
+ async $sendMessage(options: SendOptions): Promise<string> {
292
+ return "message-id";
293
+ }
294
+
295
+ async $recallMessage(id: string): Promise<void> {
296
+ // 实现消息撤回逻辑
297
+ }
298
+ }
299
+
300
+ `;
301
+ if (hasWebhook) {
302
+ code += `import { useContext } from "zhin.js";
303
+
304
+ useContext("router", (router) => {
305
+ registerAdapter(
306
+ new Adapter("${name}", (config: ${className}Config) => {
307
+ const bot = new ${className}Bot(config);
308
+
309
+ router.post("/webhook/${name}", async (ctx) => {
310
+ const raw = ctx.request.body;
311
+ const message = bot.$formatMessage(raw);
312
+ bot.emit?.("message", message);
313
+ ctx.body = { success: true };
314
+ });
315
+
316
+ return bot;
317
+ })
318
+ );
319
+ });
320
+ `;
321
+ }
322
+ else {
323
+ code += `registerAdapter(
324
+ new Adapter("${name}", (config: ${className}Config) => new ${className}Bot(config))
325
+ );
326
+ `;
327
+ }
328
+ return code;
329
+ }
330
+ /**
331
+ * 生成数据库模型代码
332
+ */
333
+ export function createModelCode(args) {
334
+ const { name, fields } = args;
335
+ const fieldTypes = [];
336
+ const fieldDefs = [];
337
+ for (const [key, value] of Object.entries(fields)) {
338
+ const typeDef = typeof value === "string" ? value : value.type;
339
+ fieldTypes.push(` ${key}${value.nullable !== false ? "?" : ""}: ${getTypeScriptType(typeDef)};`);
340
+ fieldDefs.push(` ${key}: ${JSON.stringify(value)},`);
341
+ }
342
+ return `import { defineModel, onDatabaseReady } from "zhin.js";
343
+
344
+ declare module "@zhin.js/types" {
345
+ interface Models {
346
+ ${name}: {
347
+ ${fieldTypes.join("\n")}
348
+ };
349
+ }
350
+ }
351
+
352
+ defineModel("${name}", {
353
+ ${fieldDefs.join("\n")}
354
+ });
355
+
356
+ onDatabaseReady(async (db) => {
357
+ const model = db.model("${name}");
358
+ // 在这里使用模型
359
+ });
360
+ `;
361
+ }
362
+ function getTypeScriptType(dbType) {
363
+ const typeMap = {
364
+ text: "string",
365
+ integer: "number",
366
+ real: "number",
367
+ boolean: "boolean",
368
+ json: "any",
369
+ timestamp: "Date",
370
+ date: "Date",
371
+ };
372
+ return typeMap[dbType] || "any";
373
+ }
374
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ declare module "@zhin.js/types" {
3
+ interface GlobalContext {
4
+ mcpServer: McpServer;
5
+ }
6
+ }
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,QAAQ,gBAAgB,CAAC;IAC9B,UAAU,aAAa;QACrB,SAAS,EAAE,SAAS,CAAC;KACtB;CACF"}
package/lib/index.js ADDED
@@ -0,0 +1,88 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
+ import { register, usePlugin, defineSchema, Schema, useContext } from "zhin.js";
4
+ import { registerTools } from "./tools.js";
5
+ import { registerResources } from "./resources.js";
6
+ import { registerPrompts } from "./prompts.js";
7
+ const plugin = usePlugin();
8
+ // 配置 Schema
9
+ const schema = defineSchema(Schema.object({
10
+ enabled: Schema.boolean("enabled")
11
+ .default(true)
12
+ .description("是否启用 MCP Server"),
13
+ path: Schema.string("path")
14
+ .default("/mcp")
15
+ .description("HTTP 端点路径"),
16
+ }));
17
+ const config = schema(plugin.config, "mcp");
18
+ // ============================================================================
19
+ // 创建 MCP Server
20
+ // ============================================================================
21
+ function createMCPServer() {
22
+ const server = new McpServer({
23
+ name: "zhin-mcp-server",
24
+ version: "1.0.0",
25
+ }, {
26
+ capabilities: {
27
+ tools: {},
28
+ resources: {},
29
+ prompts: {},
30
+ },
31
+ });
32
+ // 注册所有工具、资源和提示词
33
+ registerTools(server);
34
+ registerResources(server);
35
+ registerPrompts(server);
36
+ return server;
37
+ }
38
+ // ============================================================================
39
+ // 注册 Context 并启动服务
40
+ // ============================================================================
41
+ let mcpServer;
42
+ let cleanup;
43
+ register({
44
+ name: "mcpServer",
45
+ description: "MCP Server for Zhin development",
46
+ async mounted(p) {
47
+ if (!config.enabled) {
48
+ p.logger.info("MCP Server is disabled");
49
+ return null;
50
+ }
51
+ mcpServer = createMCPServer();
52
+ // HTTP Stream 传输
53
+ useContext("router", (router) => {
54
+ const mcpPath = config.path || "/mcp";
55
+ // 创建 StreamableHTTPServerTransport (无状态模式)
56
+ const httpTransport = new StreamableHTTPServerTransport({
57
+ sessionIdGenerator: undefined, // 无状态模式
58
+ });
59
+ // 连接 transport
60
+ mcpServer.connect(httpTransport).then(() => {
61
+ p.logger.info(`✅ MCP Server started at ${mcpPath}`);
62
+ }).catch((err) => {
63
+ p.logger.error("Failed to connect HTTP transport:", err);
64
+ });
65
+ // 处理 GET 和 POST 请求
66
+ router.get(mcpPath, async (ctx) => {
67
+ await httpTransport.handleRequest(ctx.req, ctx.res);
68
+ });
69
+ router.post(mcpPath, async (ctx) => {
70
+ await httpTransport.handleRequest(ctx.req, ctx.res, ctx.request.body);
71
+ });
72
+ cleanup = () => {
73
+ httpTransport.close();
74
+ p.logger.info("MCP Server HTTP transport closed");
75
+ };
76
+ });
77
+ return mcpServer;
78
+ },
79
+ async dispose() {
80
+ if (mcpServer) {
81
+ await mcpServer.close();
82
+ }
83
+ if (cleanup) {
84
+ cleanup();
85
+ }
86
+ },
87
+ });
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * 注册所有 MCP 提示词
4
+ */
5
+ export declare function registerPrompts(server: McpServer): void;
6
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,QAiEhD"}
package/lib/prompts.js ADDED
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * 注册所有 MCP 提示词
4
+ */
5
+ export function registerPrompts(server) {
6
+ server.registerPrompt("create-plugin-workflow", {
7
+ description: "创建 Zhin 插件的完整工作流程指导",
8
+ argsSchema: {
9
+ feature_type: z.string().describe("插件功能类型 (command/middleware/component/adapter)"),
10
+ },
11
+ }, async (args) => ({
12
+ description: `创建 ${args.feature_type} 类型的 Zhin 插件`,
13
+ messages: [
14
+ {
15
+ role: "user",
16
+ content: {
17
+ type: "text",
18
+ text: `我想创建一个 ${args.feature_type} 类型的 Zhin 插件,请指导我完整的开发流程。`,
19
+ },
20
+ },
21
+ ],
22
+ }));
23
+ server.registerPrompt("debug-plugin", {
24
+ description: "调试 Zhin 插件的步骤和技巧",
25
+ argsSchema: {
26
+ error_message: z.string().optional().describe("错误消息"),
27
+ },
28
+ }, async (args) => ({
29
+ description: "调试 Zhin 插件",
30
+ messages: [
31
+ {
32
+ role: "user",
33
+ content: {
34
+ type: "text",
35
+ text: args.error_message
36
+ ? `我的插件遇到错误: ${args.error_message}`
37
+ : "我想调试我的 Zhin 插件",
38
+ },
39
+ },
40
+ ],
41
+ }));
42
+ server.registerPrompt("best-practices", {
43
+ description: "Zhin 开发的最佳实践建议",
44
+ }, async () => ({
45
+ description: "Zhin 开发最佳实践",
46
+ messages: [
47
+ {
48
+ role: "user",
49
+ content: {
50
+ type: "text",
51
+ text: "请告诉我 Zhin 开发的最佳实践",
52
+ },
53
+ },
54
+ ],
55
+ }));
56
+ }
57
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,cAAc,CACnB,wBAAwB,EACxB;QACE,WAAW,EAAE,qBAAqB;QAClC,UAAU,EAAE;YACV,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;SACnF;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACf,WAAW,EAAE,MAAM,IAAI,CAAC,YAAY,cAAc;QAClD,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,UAAU,IAAI,CAAC,YAAY,2BAA2B;iBAC7D;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,cAAc,EACd;QACE,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE;YACV,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;SACtD;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QACf,WAAW,EAAE,YAAY;QACzB,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,aAAa;wBACtB,CAAC,CAAC,aAAa,IAAI,CAAC,aAAa,EAAE;wBACnC,CAAC,CAAC,gBAAgB;iBACrB;aACF;SACF;KACF,CAAC,CACH,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,gBAAgB,EAChB;QACE,WAAW,EAAE,gBAAgB;KAC9B,EACD,KAAK,IAAI,EAAE,CAAC,CAAC;QACX,WAAW,EAAE,aAAa;QAC1B,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,mBAAmB;iBAC1B;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,50 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ /**
3
+ * 资源列表定义
4
+ */
5
+ export declare const resourceList: readonly [{
6
+ readonly uri: "zhin://docs/architecture";
7
+ readonly name: "Zhin 架构文档";
8
+ readonly description: "Zhin 框架的四层抽象设计和核心架构";
9
+ }, {
10
+ readonly uri: "zhin://docs/plugin-development";
11
+ readonly name: "插件开发指南";
12
+ readonly description: "如何开发 Zhin 插件的完整指南";
13
+ }, {
14
+ readonly uri: "zhin://docs/best-practices";
15
+ readonly name: "最佳实践";
16
+ readonly description: "Zhin 开发的最佳实践和常见模式";
17
+ }, {
18
+ readonly uri: "zhin://docs/command-system";
19
+ readonly name: "命令系统";
20
+ readonly description: "Zhin 命令系统的使用方法";
21
+ }, {
22
+ readonly uri: "zhin://docs/component-system";
23
+ readonly name: "组件系统";
24
+ readonly description: "Zhin 消息组件系统的使用方法";
25
+ }, {
26
+ readonly uri: "zhin://docs/context-system";
27
+ readonly name: "Context 系统";
28
+ readonly description: "函数式依赖注入和 Context 管理";
29
+ }, {
30
+ readonly uri: "zhin://examples/basic-plugin";
31
+ readonly name: "基础插件示例";
32
+ readonly description: "一个完整的基础插件示例";
33
+ }, {
34
+ readonly uri: "zhin://examples/command-plugin";
35
+ readonly name: "命令插件示例";
36
+ readonly description: "包含多个命令的插件示例";
37
+ }, {
38
+ readonly uri: "zhin://examples/adapter";
39
+ readonly name: "适配器示例";
40
+ readonly description: "如何实现一个平台适配器";
41
+ }];
42
+ /**
43
+ * 资源内容映射
44
+ */
45
+ export declare const resourceContents: Record<string, string>;
46
+ /**
47
+ * 注册所有 MCP 资源
48
+ */
49
+ export declare function registerResources(server: McpServer): void;
50
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE;;GAEG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8Cf,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAoKnD,CAAC;AAEF;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,QA2BlD"}