@clowder-ai/connector-weixin 0.0.0-stage → 0.1.0-alpha.7

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.
Files changed (66) hide show
  1. package/README.en.md +55 -0
  2. package/README.md +27 -2
  3. package/assets/icon.svg +3 -0
  4. package/dist/WeixinAdapter.d.ts +255 -0
  5. package/dist/WeixinAdapter.d.ts.map +1 -0
  6. package/dist/WeixinAdapter.js +1130 -0
  7. package/dist/WeixinAdapter.js.map +1 -0
  8. package/dist/command-ingress.d.ts +10 -0
  9. package/dist/command-ingress.d.ts.map +1 -0
  10. package/dist/command-ingress.js +13 -0
  11. package/dist/command-ingress.js.map +1 -0
  12. package/dist/inbound-download.d.ts +13 -0
  13. package/dist/inbound-download.d.ts.map +1 -0
  14. package/dist/inbound-download.js +70 -0
  15. package/dist/inbound-download.js.map +1 -0
  16. package/dist/inbound-media-source.d.ts +25 -0
  17. package/dist/inbound-media-source.d.ts.map +1 -0
  18. package/dist/inbound-media-source.js +111 -0
  19. package/dist/inbound-media-source.js.map +1 -0
  20. package/dist/index.d.ts +6 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +3 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/materialize-media.d.ts +7 -0
  25. package/dist/materialize-media.d.ts.map +1 -0
  26. package/dist/materialize-media.js +35 -0
  27. package/dist/materialize-media.js.map +1 -0
  28. package/dist/media-notice.d.ts +6 -0
  29. package/dist/media-notice.d.ts.map +1 -0
  30. package/dist/media-notice.js +50 -0
  31. package/dist/media-notice.js.map +1 -0
  32. package/dist/plugin-entrypoint.d.ts +8 -0
  33. package/dist/plugin-entrypoint.d.ts.map +1 -0
  34. package/dist/plugin-entrypoint.js +295 -0
  35. package/dist/plugin-entrypoint.js.map +1 -0
  36. package/dist/reply-sender-map.d.ts +10 -0
  37. package/dist/reply-sender-map.d.ts.map +1 -0
  38. package/dist/reply-sender-map.js +123 -0
  39. package/dist/reply-sender-map.js.map +1 -0
  40. package/dist/rich-block-plaintext.d.ts +5 -0
  41. package/dist/rich-block-plaintext.d.ts.map +1 -0
  42. package/dist/rich-block-plaintext.js +45 -0
  43. package/dist/rich-block-plaintext.js.map +1 -0
  44. package/dist/runtime.d.ts +51 -0
  45. package/dist/runtime.d.ts.map +1 -0
  46. package/dist/runtime.js +142 -0
  47. package/dist/runtime.js.map +1 -0
  48. package/dist/settings.d.ts +19 -0
  49. package/dist/settings.d.ts.map +1 -0
  50. package/dist/settings.js +39 -0
  51. package/dist/settings.js.map +1 -0
  52. package/dist/thread-mappings.d.ts +46 -0
  53. package/dist/thread-mappings.d.ts.map +1 -0
  54. package/dist/thread-mappings.js +62 -0
  55. package/dist/thread-mappings.js.map +1 -0
  56. package/dist/types.d.ts +8 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +2 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/weixin-cdn.d.ts +43 -0
  61. package/dist/weixin-cdn.d.ts.map +1 -0
  62. package/dist/weixin-cdn.js +226 -0
  63. package/dist/weixin-cdn.js.map +1 -0
  64. package/npm-shrinkwrap.json +1013 -0
  65. package/package.json +58 -4
  66. package/plugin.yaml +107 -0
package/README.en.md ADDED
@@ -0,0 +1,55 @@
1
+ # WeChat Personal Connector
2
+
3
+ [Chinese](README.md) · English
4
+
5
+ `@clowder-ai/connector-weixin` packages iLink long polling, message normalization, QR login, media transfer,
6
+ typing, and reply delivery for a Clowder AI Host.
7
+
8
+ ## Configuration
9
+
10
+ The Host projects the Bot Token and optional media behavior explicitly from the manifest. The Bot Token is
11
+ written only by the `weixin_qr_login` operation target. It remains hidden and required for runtime
12
+ readiness; QR setup is available while the plugin is disabled. Saving a token preserves the Host enable intent. Relative Host media URLs have no package-side base URL override
13
+ anymore: outbound media with a relative URL fails closed with a clear error instead of being silently sent.
14
+
15
+ ## Security and authority
16
+
17
+ The Host owns installation, grants, credentials, connector bindings, wake policy, delivery, and durable
18
+ checkpoint state. Ordinary message text, including `@`, cannot mint a binding or wake an Agent.
19
+
20
+ ## Lifecycle and recovery
21
+
22
+ The iLink polling cursor and context tokens use the existing Host-owned state surface. They must not be stored
23
+ in package-local files or ambient Redis. Rollback drains polling before the preserved Core adapter starts.
24
+
25
+ Inbound CDN locators share that manifest-declared private state surface but never enter the Host envelope,
26
+ logs, or transcript. Public messages carry only a `pmr_*` reference plus `sourceEventId`; the declared media
27
+ source serves bounded chunks and settlement deletes the locator.
28
+
29
+ The Host-loadable builtin runtime is implemented in this package and uses only the existing Host-owned
30
+ binding, configuration/secret, state, and messaging surfaces.
31
+
32
+ ## Connection controls
33
+
34
+ Use `weixin_qr_login` (`qr-generate` / `qr-status` / `disconnect`) for QR setup and `weixin.test`
35
+ to check the connection. QR login obtains a Bot Token; the Host saves it and controls activation.
36
+
37
+ ## Commands and configuration
38
+
39
+ The builtin entrypoint intercepts `/where`, `/new`, `/threads`, `/use`, `/thread`, `/commands`, `/cats`,
40
+ `/status`, `/history`, `/unbind`, `/allow-group`, `/deny-group`, `/focus`, and `/ask` before ordinary ingress.
41
+ Commands reply through the provider and keep their audit quiet. Only an explicit body in `/thread` or
42
+ `/ask` requests Agent invocation; successful delivery is acknowledged only after the Host accepts it.
43
+ `/use` traverses the owner-visible live thread inventory beyond the first 50 rows, deduplicates IDs and
44
+ rejects a non-progressing or exhausted traversal instead of selecting from an incomplete list.
45
+
46
+ This adapter supports direct conversations only. Configure the original account/login fields and receive messages;
47
+ there is no group-permission page, permission initialization or legacy-import step. Group management commands
48
+ do not grant a direct-message sender administrator authority. Existing stored data is not deleted.
49
+
50
+ The Host owns installation, grants, credentials and lifecycle; saving configuration preserves enable intent. The language link opens a separate document and does not imply automatic language selection.
51
+
52
+ ## Configuration and connection state
53
+
54
+ Setup and credential checks work while disabled. The Host saves successful credentials and preserves enable intent; only an enabled runtime opens the messaging connection. Saved credentials are not proof of a live connection. Use the current connection test to check runtime health.
55
+ The Bot Token is obtained through QR setup, not pasted into a separate permission form. Advanced voice settings remain hidden; no runtime environment override is read. Outbound media requires Host-authorized references, not arbitrary paths or URLs.
package/README.md CHANGED
@@ -1,3 +1,28 @@
1
- # Temporary Holding Version
1
+ # 微信个人号连接器
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 简体中文 · [English](README.en.md)
4
+
5
+ 通过 iLink 将微信私聊接入 Clowder AI,支持扫码登录、消息收发、媒体传输和输入状态提示。
6
+
7
+ ## 开始使用
8
+
9
+ 1. 在插件设置打开扫码登录,使用微信扫描生成的二维码并完成确认。
10
+ 2. 确认登录结果,保存由扫码取得的凭据;需要接收消息时再启用插件。
11
+
12
+ 扫码在停用状态也可完成,保存不会自行启用插件。机器人令牌由宿主保存,无需手动复制令牌、编辑 JSON 或初始化另一份权限。本插件只支持私聊,没有群权限页。
13
+
14
+ 连接状态请使用实时连接测试检查。保存了扫码凭据不等于消息轮询正在运行。断开操作清除对应登录凭据,不删除其他已保存数据。
15
+
16
+ ## 消息与恢复
17
+
18
+ iLink 轮询游标及上下文令牌通过宿主保存;停用时停止轮询。媒体只接受宿主授权的引用,不读取任意本地路径或裸 URL。入站下载坐标保存在私有状态,对话只携带受限引用与来源标识,读取结算后清理。
19
+
20
+ 语音处理使用当前已保存的隐藏设置 `voiceItemMode`、`enableUnsafeVoiceModes`、`captureInboundVoiceMedia`;未配置模式具有独立含义。普通设置页不提供这些高级字段,也不读取运行时环境变量覆盖值。
21
+
22
+ ## 对话命令
23
+
24
+ 可使用 `/where`、`/new`、`/threads`、`/use`、`/thread`、`/commands`、`/cats`、`/status`、`/history`、`/unbind`、`/focus` 和 `/ask` 查看位置、切换对话或发起请求。`/thread`、`/ask` 只有显式携带正文时才请求猫执行,宿主接受投递后才确认成功。`/use` 会遍历可见对话,列表不完整时不猜测选择。
25
+
26
+ `/allow-group`、`/deny-group` 仅适用于支持群聊且已配置管理员的连接器,不能通过普通私聊文本取得管理权。
27
+
28
+ 宿主管理安装、授权、凭据和启停;配置保存不自动改变启用意图。英文文档是独立文件,互链不代表页面已支持自动语言切换。
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="WeChat connector">
2
+ <rect width="64" height="64" rx="14" fill="#07c160"/><circle cx="27" cy="29" r="14" fill="#fff"/><circle cx="40" cy="38" r="11" fill="#eaffea"/><circle cx="22" cy="27" r="2" fill="#07c160"/><circle cx="31" cy="27" r="2" fill="#07c160"/>
3
+ </svg>
@@ -0,0 +1,255 @@
1
+ /**
2
+ * WeChat Personal (iLink Bot) Adapter
3
+ * Inbound: Long-poll via /ilink/bot/getupdates → parse text messages
4
+ * Outbound: Send reply via /ilink/bot/sendmessage (requires context_token)
5
+ *
6
+ * Uses Tencent's iLink Bot protocol for personal WeChat accounts.
7
+ * No SDK dependency — pure HTTP (fetch) implementation.
8
+ *
9
+ * MVP: DM-only, text-only, single-account.
10
+ *
11
+ * F137 WeChat Personal Gateway
12
+ */
13
+ import type { ConnectorLogger } from './types.js';
14
+ export declare const WEIXIN_MEDIA_MAX_BYTES: number;
15
+ /**
16
+ * Voice item payload mode for WeChat voice delivery.
17
+ * - `minimal`: send only `{ media }` — experimental native voice payload.
18
+ * - `playtime`: send `{ media, playtime }` — shows correct duration but won't play.
19
+ * - `playtime-sec`: send `{ media, playtime }` with playtime in SECONDS (not ms) — hypothesis test.
20
+ * - `playtime-encode`: send `{ media, encode_type: 6, playtime }` — confirmed broken (encode_type is poison).
21
+ * - `metadata`: send all SILK fields — confirmed broken (voice "completely gone").
22
+ *
23
+ * Runtime-configurable via WEIXIN_VOICE_ITEM_MODE so co-creator can A/B test without code changes.
24
+ * Default audio delivery stays on file_item attachment because native voice_item is unreliable.
25
+ */
26
+ declare const VOICE_ITEM_MODES: readonly ["minimal", "playtime", "playtime-sec", "playtime-encode", "metadata"];
27
+ export type WeixinVoiceItemMode = (typeof VOICE_ITEM_MODES)[number];
28
+ export interface WeixinRuntimeOptions {
29
+ voiceItemMode?: WeixinVoiceItemMode;
30
+ enableUnsafeVoiceModes?: boolean;
31
+ captureInboundVoiceMedia?: boolean;
32
+ }
33
+ export interface WeixinInboundMessage {
34
+ chatId: string;
35
+ text: string;
36
+ messageId: string;
37
+ senderId: string;
38
+ contextToken: string;
39
+ createdAtMs?: number;
40
+ attachments?: WeixinAttachment[];
41
+ }
42
+ export interface WeixinSessionState {
43
+ getUpdatesBuf?: string;
44
+ contextTokens?: Record<string, string>;
45
+ }
46
+ export interface WeixinSessionStateStore {
47
+ load(): Promise<WeixinSessionState | null>;
48
+ save(state: WeixinSessionState): Promise<void>;
49
+ clear(): Promise<void>;
50
+ }
51
+ export interface WeixinAttachment {
52
+ type: 'image' | 'file' | 'audio';
53
+ /** CDN URL or media key */
54
+ mediaUrl: string;
55
+ fileName?: string;
56
+ }
57
+ /**
58
+ * iLink getupdates response — aligned with @tencent-weixin/openclaw-weixin v1.0.2
59
+ * (GetUpdatesResp in src/api/types.ts).
60
+ */
61
+ interface ILinkUpdate {
62
+ ret?: number;
63
+ errcode?: number;
64
+ errmsg?: string;
65
+ msgs?: ILinkWeixinMessage[];
66
+ get_updates_buf?: string;
67
+ longpolling_timeout_ms?: number;
68
+ }
69
+ /** MessageItem inside a WeixinMessage — matches openclaw-weixin MessageItem. */
70
+ interface ILinkMessageItem {
71
+ type?: number;
72
+ text_item?: {
73
+ text?: string;
74
+ };
75
+ image_item?: {
76
+ media?: ILinkMediaRef;
77
+ url?: string;
78
+ aeskey?: string;
79
+ };
80
+ voice_item?: {
81
+ media?: ILinkMediaRef;
82
+ text?: string;
83
+ };
84
+ file_item?: {
85
+ media?: ILinkMediaRef;
86
+ file_name?: string;
87
+ };
88
+ video_item?: {
89
+ media?: ILinkMediaRef;
90
+ };
91
+ }
92
+ interface ILinkMediaRef {
93
+ encrypt_query_param?: string;
94
+ full_url?: string;
95
+ aes_key?: string;
96
+ }
97
+ /**
98
+ * iLink WeixinMessage — aligned with @tencent-weixin/openclaw-weixin v1.0.2
99
+ * (WeixinMessage in src/api/types.ts).
100
+ */
101
+ interface ILinkWeixinMessage {
102
+ message_id?: number;
103
+ from_user_id?: string;
104
+ to_user_id?: string;
105
+ context_token?: string;
106
+ message_type?: number;
107
+ message_state?: number;
108
+ item_list?: ILinkMessageItem[];
109
+ create_time_ms?: number;
110
+ session_id?: string;
111
+ group_id?: string;
112
+ }
113
+ export interface WeixinQrCodeResult {
114
+ qrUrl: string;
115
+ qrPayload: string;
116
+ }
117
+ export type WeixinQrCodeStatus = {
118
+ status: 'waiting';
119
+ } | {
120
+ status: 'scanned';
121
+ } | {
122
+ status: 'confirmed';
123
+ botToken: string;
124
+ } | {
125
+ status: 'expired';
126
+ } | {
127
+ status: 'error';
128
+ message: string;
129
+ };
130
+ export declare class WeixinAdapter {
131
+ readonly connectorId = "weixin";
132
+ private readonly log;
133
+ private botToken;
134
+ private polling;
135
+ private pollAbortController;
136
+ private consecutiveErrors;
137
+ private getUpdatesBuf;
138
+ private readonly contextTokens;
139
+ private readonly pendingReplies;
140
+ private fetchFn;
141
+ private sessionExpiredCallback;
142
+ private readonly sessionStateStore;
143
+ private readonly runtimeOptions;
144
+ private readonly contentDedupFingerprints;
145
+ private readonly typingTickets;
146
+ private readonly typingTimers;
147
+ private readonly typingEpoch;
148
+ private fallbackMessageSequence;
149
+ constructor(botToken: string, log: ConnectorLogger, sessionStateStore?: WeixinSessionStateStore, runtimeOptions?: WeixinRuntimeOptions);
150
+ hasBotToken(): boolean;
151
+ downloadInboundMedia(locator: {
152
+ readonly platformKey: string;
153
+ }): Promise<Buffer>;
154
+ setBotToken(token: string): void;
155
+ /**
156
+ * F137 Phase D: Full disconnect — stop polling, clear bot_token and all session state.
157
+ * After disconnect, the adapter returns to pre-login state (hasBotToken() === false).
158
+ */
159
+ disconnect(): Promise<void>;
160
+ setOnSessionExpired(cb: () => void): void;
161
+ restoreSessionState(): Promise<void>;
162
+ private getHeaders;
163
+ /**
164
+ * Parse a raw iLink getupdates response into inbound messages.
165
+ * Returns parsed messages and updated cursor.
166
+ */
167
+ parseUpdates(raw: ILinkUpdate): {
168
+ messages: WeixinInboundMessage[];
169
+ newCursor: string;
170
+ sessionExpired: boolean;
171
+ };
172
+ /**
173
+ * Parse a single iLink WeixinMessage into our standard format.
174
+ * Uses item_list[].type to determine message kind (TEXT=1, IMAGE=2, VOICE=3, FILE=4, VIDEO=5).
175
+ */
176
+ private buildMediaKey;
177
+ private parseMessage;
178
+ private buildFallbackMessageId;
179
+ private nextFallbackMessageSequence;
180
+ /**
181
+ * Start long-polling loop for inbound messages.
182
+ * Similar pattern to TelegramAdapter.startPolling().
183
+ */
184
+ startPolling(handler: (msg: WeixinInboundMessage) => Promise<void>): void;
185
+ /**
186
+ * Stop long-polling gracefully.
187
+ */
188
+ stopPolling(): Promise<void>;
189
+ fetchTypingTicket(chatId: string, contextToken: string): Promise<void>;
190
+ startTyping(chatId: string): void;
191
+ stopTyping(chatId: string): void;
192
+ sendReply(externalChatId: string, content: string, _metadata?: Record<string, unknown>): Promise<void>;
193
+ private flushReply;
194
+ sendMedia(externalChatId: string, payload: {
195
+ type: 'image' | 'file' | 'audio';
196
+ content: AsyncIterable<Uint8Array>;
197
+ fileName?: string;
198
+ }): Promise<void>;
199
+ /**
200
+ * Convert WAV audio to SILK v3 (WeChat's native voice codec).
201
+ * Returns path to temp .silk file, or null if conversion fails.
202
+ */
203
+ private convertWavToSilk;
204
+ /**
205
+ * Parse WAV buffer (tolerant to RIFF size mismatch) and return mono PCM s16le.
206
+ * This avoids passing malformed WAV headers directly into silk-wasm as raw PCM.
207
+ */
208
+ private extractMonoPcmFromWav;
209
+ static stripMarkdownForWeixin(text: string): string;
210
+ /**
211
+ * Low-level: call /ilink/bot/sendmessage API.
212
+ */
213
+ private sendMessageApi;
214
+ private postSendMessageWithRetry;
215
+ private postSendMessageOnce;
216
+ private classifySendError;
217
+ /**
218
+ * Split text into chunks of maxLen characters, breaking at newlines or spaces.
219
+ */
220
+ chunkMessage(text: string, maxLen: number): string[];
221
+ /**
222
+ * Get the current polling state (for IM Hub status display).
223
+ */
224
+ isPolling(): boolean;
225
+ /**
226
+ * Check if we have a context_token for a given chatId.
227
+ */
228
+ hasContextToken(chatId: string): boolean;
229
+ private clearSessionState;
230
+ private clearPersistedSessionState;
231
+ private persistSessionState;
232
+ private buildContentDedupFingerprint;
233
+ private hasRecentContentDedupFingerprint;
234
+ private rememberContentDedupFingerprint;
235
+ private pruneContentDedupFingerprints;
236
+ private sleep;
237
+ /** @internal Test helper: inject a mock fetch function. */
238
+ _injectFetch(fn: typeof fetch): void;
239
+ /** @internal Test helper: inject a context_token for a chatId. */
240
+ _injectContextToken(chatId: string, token: string): void;
241
+ /** @internal Test helper: set the getupdates cursor. */
242
+ _setCursor(cursor: string): void;
243
+ /** @internal Test helper: get the current cursor. */
244
+ _getCursor(): string;
245
+ /** @internal Test helper: flush all pending debounced replies immediately. */
246
+ _flushAllPending(): Promise<void>;
247
+ private static staticFetchFn;
248
+ static fetchQrCode(): Promise<WeixinQrCodeResult>;
249
+ static pollQrCodeStatus(qrPayload: string): Promise<WeixinQrCodeStatus>;
250
+ static waitForQrCodeLogin(qrPayload: string, onStatusChange?: (status: WeixinQrCodeStatus) => void): Promise<WeixinQrCodeStatus>;
251
+ /** @internal Test helper: inject a mock fetch function for static QR methods. */
252
+ static _injectStaticFetch(fn: typeof fetch): void;
253
+ }
254
+ export {};
255
+ //# sourceMappingURL=WeixinAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WeixinAdapter.d.ts","sourceRoot":"","sources":["../src/WeixinAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAMlD,eAAO,MAAM,sBAAsB,QAAmB,CAAC;AA0BvD;;;;;;;;;;GAUG;AACH,QAAA,MAAM,gBAAgB,iFAAkF,CAAC;AACzG,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGpE,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACpC;AAgCD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,gFAAgF;AAChF,UAAU,gBAAgB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,UAAU,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,aAAa,CAAC;QACtB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,aAAa,CAAC;QACtB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,SAAS,CAAC,EAAE;QACV,KAAK,CAAC,EAAE,aAAa,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,KAAK,CAAC,EAAE,aAAa,CAAC;KACvB,CAAC;CACH;AAED,UAAU,aAAa;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,UAAU,kBAAkB;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA0BD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,MAAM,EAAE,SAAS,CAAA;CAAE,GACrB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAqBzC,qBAAa,aAAa;IACxB,QAAQ,CAAC,WAAW,YAAY;IAEhC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,mBAAmB,CAAgC;IAC3D,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAE3D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAQ3B;IACJ,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,sBAAsB,CAA6B;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAsC;IACxE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAuB;IACtD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA6B;IACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAC3D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqD;IAClF,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA6B;IACzD,OAAO,CAAC,uBAAuB,CAAK;gBAGlC,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,eAAe,EACpB,iBAAiB,CAAC,EAAE,uBAAuB,EAC3C,cAAc,GAAE,oBAAyB;IAQ3C,WAAW,IAAI,OAAO;IAIhB,oBAAoB,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAUtF,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAehC;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC,mBAAmB,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IAInC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB1C,OAAO,CAAC,UAAU;IAalB;;;OAGG;IACH,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG;QAAE,QAAQ,EAAE,oBAAoB,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE;IAyBhH;;;OAGG;IACH,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,YAAY;IAqFpB,OAAO,CAAC,sBAAsB;IAwC9B,OAAO,CAAC,2BAA2B;IAKnC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IA0GzE;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0B5E,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAuBjC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IA2B1B,SAAS,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YAuD9F,UAAU;IA+ClB,SAAS,CACb,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE;QACP,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;QACjC,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;QACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GACA,OAAO,CAAC,IAAI,CAAC;IAkIhB;;;OAGG;YACW,gBAAgB;IAoC9B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAoD7B,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAoBnD;;OAEG;YACW,cAAc;YAwBd,wBAAwB;YAuCxB,mBAAmB;IAwCjC,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IA0BpD;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIxC,OAAO,CAAC,iBAAiB;YAMX,0BAA0B;IAOxC,OAAO,CAAC,mBAAmB;IAa3B,OAAO,CAAC,4BAA4B;IAgBpC,OAAO,CAAC,gCAAgC;IAMxC,OAAO,CAAC,+BAA+B;IAQvC,OAAO,CAAC,6BAA6B;IAYrC,OAAO,CAAC,KAAK;IAMb,2DAA2D;IAC3D,YAAY,CAAC,EAAE,EAAE,OAAO,KAAK,GAAG,IAAI;IAIpC,kEAAkE;IAClE,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIxD,wDAAwD;IACxD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIhC,qDAAqD;IACrD,UAAU,IAAI,MAAM;IAIpB,8EAA8E;IACxE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAWvC,OAAO,CAAC,MAAM,CAAC,aAAa,CAAkC;WAEjD,WAAW,IAAI,OAAO,CAAC,kBAAkB,CAAC;WAuB1C,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;WAqChE,kBAAkB,CAC7B,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,GACpD,OAAO,CAAC,kBAAkB,CAAC;IAiB9B,iFAAiF;IACjF,MAAM,CAAC,kBAAkB,CAAC,EAAE,EAAE,OAAO,KAAK,GAAG,IAAI;CAGlD"}