@elizaos/plugin-whatsapp 1.0.0 → 2.0.0-alpha.10
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/dist/index.js +1508 -24
- package/dist/index.js.map +25 -1
- package/dist/src/accounts.d.ts +199 -0
- package/dist/src/accounts.d.ts.map +1 -0
- package/dist/src/actions/index.d.ts +3 -0
- package/dist/src/actions/index.d.ts.map +1 -0
- package/dist/src/actions/sendMessage.d.ts +4 -0
- package/dist/src/actions/sendMessage.d.ts.map +1 -0
- package/dist/src/actions/sendReaction.d.ts +4 -0
- package/dist/src/actions/sendReaction.d.ts.map +1 -0
- package/dist/src/baileys/auth.d.ts +10 -0
- package/dist/src/baileys/auth.d.ts.map +1 -0
- package/dist/src/baileys/connection.d.ts +19 -0
- package/dist/src/baileys/connection.d.ts.map +1 -0
- package/dist/src/baileys/index.d.ts +5 -0
- package/dist/src/baileys/index.d.ts.map +1 -0
- package/dist/src/baileys/message-adapter.d.ts +13 -0
- package/dist/src/baileys/message-adapter.d.ts.map +1 -0
- package/dist/src/baileys/qr-code.d.ts +6 -0
- package/dist/src/baileys/qr-code.d.ts.map +1 -0
- package/dist/src/client.d.ts +88 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/clients/baileys-client.d.ts +17 -0
- package/dist/src/clients/baileys-client.d.ts.map +1 -0
- package/dist/src/clients/factory.d.ts +6 -0
- package/dist/src/clients/factory.d.ts.map +1 -0
- package/dist/src/clients/index.d.ts +4 -0
- package/dist/src/clients/index.d.ts.map +1 -0
- package/dist/src/clients/interface.d.ts +10 -0
- package/dist/src/clients/interface.d.ts.map +1 -0
- package/dist/src/config.d.ts +135 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/handlers/index.d.ts +3 -0
- package/dist/src/handlers/index.d.ts.map +1 -0
- package/dist/src/handlers/message.handler.d.ts +8 -0
- package/dist/src/handlers/message.handler.d.ts.map +1 -0
- package/dist/src/handlers/webhook.handler.d.ts +7 -0
- package/dist/src/handlers/webhook.handler.d.ts.map +1 -0
- package/dist/src/index.d.ts +27 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/normalize.d.ts +69 -0
- package/dist/src/normalize.d.ts.map +1 -0
- package/dist/src/service.d.ts +117 -0
- package/dist/src/service.d.ts.map +1 -0
- package/dist/src/types.d.ts +367 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/utils/config-detector.d.ts +3 -0
- package/dist/src/utils/config-detector.d.ts.map +1 -0
- package/dist/src/utils/index.d.ts +3 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/validators.d.ts +10 -0
- package/dist/src/utils/validators.d.ts.map +1 -0
- package/package.json +129 -75
- package/LICENSE +0 -21
- package/README.md +0 -226
- package/dist/index.d.ts +0 -71
package/dist/index.js.map
CHANGED
|
@@ -1 +1,25 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/actions/sendMessage.ts", "../src/actions/sendReaction.ts", "../src/client.ts", "../src/utils/config-detector.ts", "../src/clients/baileys-client.ts", "../src/baileys/auth.ts", "../src/baileys/connection.ts", "../src/baileys/message-adapter.ts", "../src/baileys/qr-code.ts", "../src/clients/factory.ts", "../src/handlers/message.handler.ts", "../src/handlers/webhook.handler.ts", "../src/accounts.ts", "../src/normalize.ts", "../src/types.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import { EventEmitter } from \"node:events\";\nimport type { Plugin } from \"@elizaos/core\";\nimport { sendMessageAction, sendReactionAction } from \"./actions\";\nimport { ClientFactory } from \"./clients/factory\";\nimport type { IWhatsAppClient } from \"./clients/interface\";\nimport { MessageHandler, WebhookHandler } from \"./handlers\";\nimport type {\n ConnectionStatus,\n WhatsAppConfig,\n WhatsAppMessage,\n WhatsAppMessageResponse,\n WhatsAppWebhookEvent,\n} from \"./types\";\n\nexport class WhatsAppPlugin extends EventEmitter implements Plugin {\n private readonly client: IWhatsAppClient;\n private readonly messageHandler: MessageHandler;\n private readonly webhookHandler: WebhookHandler;\n\n name: string;\n description: string;\n actions = [sendMessageAction, sendReactionAction];\n\n constructor(config: WhatsAppConfig) {\n super();\n this.name = \"WhatsApp Plugin\";\n this.description = \"WhatsApp integration supporting Cloud API and Baileys (QR auth)\";\n this.client = ClientFactory.create(config);\n this.messageHandler = new MessageHandler(this.client);\n this.webhookHandler = new WebhookHandler();\n this.setupEventForwarding();\n }\n\n private setupEventForwarding(): void {\n this.client.on(\"message\", (payload) => this.emit(\"message\", payload));\n this.client.on(\"qr\", (payload) => this.emit(\"qr\", payload));\n this.client.on(\"ready\", () => this.emit(\"ready\"));\n this.client.on(\"connection\", (status) => this.emit(\"connection\", status));\n this.client.on(\"error\", (error) => this.emit(\"error\", error));\n }\n\n async start(): Promise<void> {\n await this.client.start();\n }\n\n async stop(): Promise<void> {\n await this.client.stop();\n }\n\n getConnectionStatus(): ConnectionStatus {\n return this.client.getConnectionStatus();\n }\n\n async sendMessage(message: WhatsAppMessage): Promise<WhatsAppMessageResponse> {\n return this.messageHandler.send(message);\n }\n\n async handleWebhook(event: WhatsAppWebhookEvent): Promise<void> {\n return this.webhookHandler.handle(event);\n }\n\n async verifyWebhook(token: string): Promise<boolean> {\n if (!this.client.verifyWebhook) {\n throw new Error(\"verifyWebhook is only supported by Cloud API authentication\");\n }\n return this.client.verifyWebhook(token);\n }\n}\n\nconst whatsappPlugin: Plugin = {\n name: \"whatsapp\",\n description: \"WhatsApp integration for ElizaOS (Cloud API + Baileys)\",\n actions: [sendMessageAction, sendReactionAction],\n};\n\nexport default whatsappPlugin;\n\n// Account management exports\nexport {\n checkWhatsAppUserAccess,\n DEFAULT_ACCOUNT_ID,\n isMultiAccountEnabled,\n isWhatsAppMentionRequired,\n isWhatsAppUserAllowed,\n listEnabledWhatsAppAccounts,\n listWhatsAppAccountIds,\n normalizeAccountId,\n type ResolvedWhatsAppAccount,\n resolveDefaultWhatsAppAccountId,\n resolveWhatsAppAccount,\n resolveWhatsAppGroupConfig,\n resolveWhatsAppToken,\n type WhatsAppAccessCheckResult,\n type WhatsAppAccountRuntimeConfig,\n type WhatsAppGroupRuntimeConfig,\n type WhatsAppMultiAccountConfig,\n type WhatsAppTokenResolution,\n type WhatsAppTokenSource,\n} from \"./accounts\";\n\n// Channel configuration types\nexport type {\n WhatsAppAccountConfig,\n WhatsAppAckReactionConfig,\n WhatsAppActionConfig,\n WhatsAppChannelConfig,\n WhatsAppGroupConfig,\n} from \"./config\";\n\n// Normalization and utility exports\nexport {\n buildWhatsAppUserJid,\n type ChunkWhatsAppTextOpts,\n chunkWhatsAppText,\n formatWhatsAppId,\n formatWhatsAppPhoneNumber,\n getWhatsAppChatType,\n isValidWhatsAppNumber,\n isWhatsAppGroup,\n isWhatsAppGroupJid,\n isWhatsAppUserTarget,\n normalizeE164,\n normalizeWhatsAppTarget,\n resolveWhatsAppSystemLocation,\n truncateText,\n WHATSAPP_TEXT_CHUNK_LIMIT,\n} from \"./normalize\";\n\nexport { ClientFactory } from \"./clients/factory\";\nexport * from \"./types\";\n",
|
|
6
|
+
"import type {\n Action,\n ActionExample,\n ActionResult,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { composePromptFromState, ModelType, parseJSONObjectFromText } from \"@elizaos/core\";\n\nexport const WHATSAPP_SEND_MESSAGE_ACTION = \"WHATSAPP_SEND_MESSAGE\";\n\nconst SEND_MESSAGE_TEMPLATE = `\nYou are extracting WhatsApp message parameters from a conversation.\n\nThe user wants to send a WhatsApp message. Extract the following:\n1. to: The phone number to send to (E.164 format, e.g., +14155552671)\n2. text: The message text to send\n\n{{recentMessages}}\n\nBased on the conversation, extract the message parameters.\n\nRespond with a JSON object:\n{\n \"to\": \"+14155552671\",\n \"text\": \"Hello from WhatsApp!\"\n}\n`;\n\ninterface SendMessageParams {\n to: string;\n text: string;\n}\n\nexport const sendMessageAction: Action = {\n name: WHATSAPP_SEND_MESSAGE_ACTION,\n similes: [\"SEND_WHATSAPP\", \"WHATSAPP_MESSAGE\", \"TEXT_WHATSAPP\", \"SEND_WHATSAPP_MESSAGE\"],\n description: \"Send a text message via WhatsApp\",\n\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['whatsapp', 'send', 'message'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:whatsapp|send|message)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'whatsapp';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n const source = message.content?.source;\n return source === \"whatsapp\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n _options?: HandlerOptions,\n callback?: HandlerCallback\n ): Promise<ActionResult> => {\n // Get WhatsApp settings\n const accessToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string;\n const phoneNumberId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string;\n const apiVersion = (runtime.getSetting(\"WHATSAPP_API_VERSION\") as string) || \"v24.0\";\n\n if (!accessToken || !phoneNumberId) {\n if (callback) {\n await callback({\n text: \"WhatsApp is not configured. Missing access token or phone number ID.\",\n });\n }\n return { success: false, error: \"WhatsApp not configured\" };\n }\n\n const currentState = state ?? (await runtime.composeState(message));\n\n // Extract message parameters using LLM\n const prompt = composePromptFromState({\n state: currentState,\n template: SEND_MESSAGE_TEMPLATE,\n });\n\n let params: SendMessageParams;\n try {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsed = parseJSONObjectFromText(response) as unknown as SendMessageParams | null;\n if (!parsed || !parsed.to || !parsed.text) {\n // Try to use context from message\n const to = message.content?.from as string;\n const text = currentState.values?.response?.toString() || \"\";\n\n if (!to) {\n if (callback) {\n await callback({\n text: \"Could not determine who to send the message to\",\n });\n }\n return { success: false, error: \"Missing recipient\" };\n }\n\n // Validate text is not empty\n if (!text || text.trim() === \"\") {\n if (callback) {\n await callback({\n text: \"Cannot send an empty message. Please provide message content.\",\n });\n }\n return { success: false, error: \"Empty message text\" };\n }\n\n params = { to, text };\n } else {\n // Also validate that parsed text is not empty\n if (!parsed.text.trim()) {\n if (callback) {\n await callback({\n text: \"Cannot send an empty message. Please provide message content.\",\n });\n }\n return { success: false, error: \"Empty message text\" };\n }\n params = parsed;\n }\n } catch {\n if (callback) {\n await callback({\n text: \"Failed to parse message parameters\",\n });\n }\n return { success: false, error: \"Failed to parse message parameters\" };\n }\n\n // Send the message via WhatsApp Cloud API\n try {\n const url = `https://graph.facebook.com/${apiVersion}/${phoneNumberId}/messages`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: params.to,\n type: \"text\",\n text: {\n preview_url: false,\n body: params.text,\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n throw new Error(errorData.error?.message || `HTTP ${response.status}`);\n }\n\n const data = (await response.json()) as { messages: Array<{ id: string }> };\n const messageId = data.messages?.[0]?.id;\n\n if (callback) {\n await callback({\n text: `Message sent to ${params.to}`,\n action: WHATSAPP_SEND_MESSAGE_ACTION,\n });\n }\n\n return {\n success: true,\n data: {\n action: WHATSAPP_SEND_MESSAGE_ACTION,\n to: params.to,\n messageId,\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (callback) {\n await callback({\n text: `Failed to send WhatsApp message: ${errorMessage}`,\n });\n }\n return { success: false, error: errorMessage };\n }\n },\n\n examples: [\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"Send a WhatsApp message to +14155552671 saying hello\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"I'll send that WhatsApp message now.\",\n actions: [WHATSAPP_SEND_MESSAGE_ACTION],\n },\n },\n ],\n ] as ActionExample[][],\n};\n",
|
|
7
|
+
"import type {\n Action,\n ActionExample,\n ActionResult,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n} from \"@elizaos/core\";\nimport { composePromptFromState, ModelType, parseJSONObjectFromText } from \"@elizaos/core\";\n\nexport const WHATSAPP_SEND_REACTION_ACTION = \"WHATSAPP_SEND_REACTION\";\n\nconst REACTION_TEMPLATE = `\nYou are extracting WhatsApp reaction parameters from a conversation.\n\nThe user wants to react to a WhatsApp message. Extract the following:\n1. messageId: The ID of the message to react to\n2. emoji: The emoji to use as a reaction\n\n{{recentMessages}}\n\nBased on the conversation, extract the reaction parameters.\n\nRespond with a JSON object:\n{\n \"messageId\": \"wamid.xxx\",\n \"emoji\": \"👍\"\n}\n`;\n\ninterface ReactionParams {\n messageId: string;\n emoji: string;\n}\n\nexport const sendReactionAction: Action = {\n name: WHATSAPP_SEND_REACTION_ACTION,\n similes: [\"WHATSAPP_REACT\", \"REACT_WHATSAPP\", \"WHATSAPP_EMOJI\"],\n description: \"Send a reaction emoji to a WhatsApp message\",\n\n validate: async (runtime: any, message: any, state?: any, options?: any): Promise<boolean> => {\n \tconst __avTextRaw = typeof message?.content?.text === 'string' ? message.content.text : '';\n \tconst __avText = __avTextRaw.toLowerCase();\n \tconst __avKeywords = ['whatsapp', 'send', 'reaction'];\n \tconst __avKeywordOk =\n \t\t__avKeywords.length > 0 &&\n \t\t__avKeywords.some((kw) => kw.length > 0 && __avText.includes(kw));\n \tconst __avRegex = new RegExp('\\\\b(?:whatsapp|send|reaction)\\\\b', 'i');\n \tconst __avRegexOk = __avRegex.test(__avText);\n \tconst __avSource = String(message?.content?.source ?? message?.source ?? '');\n \tconst __avExpectedSource = 'whatsapp';\n \tconst __avSourceOk = __avExpectedSource\n \t\t? __avSource === __avExpectedSource\n \t\t: Boolean(__avSource || state || runtime?.agentId || runtime?.getService);\n \tconst __avOptions = options && typeof options === 'object' ? options : {};\n \tconst __avInputOk =\n \t\t__avText.trim().length > 0 ||\n \t\tObject.keys(__avOptions as Record<string, unknown>).length > 0 ||\n \t\tBoolean(message?.content && typeof message.content === 'object');\n\n \tif (!(__avKeywordOk && __avRegexOk && __avSourceOk && __avInputOk)) {\n \t\treturn false;\n \t}\n\n \tconst __avLegacyValidate = async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {\n const source = message.content?.source;\n return source === \"whatsapp\";\n };\n \ttry {\n \t\treturn Boolean(await (__avLegacyValidate as any)(runtime, message, state, options));\n \t} catch {\n \t\treturn false;\n \t}\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state: State | undefined,\n _options?: HandlerOptions,\n callback?: HandlerCallback\n ): Promise<ActionResult> => {\n // Get WhatsApp settings\n const accessToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string;\n const phoneNumberId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string;\n const apiVersion = (runtime.getSetting(\"WHATSAPP_API_VERSION\") as string) || \"v24.0\";\n\n if (!accessToken || !phoneNumberId) {\n if (callback) {\n await callback({\n text: \"WhatsApp is not configured. Missing access token or phone number ID.\",\n });\n }\n return { success: false, error: \"WhatsApp not configured\" };\n }\n\n const currentState = state ?? (await runtime.composeState(message));\n\n // Extract reaction parameters using LLM\n const prompt = composePromptFromState({\n state: currentState,\n template: REACTION_TEMPLATE,\n });\n\n let params: ReactionParams;\n try {\n const response = await runtime.useModel(ModelType.TEXT_SMALL, {\n prompt,\n });\n\n const parsed = parseJSONObjectFromText(response) as unknown as ReactionParams | null;\n if (!parsed || !parsed.messageId || !parsed.emoji) {\n // Try to use context from message\n const messageId = message.content?.messageId as string;\n if (!messageId) {\n if (callback) {\n await callback({\n text: \"Could not determine which message to react to\",\n });\n }\n return { success: false, error: \"Missing message ID\" };\n }\n params = { messageId, emoji: \"👍\" }; // Default to thumbs up\n } else {\n params = parsed;\n }\n } catch {\n if (callback) {\n await callback({\n text: \"Failed to parse reaction parameters\",\n });\n }\n return { success: false, error: \"Failed to parse reaction parameters\" };\n }\n\n // Get the recipient (sender of the original message)\n const to = message.content?.from as string;\n if (!to) {\n if (callback) {\n await callback({\n text: \"Could not determine the recipient for the reaction\",\n });\n }\n return { success: false, error: \"Missing recipient\" };\n }\n\n // Send the reaction via WhatsApp Cloud API\n try {\n const url = `https://graph.facebook.com/${apiVersion}/${phoneNumberId}/messages`;\n\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to,\n type: \"reaction\",\n reaction: {\n message_id: params.messageId,\n emoji: params.emoji,\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n throw new Error(errorData.error?.message || `HTTP ${response.status}`);\n }\n\n if (callback) {\n await callback({\n text: `Reacted with ${params.emoji}`,\n action: WHATSAPP_SEND_REACTION_ACTION,\n });\n }\n\n return {\n success: true,\n data: {\n action: WHATSAPP_SEND_REACTION_ACTION,\n messageId: params.messageId,\n emoji: params.emoji,\n },\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (callback) {\n await callback({\n text: `Failed to send reaction: ${errorMessage}`,\n });\n }\n return { success: false, error: errorMessage };\n }\n },\n\n examples: [\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"React with a thumbs up\",\n },\n },\n {\n name: \"{{agentName}}\",\n content: {\n text: \"I'll add that reaction.\",\n actions: [WHATSAPP_SEND_REACTION_ACTION],\n },\n },\n ],\n ] as ActionExample[][],\n};\n",
|
|
8
|
+
"import axios, { type AxiosInstance, type AxiosResponse } from \"axios\";\nimport { EventEmitter } from \"node:events\";\nimport type { IWhatsAppClient } from \"./clients/interface\";\nimport type {\n CloudAPIConfig,\n ConnectionStatus,\n SendReactionParams,\n SendReactionResult,\n WhatsAppInteractiveMessage,\n WhatsAppLocationMessage,\n WhatsAppMediaMessage,\n WhatsAppMessage,\n WhatsAppMessageResponse,\n WhatsAppReactionMessage,\n} from \"./types\";\n\nconst DEFAULT_API_VERSION = \"v24.0\";\n\nexport class WhatsAppClient extends EventEmitter implements IWhatsAppClient {\n private client: AxiosInstance;\n private config: CloudAPIConfig;\n private connectionStatus: ConnectionStatus = \"close\";\n\n constructor(config: CloudAPIConfig) {\n super();\n this.config = config;\n const apiVersion = config.apiVersion || DEFAULT_API_VERSION;\n\n this.client = axios.create({\n baseURL: `https://graph.facebook.com/${apiVersion}`,\n headers: {\n Authorization: `Bearer ${config.accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n });\n }\n\n async start(): Promise<void> {\n this.connectionStatus = \"open\";\n this.emit(\"connection\", \"open\");\n this.emit(\"ready\");\n }\n\n async stop(): Promise<void> {\n this.connectionStatus = \"close\";\n this.emit(\"connection\", \"close\");\n }\n\n getConnectionStatus(): ConnectionStatus {\n return this.connectionStatus;\n }\n\n /**\n * Get the configured phone number ID.\n */\n getPhoneNumberId(): string {\n return this.config.phoneNumberId;\n }\n\n /**\n * Send a message of any supported type.\n */\n async sendMessage(message: WhatsAppMessage): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n const endpoint = `/${this.config.phoneNumberId}/messages`;\n const payload = this.buildMessagePayload(message);\n return this.client.post(endpoint, payload);\n }\n\n /**\n * Send a text message.\n */\n async sendTextMessage(\n to: string,\n text: string,\n _previewUrl = false\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"text\",\n to,\n content: text,\n });\n }\n\n /**\n * Send a reaction to a message.\n */\n async sendReaction(params: SendReactionParams): Promise<SendReactionResult> {\n const endpoint = `/${this.config.phoneNumberId}/messages`;\n\n const payload = {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: params.to,\n type: \"reaction\",\n reaction: {\n message_id: params.messageId,\n emoji: params.emoji,\n },\n };\n\n try {\n const response = await this.client.post<WhatsAppMessageResponse>(endpoint, payload);\n return {\n success: true,\n messageId: response.data.messages?.[0]?.id,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: errorMessage,\n };\n }\n }\n\n /**\n * Remove a reaction from a message (send empty emoji).\n */\n async removeReaction(to: string, messageId: string): Promise<SendReactionResult> {\n return this.sendReaction({\n to,\n messageId,\n emoji: \"\",\n });\n }\n\n /**\n * Send an image message.\n */\n async sendImage(\n to: string,\n imageUrl: string,\n caption?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"image\",\n to,\n content: {\n link: imageUrl,\n caption,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send a video message.\n */\n async sendVideo(\n to: string,\n videoUrl: string,\n caption?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"video\",\n to,\n content: {\n link: videoUrl,\n caption,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send an audio message.\n */\n async sendAudio(to: string, audioUrl: string): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"audio\",\n to,\n content: {\n link: audioUrl,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send a document message.\n */\n async sendDocument(\n to: string,\n documentUrl: string,\n filename?: string,\n caption?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"document\",\n to,\n content: {\n link: documentUrl,\n filename,\n caption,\n } as WhatsAppMediaMessage,\n });\n }\n\n /**\n * Send a location message.\n */\n async sendLocation(\n to: string,\n latitude: number,\n longitude: number,\n name?: string,\n address?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n return this.sendMessage({\n type: \"location\",\n to,\n content: {\n latitude,\n longitude,\n name,\n address,\n } as WhatsAppLocationMessage,\n });\n }\n\n /**\n * Send an interactive button message.\n */\n async sendButtonMessage(\n to: string,\n bodyText: string,\n buttons: Array<{ id: string; title: string }>,\n headerText?: string,\n footerText?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n const interactive: WhatsAppInteractiveMessage = {\n type: \"button\",\n body: { text: bodyText },\n action: {\n buttons: buttons.map((btn) => ({\n type: \"reply\" as const,\n reply: { id: btn.id, title: btn.title },\n })),\n },\n };\n\n if (headerText) {\n interactive.header = { type: \"text\", text: headerText };\n }\n if (footerText) {\n interactive.footer = { text: footerText };\n }\n\n return this.sendMessage({\n type: \"interactive\",\n to,\n content: interactive,\n });\n }\n\n /**\n * Send an interactive list message.\n */\n async sendListMessage(\n to: string,\n bodyText: string,\n buttonText: string,\n sections: Array<{\n title?: string;\n rows: Array<{ id: string; title: string; description?: string }>;\n }>,\n headerText?: string,\n footerText?: string\n ): Promise<AxiosResponse<WhatsAppMessageResponse>> {\n const interactive: WhatsAppInteractiveMessage = {\n type: \"list\",\n body: { text: bodyText },\n action: {\n button: buttonText,\n sections,\n },\n };\n\n if (headerText) {\n interactive.header = { type: \"text\", text: headerText };\n }\n if (footerText) {\n interactive.footer = { text: footerText };\n }\n\n return this.sendMessage({\n type: \"interactive\",\n to,\n content: interactive,\n });\n }\n\n /**\n * Mark a message as read.\n */\n async markMessageAsRead(messageId: string): Promise<boolean> {\n const endpoint = `/${this.config.phoneNumberId}/messages`;\n\n const payload = {\n messaging_product: \"whatsapp\",\n status: \"read\",\n message_id: messageId,\n };\n\n try {\n await this.client.post(endpoint, payload);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Download media by ID.\n */\n async getMediaUrl(mediaId: string): Promise<string | null> {\n try {\n const response = await this.client.get(`/${mediaId}`);\n return response.data.url || null;\n } catch {\n return null;\n }\n }\n\n /**\n * Verify webhook token.\n */\n async verifyWebhook(token: string): Promise<boolean> {\n return token === this.config.webhookVerifyToken;\n }\n\n /**\n * Build the message payload based on message type.\n */\n private buildMessagePayload(message: WhatsAppMessage): Record<string, unknown> {\n const basePayload = {\n messaging_product: \"whatsapp\",\n recipient_type: \"individual\",\n to: message.to,\n type: message.type,\n };\n\n // Add context for replies\n const contextPayload = message.replyToMessageId\n ? { context: { message_id: message.replyToMessageId } }\n : {};\n\n switch (message.type) {\n case \"text\":\n return {\n ...basePayload,\n ...contextPayload,\n text: {\n body: message.content as string,\n },\n };\n\n case \"template\":\n return {\n ...basePayload,\n ...contextPayload,\n template: message.content,\n };\n\n case \"image\": {\n const imageContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n image: {\n link: imageContent.link,\n caption: imageContent.caption,\n },\n };\n }\n\n case \"video\": {\n const videoContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n video: {\n link: videoContent.link,\n caption: videoContent.caption,\n },\n };\n }\n\n case \"audio\": {\n const audioContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n audio: {\n link: audioContent.link,\n },\n };\n }\n\n case \"document\": {\n const docContent = message.content as WhatsAppMediaMessage;\n return {\n ...basePayload,\n ...contextPayload,\n document: {\n link: docContent.link,\n filename: docContent.filename,\n caption: docContent.caption,\n },\n };\n }\n\n case \"location\": {\n const locContent = message.content as WhatsAppLocationMessage;\n return {\n ...basePayload,\n ...contextPayload,\n location: {\n latitude: locContent.latitude,\n longitude: locContent.longitude,\n name: locContent.name,\n address: locContent.address,\n },\n };\n }\n\n case \"reaction\": {\n const reactionContent = message.content as WhatsAppReactionMessage;\n return {\n ...basePayload,\n reaction: {\n message_id: reactionContent.messageId,\n emoji: reactionContent.emoji,\n },\n };\n }\n\n case \"interactive\": {\n const interactiveContent = message.content as WhatsAppInteractiveMessage;\n return {\n ...basePayload,\n ...contextPayload,\n interactive: interactiveContent,\n };\n }\n\n default:\n return basePayload;\n }\n }\n}\n",
|
|
9
|
+
"import type { WhatsAppConfig } from \"../types\";\n\nexport function detectAuthMethod(config: WhatsAppConfig | Record<string, unknown>): \"baileys\" | \"cloudapi\" {\n const explicitMethod = (config as { authMethod?: unknown }).authMethod;\n if (explicitMethod !== undefined) {\n if (explicitMethod === \"baileys\" || explicitMethod === \"cloudapi\") {\n return explicitMethod;\n }\n throw new Error(\n `Invalid authMethod: \"${String(explicitMethod)}\". Must be either \"baileys\" or \"cloudapi\".`\n );\n }\n\n if (\"authDir\" in config && config.authDir) {\n return \"baileys\";\n }\n\n if (\"accessToken\" in config && \"phoneNumberId\" in config) {\n return \"cloudapi\";\n }\n\n throw new Error(\n \"Cannot detect auth method. Provide either authDir (Baileys) or accessToken + phoneNumberId (Cloud API).\"\n );\n}\n",
|
|
10
|
+
"import { EventEmitter } from \"node:events\";\nimport { BaileysAuthManager } from \"../baileys/auth\";\nimport { BaileysConnection } from \"../baileys/connection\";\nimport { MessageAdapter } from \"../baileys/message-adapter\";\nimport { QRCodeGenerator } from \"../baileys/qr-code\";\nimport type { IWhatsAppClient } from \"./interface\";\nimport type { BaileysConfig, ConnectionStatus, WhatsAppMessage, WhatsAppMessageResponse } from \"../types\";\n\nexport class BaileysClient extends EventEmitter implements IWhatsAppClient {\n private readonly config: BaileysConfig;\n private readonly authManager: BaileysAuthManager;\n private readonly connection: BaileysConnection;\n private readonly qrGenerator: QRCodeGenerator;\n private readonly adapter: MessageAdapter;\n\n constructor(config: BaileysConfig) {\n super();\n this.config = config;\n this.authManager = new BaileysAuthManager(config.authDir);\n this.connection = new BaileysConnection(this.authManager);\n this.qrGenerator = new QRCodeGenerator();\n this.adapter = new MessageAdapter();\n this.setupEventForwarding();\n }\n\n private setupEventForwarding(): void {\n this.connection.on(\"qr\", async (qr: string) => {\n try {\n const qrData = await this.qrGenerator.generate(qr);\n if (this.config.printQRInTerminal !== false) {\n console.log(\"\\n=== Scan QR Code ===\\n\");\n console.log(qrData.terminal);\n }\n this.emit(\"qr\", qrData);\n } catch (error) {\n this.emit(\"error\", error);\n }\n });\n\n this.connection.on(\"connection\", (status: ConnectionStatus) => {\n this.emit(\"connection\", status);\n if (status === \"open\") {\n this.emit(\"ready\");\n }\n });\n\n this.connection.on(\"messages\", (messages: unknown[]) => {\n for (const message of messages) {\n const maybe = message as { key?: { fromMe?: boolean }; message?: unknown };\n if (!maybe.key?.fromMe && maybe.message) {\n this.emit(\"message\", this.adapter.toUnified(message as any));\n }\n }\n });\n\n this.connection.on(\"error\", (error: unknown) => {\n this.emit(\"error\", error);\n });\n }\n\n async start(): Promise<void> {\n await this.connection.connect();\n }\n\n async stop(): Promise<void> {\n await this.connection.disconnect();\n }\n\n async sendMessage(message: WhatsAppMessage): Promise<WhatsAppMessageResponse> {\n const socket = this.connection.getSocket();\n if (!socket) {\n throw new Error(\"Not connected to WhatsApp via Baileys\");\n }\n\n const payload = this.adapter.toBaileys(message);\n const result = await socket.sendMessage(message.to, payload as any);\n const id = result?.key?.id ?? \"\";\n\n return {\n messaging_product: \"whatsapp\",\n contacts: [{ input: message.to, wa_id: message.to }],\n messages: [{ id }],\n };\n }\n\n getConnectionStatus(): ConnectionStatus {\n return this.connection.getStatus();\n }\n}\n",
|
|
11
|
+
"import { useMultiFileAuthState } from \"@whiskeysockets/baileys\";\nimport type { AuthenticationState } from \"@whiskeysockets/baileys\";\n\nexport class BaileysAuthManager {\n private readonly authDir: string;\n private state?: AuthenticationState;\n private saveCreds?: () => Promise<void>;\n\n constructor(authDir: string) {\n this.authDir = authDir;\n }\n\n async initialize(): Promise<AuthenticationState> {\n const result = await useMultiFileAuthState(this.authDir);\n this.state = result.state;\n this.saveCreds = result.saveCreds;\n return this.state;\n }\n\n async save(): Promise<void> {\n if (this.saveCreds) {\n await this.saveCreds();\n }\n }\n}\n",
|
|
12
|
+
"import makeWASocket, { DisconnectReason, type WASocket } from \"@whiskeysockets/baileys\";\nimport { Boom } from \"@hapi/boom\";\nimport { EventEmitter } from \"node:events\";\nimport pino from \"pino\";\nimport type { BaileysAuthManager } from \"./auth\";\nimport type { ConnectionStatus } from \"../types\";\n\nexport class BaileysConnection extends EventEmitter {\n private socket?: WASocket;\n private readonly authManager: BaileysAuthManager;\n private connectionStatus: ConnectionStatus = \"close\";\n private reconnecting = false;\n private reconnectAttempts = 0;\n private readonly maxReconnectAttempts = 10;\n\n constructor(authManager: BaileysAuthManager) {\n super();\n this.authManager = authManager;\n }\n\n async connect(): Promise<WASocket> {\n this.connectionStatus = \"connecting\";\n this.emit(\"connection\", \"connecting\");\n\n const state = await this.authManager.initialize();\n this.socket = makeWASocket({\n auth: state,\n printQRInTerminal: false,\n logger: pino({ level: \"silent\" }),\n browser: [\"Chrome (Linux)\", \"\", \"\"],\n });\n\n this.setupEventHandlers();\n return this.socket;\n }\n\n private setupEventHandlers(): void {\n if (!this.socket) {\n return;\n }\n\n this.socket.ev.on(\"connection.update\", async (update) => {\n const { connection, qr, lastDisconnect } = update;\n\n if (qr) {\n this.emit(\"qr\", qr);\n }\n\n if (connection) {\n this.connectionStatus = connection;\n this.emit(\"connection\", connection);\n }\n\n if (connection === \"open\") {\n this.reconnectAttempts = 0;\n return;\n }\n\n if (connection !== \"close\") {\n return;\n }\n\n const statusCode = (lastDisconnect?.error as Boom | undefined)?.output?.statusCode;\n const isQRTimeout = statusCode === 515;\n const shouldReconnect = statusCode !== DisconnectReason.loggedOut && statusCode !== 405;\n\n if (lastDisconnect?.error && !isQRTimeout) {\n this.emit(\"error\", lastDisconnect.error);\n }\n\n if (!shouldReconnect) {\n return;\n }\n\n if (this.reconnecting) {\n return;\n }\n\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.emit(\"error\", new Error(\"Max reconnection attempts reached\"));\n return;\n }\n\n this.reconnecting = true;\n try {\n this.reconnectAttempts += 1;\n const baseDelayMs = isQRTimeout ? 1000 : 3000;\n const backoffMs = Math.min(\n baseDelayMs * Math.pow(2, this.reconnectAttempts - 1),\n 30000\n );\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n await this.connect();\n } catch (error) {\n this.emit(\"error\", error);\n } finally {\n this.reconnecting = false;\n }\n });\n\n this.socket.ev.on(\"creds.update\", async () => {\n await this.authManager.save();\n });\n\n this.socket.ev.on(\"messages.upsert\", ({ messages }) => {\n this.emit(\"messages\", messages);\n });\n }\n\n getSocket(): WASocket | undefined {\n return this.socket;\n }\n\n getStatus(): ConnectionStatus {\n return this.connectionStatus;\n }\n\n async disconnect(): Promise<void> {\n if (!this.socket) {\n return;\n }\n\n (\n this.socket.ev as unknown as {\n removeAllListeners: (...args: unknown[]) => void;\n }\n ).removeAllListeners();\n (this.socket as unknown as { ws?: { close?: () => void } }).ws?.close?.();\n this.socket = undefined;\n this.connectionStatus = \"close\";\n this.emit(\"connection\", \"close\");\n }\n}\n",
|
|
13
|
+
"import type { proto } from \"@whiskeysockets/baileys\";\nimport type {\n UnifiedMessage,\n WhatsAppMediaMessage,\n WhatsAppMessage,\n WhatsAppTemplate,\n} from \"../types\";\n\nexport class MessageAdapter {\n toUnified(msg: proto.IWebMessageInfo): UnifiedMessage {\n return {\n id: msg.key?.id ?? \"\",\n from: msg.key?.remoteJid ?? \"\",\n timestamp: Number(msg.messageTimestamp ?? 0),\n type: this.detectType(msg),\n content: this.extractContent(msg),\n };\n }\n\n toBaileys(msg: WhatsAppMessage): Record<string, unknown> {\n switch (msg.type) {\n case \"text\":\n return { text: msg.content as string };\n case \"image\":\n return this.mediaWithCaption(\"image\", msg.content as WhatsAppMediaMessage);\n case \"video\":\n return this.mediaWithCaption(\"video\", msg.content as WhatsAppMediaMessage);\n case \"audio\":\n return this.mediaNoCaption(\"audio\", msg.content as WhatsAppMediaMessage);\n case \"document\":\n return this.mediaWithFilename(msg.content as WhatsAppMediaMessage);\n case \"template\":\n return { text: this.renderTemplate(msg.content as WhatsAppTemplate) };\n default:\n throw new Error(`Message type ${msg.type} is not yet supported for Baileys`);\n }\n }\n\n private mediaWithCaption(\n key: \"image\" | \"video\",\n media: WhatsAppMediaMessage\n ): Record<string, unknown> {\n if (!media?.link) {\n throw new Error(`${key} message requires a media link`);\n }\n return {\n [key]: { url: media.link },\n ...(media.caption ? { caption: media.caption } : {}),\n };\n }\n\n private mediaNoCaption(\n key: \"audio\",\n media: WhatsAppMediaMessage\n ): Record<string, unknown> {\n if (!media?.link) {\n throw new Error(`${key} message requires a media link`);\n }\n return { [key]: { url: media.link } };\n }\n\n private mediaWithFilename(media: WhatsAppMediaMessage): Record<string, unknown> {\n if (!media?.link) {\n throw new Error(\"document message requires a media link\");\n }\n return {\n document: { url: media.link },\n ...(media.filename ? { fileName: media.filename } : {}),\n ...(media.caption ? { caption: media.caption } : {}),\n };\n }\n\n private detectType(\n msg: proto.IWebMessageInfo\n ): \"text\" | \"image\" | \"audio\" | \"video\" | \"document\" {\n if (msg.message?.conversation || msg.message?.extendedTextMessage) {\n return \"text\";\n }\n if (msg.message?.imageMessage) {\n return \"image\";\n }\n if (msg.message?.audioMessage) {\n return \"audio\";\n }\n if (msg.message?.videoMessage) {\n return \"video\";\n }\n if (msg.message?.documentMessage) {\n return \"document\";\n }\n return \"text\";\n }\n\n private extractContent(msg: proto.IWebMessageInfo): string {\n return msg.message?.conversation ?? msg.message?.extendedTextMessage?.text ?? \"\";\n }\n\n private renderTemplate(template: WhatsAppTemplate): string {\n const params = template.components?.flatMap((component) =>\n component.parameters.map((parameter) => parameter.text).filter(Boolean)\n );\n return params && params.length > 0\n ? `${template.name}: ${params.join(\", \")}`\n : template.name;\n }\n}\n",
|
|
14
|
+
"import QRCode from \"qrcode\";\nimport QRCodeTerminal from \"qrcode-terminal\";\nimport type { QRCodeData } from \"../types\";\n\nexport class QRCodeGenerator {\n async generate(qrString: string): Promise<QRCodeData> {\n return {\n terminal: await this.generateTerminal(qrString),\n dataURL: await QRCode.toDataURL(qrString),\n raw: qrString,\n };\n }\n\n private async generateTerminal(qr: string): Promise<string> {\n return new Promise((resolve) => {\n QRCodeTerminal.generate(qr, { small: true }, (output: string) => {\n resolve(output);\n });\n });\n }\n}\n",
|
|
15
|
+
"import { WhatsAppClient } from \"../client\";\nimport type { BaileysConfig, CloudAPIConfig, WhatsAppConfig } from \"../types\";\nimport { detectAuthMethod } from \"../utils/config-detector\";\nimport { BaileysClient } from \"./baileys-client\";\nimport type { IWhatsAppClient } from \"./interface\";\n\nexport class ClientFactory {\n static create(config: WhatsAppConfig): IWhatsAppClient {\n const authMethod = detectAuthMethod(config);\n if (authMethod === \"baileys\") {\n return new BaileysClient(config as BaileysConfig);\n }\n return new WhatsAppClient(config as CloudAPIConfig);\n }\n}\n",
|
|
16
|
+
"import type { IWhatsAppClient } from \"../clients/interface\";\nimport type { WhatsAppMessage, WhatsAppMessageResponse } from \"../types\";\n\nexport class MessageHandler {\n constructor(private client: IWhatsAppClient) {}\n\n async send(message: WhatsAppMessage): Promise<WhatsAppMessageResponse> {\n try {\n const response = await this.client.sendMessage(message);\n if (response && typeof response === \"object\" && \"data\" in response) {\n return (response as { data: WhatsAppMessageResponse }).data;\n }\n return response as WhatsAppMessageResponse;\n } catch (error: unknown) {\n if (error instanceof Error) {\n throw new Error(`Failed to send WhatsApp message: ${error.message}`);\n }\n throw new Error(\"Failed to send WhatsApp message\");\n }\n }\n}\n",
|
|
17
|
+
"import type { WhatsAppIncomingMessage, WhatsAppStatusUpdate, WhatsAppWebhookEvent } from \"../types\";\n\nexport class WebhookHandler {\n async handle(event: WhatsAppWebhookEvent): Promise<void> {\n try {\n // Process messages\n if (event.entry?.[0]?.changes?.[0]?.value?.messages) {\n const messages = event.entry[0].changes[0].value.messages;\n for (const message of messages) {\n await this.handleMessage(message);\n }\n }\n\n // Process status updates\n if (event.entry?.[0]?.changes?.[0]?.value?.statuses) {\n const statuses = event.entry[0].changes[0].value.statuses;\n for (const status of statuses) {\n await this.handleStatus(status);\n }\n }\n } catch (error: unknown) {\n if (error instanceof Error) {\n throw new Error(`Failed to send WhatsApp message: ${error.message}`);\n }\n throw new Error(\"Failed to send WhatsApp message\");\n }\n }\n\n private async handleMessage(message: WhatsAppIncomingMessage): Promise<void> {\n // Implement message handling logic\n // This could emit events or trigger callbacks based on your framework's needs\n console.log(\"Received message:\", message);\n }\n\n private async handleStatus(status: WhatsAppStatusUpdate): Promise<void> {\n // Implement status update handling logic\n // This could emit events or trigger callbacks based on your framework's needs\n console.log(\"Received status update:\", status);\n }\n}\n",
|
|
18
|
+
"import type { IAgentRuntime } from \"@elizaos/core\";\nimport { checkPairingAllowed, isInAllowlist, type PairingCheckResult } from \"@elizaos/core\";\n\n/**\n * Default account identifier used when no specific account is configured\n */\nexport const DEFAULT_ACCOUNT_ID = \"default\";\n\n/**\n * Token source indicator\n */\nexport type WhatsAppTokenSource = \"config\" | \"env\" | \"character\" | \"none\";\n\n/**\n * Group-specific runtime configuration (for account resolution)\n */\nexport interface WhatsAppGroupRuntimeConfig {\n /** If false, ignore messages from this group */\n enabled?: boolean;\n /** Allowlist for users in this group */\n allowFrom?: Array<string | number>;\n /** Require bot mention to respond */\n requireMention?: boolean;\n /** Custom system prompt for this group */\n systemPrompt?: string;\n /** Skills enabled for this group */\n skills?: string[];\n}\n\n/**\n * Configuration for a single WhatsApp account (runtime resolution)\n */\nexport interface WhatsAppAccountRuntimeConfig {\n /** Optional display name for this account */\n name?: string;\n /** If false, do not start this WhatsApp account */\n enabled?: boolean;\n /** WhatsApp Cloud API access token */\n accessToken?: string;\n /** Phone number ID from WhatsApp Business */\n phoneNumberId?: string;\n /** Business account ID */\n businessAccountId?: string;\n /** Webhook verification token */\n webhookVerifyToken?: string;\n /** API version to use */\n apiVersion?: string;\n /** Allowlist for DM senders */\n allowFrom?: Array<string | number>;\n /** Allowlist for groups */\n groupAllowFrom?: Array<string | number>;\n /** DM access policy */\n dmPolicy?: \"open\" | \"allowlist\" | \"pairing\" | \"disabled\";\n /** Group message access policy */\n groupPolicy?: \"open\" | \"allowlist\" | \"disabled\";\n /** Max media size in MB */\n mediaMaxMb?: number;\n /** Text chunk limit for messages */\n textChunkLimit?: number;\n /** Group-specific configurations */\n groups?: Record<string, WhatsAppGroupRuntimeConfig>;\n}\n\n/**\n * Multi-account WhatsApp configuration structure\n */\nexport interface WhatsAppMultiAccountConfig {\n /** Default/base configuration applied to all accounts */\n enabled?: boolean;\n accessToken?: string;\n phoneNumberId?: string;\n businessAccountId?: string;\n webhookVerifyToken?: string;\n apiVersion?: string;\n dmPolicy?: \"open\" | \"allowlist\" | \"pairing\" | \"disabled\";\n groupPolicy?: \"open\" | \"allowlist\" | \"disabled\";\n mediaMaxMb?: number;\n textChunkLimit?: number;\n /** Per-account configuration overrides */\n accounts?: Record<string, WhatsAppAccountRuntimeConfig>;\n /** Group configurations at base level */\n groups?: Record<string, WhatsAppGroupRuntimeConfig>;\n}\n\n/**\n * Token resolution result\n */\nexport interface WhatsAppTokenResolution {\n token: string;\n source: WhatsAppTokenSource;\n}\n\n/**\n * Resolved WhatsApp account with all configuration merged\n */\nexport interface ResolvedWhatsAppAccount {\n accountId: string;\n enabled: boolean;\n name?: string;\n accessToken: string;\n phoneNumberId: string;\n businessAccountId?: string;\n tokenSource: WhatsAppTokenSource;\n configured: boolean;\n config: WhatsAppAccountRuntimeConfig;\n}\n\n/**\n * Normalizes an account ID, returning the default if not provided\n */\nexport function normalizeAccountId(accountId?: string | null): string {\n if (!accountId || typeof accountId !== \"string\") {\n return DEFAULT_ACCOUNT_ID;\n }\n const trimmed = accountId.trim().toLowerCase();\n if (!trimmed || trimmed === \"default\") {\n return DEFAULT_ACCOUNT_ID;\n }\n return trimmed;\n}\n\n/**\n * Gets the multi-account configuration from runtime settings\n */\nexport function getMultiAccountConfig(runtime: IAgentRuntime): WhatsAppMultiAccountConfig {\n const characterWhatsApp = runtime.character?.settings?.whatsapp as\n | WhatsAppMultiAccountConfig\n | undefined;\n\n return {\n enabled: characterWhatsApp?.enabled,\n accessToken: characterWhatsApp?.accessToken,\n phoneNumberId: characterWhatsApp?.phoneNumberId,\n businessAccountId: characterWhatsApp?.businessAccountId,\n webhookVerifyToken: characterWhatsApp?.webhookVerifyToken,\n apiVersion: characterWhatsApp?.apiVersion,\n dmPolicy: characterWhatsApp?.dmPolicy,\n groupPolicy: characterWhatsApp?.groupPolicy,\n mediaMaxMb: characterWhatsApp?.mediaMaxMb,\n textChunkLimit: characterWhatsApp?.textChunkLimit,\n accounts: characterWhatsApp?.accounts,\n groups: characterWhatsApp?.groups,\n };\n}\n\n/**\n * Lists all configured account IDs\n */\nexport function listWhatsAppAccountIds(runtime: IAgentRuntime): string[] {\n const config = getMultiAccountConfig(runtime);\n const accounts = config.accounts;\n const ids = new Set<string>();\n\n // Check if default account is configured\n const envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string | undefined;\n const envPhoneId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string | undefined;\n\n const baseConfigured = Boolean(config.accessToken?.trim() && config.phoneNumberId?.trim());\n const envConfigured = Boolean(envToken?.trim() && envPhoneId?.trim());\n\n if (baseConfigured || envConfigured) {\n ids.add(DEFAULT_ACCOUNT_ID);\n }\n\n // Add named accounts\n if (accounts && typeof accounts === \"object\") {\n for (const id of Object.keys(accounts)) {\n if (id) {\n ids.add(normalizeAccountId(id));\n }\n }\n }\n\n const result = Array.from(ids);\n if (result.length === 0) {\n return [DEFAULT_ACCOUNT_ID];\n }\n\n return result.slice().sort((a, b) => a.localeCompare(b));\n}\n\n/**\n * Resolves the default account ID to use\n */\nexport function resolveDefaultWhatsAppAccountId(runtime: IAgentRuntime): string {\n const ids = listWhatsAppAccountIds(runtime);\n if (ids.includes(DEFAULT_ACCOUNT_ID)) {\n return DEFAULT_ACCOUNT_ID;\n }\n return ids[0] ?? DEFAULT_ACCOUNT_ID;\n}\n\n/**\n * Gets the account-specific configuration\n */\nfunction getAccountConfig(\n runtime: IAgentRuntime,\n accountId: string\n): WhatsAppAccountRuntimeConfig | undefined {\n const config = getMultiAccountConfig(runtime);\n const accounts = config.accounts;\n\n if (!accounts || typeof accounts !== \"object\") {\n return undefined;\n }\n\n // Try direct match first\n const direct = accounts[accountId];\n if (direct) {\n return direct;\n }\n\n // Try normalized match\n const normalized = normalizeAccountId(accountId);\n const matchKey = Object.keys(accounts).find((key) => normalizeAccountId(key) === normalized);\n return matchKey ? accounts[matchKey] : undefined;\n}\n\n/**\n * Resolves the access token for a WhatsApp account\n */\nexport function resolveWhatsAppToken(\n runtime: IAgentRuntime,\n accountId: string\n): WhatsAppTokenResolution {\n const multiConfig = getMultiAccountConfig(runtime);\n const accountConfig = getAccountConfig(runtime, accountId);\n\n // Check account-level config first\n if (accountConfig?.accessToken?.trim()) {\n return { token: accountConfig.accessToken.trim(), source: \"config\" };\n }\n\n // For default account, check base config\n if (accountId === DEFAULT_ACCOUNT_ID) {\n if (multiConfig.accessToken?.trim()) {\n return { token: multiConfig.accessToken.trim(), source: \"config\" };\n }\n\n // Check environment/runtime settings\n const envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string | undefined;\n if (envToken?.trim()) {\n return { token: envToken.trim(), source: \"env\" };\n }\n }\n\n return { token: \"\", source: \"none\" };\n}\n\n/**\n * Merges base configuration with account-specific overrides\n */\n/**\n * Removes undefined values from an object to prevent them from overwriting during spread\n */\nfunction filterDefined<T extends object>(obj: T): Partial<T> {\n return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined)) as Partial<T>;\n}\n\nfunction mergeWhatsAppAccountConfig(\n runtime: IAgentRuntime,\n accountId: string\n): WhatsAppAccountRuntimeConfig {\n const multiConfig = getMultiAccountConfig(runtime);\n const { accounts: _ignored, ...baseConfig } = multiConfig;\n const accountConfig = getAccountConfig(runtime, accountId) ?? {};\n\n // Get environment/runtime settings for the base config\n const envToken = runtime.getSetting(\"WHATSAPP_ACCESS_TOKEN\") as string | undefined;\n const envPhoneId = runtime.getSetting(\"WHATSAPP_PHONE_NUMBER_ID\") as string | undefined;\n const envBusinessId = runtime.getSetting(\"WHATSAPP_BUSINESS_ACCOUNT_ID\") as string | undefined;\n const envWebhookToken = runtime.getSetting(\"WHATSAPP_WEBHOOK_VERIFY_TOKEN\") as string | undefined;\n const envDmPolicy = runtime.getSetting(\"WHATSAPP_DM_POLICY\") as string | undefined;\n const envGroupPolicy = runtime.getSetting(\"WHATSAPP_GROUP_POLICY\") as string | undefined;\n\n const envConfig: WhatsAppAccountRuntimeConfig = {\n accessToken: envToken || undefined,\n phoneNumberId: envPhoneId || undefined,\n businessAccountId: envBusinessId || undefined,\n webhookVerifyToken: envWebhookToken || undefined,\n dmPolicy: envDmPolicy as WhatsAppAccountRuntimeConfig[\"dmPolicy\"] | undefined,\n groupPolicy: envGroupPolicy as WhatsAppAccountRuntimeConfig[\"groupPolicy\"] | undefined,\n };\n\n // Merge order: env defaults < base config < account config\n // Filter undefined values to prevent them from overwriting defined values\n return {\n ...filterDefined(envConfig),\n ...filterDefined(baseConfig),\n ...filterDefined(accountConfig),\n };\n}\n\n/**\n * Resolves a complete WhatsApp account configuration\n */\nexport function resolveWhatsAppAccount(\n runtime: IAgentRuntime,\n accountId?: string | null\n): ResolvedWhatsAppAccount {\n const normalizedAccountId = normalizeAccountId(accountId);\n const multiConfig = getMultiAccountConfig(runtime);\n\n const baseEnabled = multiConfig.enabled !== false;\n const merged = mergeWhatsAppAccountConfig(runtime, normalizedAccountId);\n const accountEnabled = merged.enabled !== false;\n const enabled = baseEnabled && accountEnabled;\n\n const { token, source: tokenSource } = resolveWhatsAppToken(runtime, normalizedAccountId);\n const phoneNumberId = merged.phoneNumberId?.trim() || \"\";\n\n // Determine if this account is actually configured\n const configured = Boolean(token && phoneNumberId);\n\n return {\n accountId: normalizedAccountId,\n enabled,\n name: merged.name?.trim() || undefined,\n accessToken: token,\n phoneNumberId,\n businessAccountId: merged.businessAccountId?.trim() || undefined,\n tokenSource,\n configured,\n config: merged,\n };\n}\n\n/**\n * Lists all enabled WhatsApp accounts\n */\nexport function listEnabledWhatsAppAccounts(runtime: IAgentRuntime): ResolvedWhatsAppAccount[] {\n return listWhatsAppAccountIds(runtime)\n .map((accountId) => resolveWhatsAppAccount(runtime, accountId))\n .filter((account) => account.enabled && account.configured);\n}\n\n/**\n * Checks if multi-account mode is enabled\n */\nexport function isMultiAccountEnabled(runtime: IAgentRuntime): boolean {\n const accounts = listEnabledWhatsAppAccounts(runtime);\n return accounts.length > 1;\n}\n\n/**\n * Resolves group configuration for a specific group\n */\nexport function resolveWhatsAppGroupConfig(\n runtime: IAgentRuntime,\n accountId: string,\n groupId: string\n): WhatsAppGroupRuntimeConfig | undefined {\n const multiConfig = getMultiAccountConfig(runtime);\n const accountConfig = getAccountConfig(runtime, accountId);\n\n // Check account-level groups first\n const accountGroup = accountConfig?.groups?.[groupId];\n if (accountGroup) {\n return accountGroup;\n }\n\n // Fall back to base-level groups\n return multiConfig.groups?.[groupId];\n}\n\n/**\n * Checks if a user is allowed based on policy and allowlist\n */\nexport function isWhatsAppUserAllowed(params: {\n identifier: string;\n accountConfig: WhatsAppAccountRuntimeConfig;\n isGroup: boolean;\n groupId?: string;\n groupConfig?: WhatsAppGroupRuntimeConfig;\n}): boolean {\n const { identifier, accountConfig, isGroup, groupConfig } = params;\n\n if (isGroup) {\n const policy = accountConfig.groupPolicy ?? \"allowlist\";\n if (policy === \"disabled\") {\n return false;\n }\n\n if (policy === \"open\") {\n return true;\n }\n\n // Check group-specific allowlist first\n if (groupConfig?.allowFrom?.length) {\n return groupConfig.allowFrom.some((allowed) => String(allowed) === identifier);\n }\n\n // Check account-level group allowlist\n if (accountConfig.groupAllowFrom?.length) {\n return accountConfig.groupAllowFrom.some((allowed) => String(allowed) === identifier);\n }\n\n return policy !== \"allowlist\";\n }\n\n // DM handling\n const policy = accountConfig.dmPolicy ?? \"pairing\";\n if (policy === \"disabled\") {\n return false;\n }\n\n if (policy === \"open\") {\n return true;\n }\n\n if (policy === \"pairing\") {\n return true;\n }\n\n // Allowlist policy\n if (accountConfig.allowFrom?.length) {\n return accountConfig.allowFrom.some((allowed) => String(allowed) === identifier);\n }\n\n return false;\n}\n\n/**\n * Checks if mention is required in a group\n */\nexport function isWhatsAppMentionRequired(params: {\n accountConfig: WhatsAppAccountRuntimeConfig;\n groupConfig?: WhatsAppGroupRuntimeConfig;\n}): boolean {\n const { groupConfig } = params;\n return groupConfig?.requireMention ?? false;\n}\n\n/**\n * Result of an async WhatsApp access check\n */\nexport interface WhatsAppAccessCheckResult {\n /** Whether the sender is allowed to proceed */\n allowed: boolean;\n /** If not allowed (pairing policy), the pairing code */\n pairingCode?: string;\n /** Whether a new pairing request was created */\n newPairingRequest?: boolean;\n /** Human-readable message to send to the user when blocked */\n replyMessage?: string;\n}\n\n/**\n * Checks if a user is allowed based on policy and allowlist, with async pairing support.\n *\n * For non-pairing policies, this behaves identically to `isWhatsAppUserAllowed`.\n * For the \"pairing\" policy, this actually checks the PairingService allowlist\n * and creates pairing requests when needed.\n *\n * @example\n * ```typescript\n * const result = await checkWhatsAppUserAccess({\n * runtime,\n * identifier: message.from,\n * accountConfig,\n * isGroup: false,\n * metadata: { name: contact.name },\n * });\n *\n * if (!result.allowed) {\n * if (result.replyMessage) {\n * await sendMessage(result.replyMessage);\n * }\n * return; // Block message processing\n * }\n * ```\n */\nexport async function checkWhatsAppUserAccess(params: {\n runtime: IAgentRuntime;\n identifier: string;\n accountConfig: WhatsAppAccountRuntimeConfig;\n isGroup: boolean;\n groupId?: string;\n groupConfig?: WhatsAppGroupRuntimeConfig;\n metadata?: Record<string, string>;\n}): Promise<WhatsAppAccessCheckResult> {\n const { runtime, identifier, accountConfig, isGroup, groupConfig, metadata } = params;\n\n if (isGroup) {\n // Group access - same logic as synchronous version\n const policy = accountConfig.groupPolicy ?? \"allowlist\";\n if (policy === \"disabled\") {\n return { allowed: false };\n }\n\n if (policy === \"open\") {\n return { allowed: true };\n }\n\n // Check group-specific allowlist first\n if (groupConfig?.allowFrom?.length) {\n const allowed = groupConfig.allowFrom.some((a) => String(a) === identifier);\n return { allowed };\n }\n\n // Check account-level group allowlist\n if (accountConfig.groupAllowFrom?.length) {\n const allowed = accountConfig.groupAllowFrom.some((a) => String(a) === identifier);\n return { allowed };\n }\n\n return { allowed: policy !== \"allowlist\" };\n }\n\n // DM handling\n const policy = accountConfig.dmPolicy ?? \"pairing\";\n if (policy === \"disabled\") {\n return { allowed: false };\n }\n\n if (policy === \"open\") {\n return { allowed: true };\n }\n\n if (policy === \"pairing\") {\n // Use the PairingService for actual pairing workflow\n const result: PairingCheckResult = await checkPairingAllowed(runtime, {\n channel: \"whatsapp\",\n senderId: identifier,\n metadata,\n });\n\n return {\n allowed: result.allowed,\n pairingCode: result.pairingCode,\n newPairingRequest: result.newRequest,\n replyMessage: result.replyMessage,\n };\n }\n\n // Allowlist policy - check static allowlist first\n if (accountConfig.allowFrom?.length) {\n const allowed = accountConfig.allowFrom.some((a) => String(a) === identifier);\n if (allowed) {\n return { allowed: true };\n }\n }\n\n // Also check the dynamic pairing allowlist for the allowlist policy\n const inDynamicAllowlist = await isInAllowlist(runtime, \"whatsapp\", identifier);\n return { allowed: inDynamicAllowlist };\n}\n",
|
|
19
|
+
"/**\n * WhatsApp text chunk limit\n */\nexport const WHATSAPP_TEXT_CHUNK_LIMIT = 4096;\n\n/**\n * Regex for WhatsApp user JID (e.g., \"41796666864:0@s.whatsapp.net\")\n */\nconst WHATSAPP_USER_JID_RE = /^(\\d+)(?::\\d+)?@s\\.whatsapp\\.net$/i;\n\n/**\n * Regex for WhatsApp LID (e.g., \"123@lid\")\n */\nconst WHATSAPP_LID_RE = /^(\\d+)@lid$/i;\n\n/**\n * Strips WhatsApp target prefixes from a value\n */\nfunction stripWhatsAppTargetPrefixes(value: string): string {\n let candidate = value.trim();\n for (;;) {\n const before = candidate;\n candidate = candidate.replace(/^whatsapp:/i, \"\").trim();\n if (candidate === before) {\n return candidate;\n }\n }\n}\n\n/**\n * Normalizes a phone number to E.164 format\n */\nexport function normalizeE164(input: string): string {\n const stripped = input.replace(/[\\s\\-().]+/g, \"\");\n const digitsOnly = stripped.replace(/[^\\d+]/g, \"\");\n\n if (!digitsOnly) {\n return \"\";\n }\n\n // If it starts with +, keep as-is (already E.164)\n if (digitsOnly.startsWith(\"+\")) {\n return digitsOnly;\n }\n\n // If it starts with 00, replace with +\n if (digitsOnly.startsWith(\"00\")) {\n return `+${digitsOnly.slice(2)}`;\n }\n\n // Assume it's a full number without the +\n if (digitsOnly.length >= 10) {\n return `+${digitsOnly}`;\n }\n\n // Return as-is if too short\n return digitsOnly;\n}\n\n/**\n * Checks if a value is a WhatsApp group JID (e.g., \"123456789-987654321@g.us\")\n */\nexport function isWhatsAppGroupJid(value: string): boolean {\n const candidate = stripWhatsAppTargetPrefixes(value);\n const lower = candidate.toLowerCase();\n if (!lower.endsWith(\"@g.us\")) {\n return false;\n }\n const localPart = candidate.slice(0, candidate.length - \"@g.us\".length);\n if (!localPart || localPart.includes(\"@\")) {\n return false;\n }\n return /^[0-9]+(-[0-9]+)*$/.test(localPart);\n}\n\n/**\n * Checks if a value looks like a WhatsApp user target\n * (e.g., \"41796666864:0@s.whatsapp.net\" or \"123@lid\")\n */\nexport function isWhatsAppUserTarget(value: string): boolean {\n const candidate = stripWhatsAppTargetPrefixes(value);\n return WHATSAPP_USER_JID_RE.test(candidate) || WHATSAPP_LID_RE.test(candidate);\n}\n\n/**\n * Extracts the phone number from a WhatsApp user JID\n * \"41796666864:0@s.whatsapp.net\" -> \"41796666864\"\n * \"123456@lid\" -> \"123456\"\n */\nfunction extractUserJidPhone(jid: string): string | null {\n const userMatch = jid.match(WHATSAPP_USER_JID_RE);\n if (userMatch) {\n return userMatch[1];\n }\n const lidMatch = jid.match(WHATSAPP_LID_RE);\n if (lidMatch) {\n return lidMatch[1];\n }\n return null;\n}\n\n/**\n * Normalizes a WhatsApp target (phone number, user JID, or group JID)\n * Returns null if the target is invalid\n */\nexport function normalizeWhatsAppTarget(value: string): string | null {\n const candidate = stripWhatsAppTargetPrefixes(value);\n if (!candidate) {\n return null;\n }\n\n // Handle group JIDs\n if (isWhatsAppGroupJid(candidate)) {\n const localPart = candidate.slice(0, candidate.length - \"@g.us\".length);\n return `${localPart}@g.us`;\n }\n\n // Handle user JIDs (e.g., \"41796666864:0@s.whatsapp.net\")\n if (isWhatsAppUserTarget(candidate)) {\n const phone = extractUserJidPhone(candidate);\n if (!phone) {\n return null;\n }\n const normalized = normalizeE164(phone);\n return normalized.length > 1 ? normalized : null;\n }\n\n // If the caller passed a JID-ish string that we don't understand, fail fast.\n // Otherwise normalizeE164 would happily treat \"group:120@g.us\" as a phone number.\n if (candidate.includes(\"@\")) {\n return null;\n }\n\n // Treat as a phone number\n const normalized = normalizeE164(candidate);\n return normalized.length > 1 ? normalized : null;\n}\n\n/**\n * Formats a WhatsApp ID for display\n */\nexport function formatWhatsAppId(id: string): string {\n if (isWhatsAppGroupJid(id)) {\n return `group:${id}`;\n }\n const normalized = normalizeWhatsAppTarget(id);\n return normalized || id;\n}\n\n/**\n * Checks if a WhatsApp ID is a group\n */\nexport function isWhatsAppGroup(id: string): boolean {\n return isWhatsAppGroupJid(id);\n}\n\n/**\n * Gets the chat type from a WhatsApp ID\n */\nexport function getWhatsAppChatType(id: string): \"group\" | \"user\" {\n return isWhatsAppGroupJid(id) ? \"group\" : \"user\";\n}\n\n/**\n * Builds a WhatsApp JID from a phone number\n */\nexport function buildWhatsAppUserJid(phoneNumber: string): string {\n const normalized = normalizeE164(phoneNumber);\n const digits = normalized.replace(/^\\+/, \"\");\n return `${digits}@s.whatsapp.net`;\n}\n\n/**\n * Options for text chunking\n */\nexport interface ChunkWhatsAppTextOpts {\n limit?: number;\n}\n\n/**\n * Splits text at the last safe break point within the limit\n */\nfunction splitAtBreakPoint(text: string, limit: number): { chunk: string; remainder: string } {\n if (text.length <= limit) {\n return { chunk: text, remainder: \"\" };\n }\n\n const searchArea = text.slice(0, limit);\n\n // Prefer double newlines (paragraph breaks)\n const doubleNewline = searchArea.lastIndexOf(\"\\n\\n\");\n if (doubleNewline > limit * 0.5) {\n return {\n chunk: text.slice(0, doubleNewline).trimEnd(),\n remainder: text.slice(doubleNewline + 2).trimStart(),\n };\n }\n\n // Try single newlines\n const singleNewline = searchArea.lastIndexOf(\"\\n\");\n if (singleNewline > limit * 0.5) {\n return {\n chunk: text.slice(0, singleNewline).trimEnd(),\n remainder: text.slice(singleNewline + 1).trimStart(),\n };\n }\n\n // Try sentence boundaries\n const sentenceEnd = Math.max(\n searchArea.lastIndexOf(\". \"),\n searchArea.lastIndexOf(\"! \"),\n searchArea.lastIndexOf(\"? \")\n );\n if (sentenceEnd > limit * 0.5) {\n return {\n chunk: text.slice(0, sentenceEnd + 1).trimEnd(),\n remainder: text.slice(sentenceEnd + 2).trimStart(),\n };\n }\n\n // Try word boundaries\n const space = searchArea.lastIndexOf(\" \");\n if (space > limit * 0.5) {\n return {\n chunk: text.slice(0, space).trimEnd(),\n remainder: text.slice(space + 1).trimStart(),\n };\n }\n\n // Hard break at limit\n return {\n chunk: text.slice(0, limit),\n remainder: text.slice(limit),\n };\n}\n\n/**\n * Chunks text for WhatsApp messages\n */\nexport function chunkWhatsAppText(text: string, opts: ChunkWhatsAppTextOpts = {}): string[] {\n const limit = opts.limit ?? WHATSAPP_TEXT_CHUNK_LIMIT;\n\n if (!text?.trim()) {\n return [];\n }\n\n const normalizedText = text.trim();\n if (normalizedText.length <= limit) {\n return [normalizedText];\n }\n\n const chunks: string[] = [];\n let remaining = normalizedText;\n\n while (remaining.length > 0) {\n const { chunk, remainder } = splitAtBreakPoint(remaining, limit);\n if (chunk) {\n chunks.push(chunk);\n }\n remaining = remainder;\n }\n\n return chunks.filter((c) => c.length > 0);\n}\n\n/**\n * Truncates text to a maximum length with ellipsis\n */\nexport function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n if (maxLength <= 3) {\n return \"...\".slice(0, maxLength);\n }\n return `${text.slice(0, maxLength - 3)}...`;\n}\n\n/**\n * Resolves the system location string for logging\n */\nexport function resolveWhatsAppSystemLocation(params: {\n chatType: \"group\" | \"user\";\n chatId: string;\n chatName?: string;\n}): string {\n const { chatType, chatId, chatName } = params;\n const name = chatName || chatId.slice(0, 8);\n return `WhatsApp ${chatType}:${name}`;\n}\n\n/**\n * Validates a WhatsApp phone number\n */\nexport function isValidWhatsAppNumber(value: string): boolean {\n const normalized = normalizeWhatsAppTarget(value);\n if (!normalized) {\n return false;\n }\n // Must be E.164 format with at least 10 digits\n if (!normalized.startsWith(\"+\")) {\n return false;\n }\n const digits = normalized.replace(/^\\+/, \"\");\n return /^\\d{10,15}$/.test(digits);\n}\n\n/**\n * Formats a phone number for WhatsApp display\n */\nexport function formatWhatsAppPhoneNumber(phoneNumber: string): string {\n const normalized = normalizeE164(phoneNumber);\n if (!normalized) {\n return phoneNumber;\n }\n // Format as +XX XXX XXX XXXX for display\n const digits = normalized.replace(/^\\+/, \"\");\n if (digits.length <= 10) {\n return normalized;\n }\n // Simple formatting: country code + rest\n const countryCode = digits.slice(0, digits.length - 10);\n const rest = digits.slice(-10);\n return `+${countryCode} ${rest.slice(0, 3)} ${rest.slice(3, 6)} ${rest.slice(6)}`;\n}\n",
|
|
20
|
+
"export type WhatsAppConfig = CloudAPIConfig | BaileysConfig;\n\nexport interface CloudAPIConfig {\n authMethod?: \"cloudapi\";\n accessToken: string;\n phoneNumberId: string;\n webhookVerifyToken?: string;\n businessAccountId?: string;\n apiVersion?: string;\n}\n\nexport interface BaileysConfig {\n authMethod?: \"baileys\";\n authDir: string;\n printQRInTerminal?: boolean;\n sessionPath?: string;\n}\n\n/**\n * Message types supported by WhatsApp Cloud API.\n */\nexport type WhatsAppMessageType =\n | \"text\"\n | \"template\"\n | \"image\"\n | \"audio\"\n | \"video\"\n | \"document\"\n | \"sticker\"\n | \"location\"\n | \"contacts\"\n | \"interactive\"\n | \"reaction\";\n\nexport interface WhatsAppMessage {\n type: WhatsAppMessageType;\n to: string;\n content:\n | string\n | WhatsAppTemplate\n | WhatsAppMediaMessage\n | WhatsAppInteractiveMessage\n | WhatsAppReactionMessage\n | WhatsAppLocationMessage;\n replyToMessageId?: string;\n}\n\nexport interface WhatsAppTemplate {\n name: string;\n language: {\n code: string;\n };\n components?: Array<{\n type: string;\n parameters: Array<{\n type: string;\n text?: string;\n image?: { link: string };\n document?: { link: string; filename?: string };\n video?: { link: string };\n }>;\n }>;\n}\n\n/**\n * Media message content.\n */\nexport interface WhatsAppMediaMessage {\n link?: string;\n id?: string;\n caption?: string;\n filename?: string;\n mimeType?: string;\n}\n\n/**\n * Reaction message content.\n */\nexport interface WhatsAppReactionMessage {\n messageId: string;\n emoji: string;\n}\n\n/**\n * Location message content.\n */\nexport interface WhatsAppLocationMessage {\n latitude: number;\n longitude: number;\n name?: string;\n address?: string;\n}\n\n/**\n * Interactive message types.\n */\nexport type InteractiveMessageType = \"button\" | \"list\" | \"product\" | \"product_list\" | \"flow\";\n\n/**\n * Interactive message content.\n */\nexport interface WhatsAppInteractiveMessage {\n type: InteractiveMessageType;\n header?: {\n type: \"text\" | \"image\" | \"video\" | \"document\";\n text?: string;\n image?: { link: string };\n video?: { link: string };\n document?: { link: string; filename?: string };\n };\n body: {\n text: string;\n };\n footer?: {\n text: string;\n };\n action: WhatsAppInteractiveAction;\n}\n\n/**\n * Interactive action based on message type.\n */\nexport type WhatsAppInteractiveAction =\n | WhatsAppButtonAction\n | WhatsAppListAction\n | WhatsAppFlowAction;\n\n/**\n * Button action for interactive messages.\n */\nexport interface WhatsAppButtonAction {\n buttons: Array<{\n type: \"reply\";\n reply: {\n id: string;\n title: string;\n };\n }>;\n}\n\n/**\n * List action for interactive messages.\n */\nexport interface WhatsAppListAction {\n button: string;\n sections: Array<{\n title?: string;\n rows: Array<{\n id: string;\n title: string;\n description?: string;\n }>;\n }>;\n}\n\n/**\n * Flow action for interactive messages.\n */\nexport interface WhatsAppFlowAction {\n name: \"flow\";\n parameters: {\n flow_message_version: string;\n flow_token: string;\n flow_id: string;\n flow_cta: string;\n flow_action: \"navigate\" | \"data_exchange\";\n flow_action_payload?: {\n screen: string;\n data?: Record<string, unknown>;\n };\n };\n}\n\nexport interface WhatsAppIncomingMessage {\n from: string;\n id: string;\n timestamp: string;\n text?: {\n body: string;\n };\n image?: {\n caption?: string;\n mime_type: string;\n sha256: string;\n id: string;\n };\n video?: {\n caption?: string;\n mime_type: string;\n sha256: string;\n id: string;\n };\n audio?: {\n mime_type: string;\n sha256: string;\n id: string;\n voice?: boolean;\n };\n document?: {\n caption?: string;\n filename: string;\n mime_type: string;\n sha256: string;\n id: string;\n };\n sticker?: {\n mime_type: string;\n sha256: string;\n id: string;\n animated?: boolean;\n };\n location?: {\n latitude: number;\n longitude: number;\n name?: string;\n address?: string;\n };\n contacts?: Array<{\n name: {\n formatted_name: string;\n first_name?: string;\n last_name?: string;\n };\n phones?: Array<{\n phone: string;\n type: string;\n }>;\n }>;\n interactive?: {\n type: \"button_reply\" | \"list_reply\" | \"nfm_reply\";\n button_reply?: {\n id: string;\n title: string;\n };\n list_reply?: {\n id: string;\n title: string;\n description?: string;\n };\n nfm_reply?: {\n response_json: string;\n body: string;\n name: string;\n };\n };\n reaction?: {\n message_id: string;\n emoji: string;\n };\n context?: {\n from: string;\n id: string;\n referred_product?: {\n catalog_id: string;\n product_retailer_id: string;\n };\n };\n type: string;\n}\n\nexport interface WhatsAppStatusUpdate {\n id: string;\n status: \"sent\" | \"delivered\" | \"read\" | \"failed\";\n timestamp: string;\n recipient_id: string;\n conversation?: {\n id: string;\n origin?: {\n type: string;\n };\n expiration_timestamp?: string;\n };\n pricing?: {\n billable: boolean;\n pricing_model: string;\n category: string;\n };\n errors?: Array<{\n code: number;\n title: string;\n message?: string;\n error_data?: {\n details: string;\n };\n }>;\n}\n\nexport interface WhatsAppWebhookEvent {\n object: string;\n entry: Array<{\n id: string;\n changes: Array<{\n value: {\n messaging_product: string;\n metadata: {\n display_phone_number: string;\n phone_number_id: string;\n };\n statuses?: WhatsAppStatusUpdate[];\n messages?: WhatsAppIncomingMessage[];\n contacts?: Array<{\n profile: {\n name: string;\n };\n wa_id: string;\n }>;\n errors?: Array<{\n code: number;\n title: string;\n message?: string;\n error_data?: {\n details: string;\n };\n }>;\n };\n field: string;\n }>;\n }>;\n}\n\nexport interface WhatsAppMessageResponse {\n messaging_product: string;\n contacts: Array<{\n input: string;\n wa_id: string;\n }>;\n messages: Array<{\n id: string;\n message_status?: string;\n }>;\n}\n\nexport interface QRCodeData {\n terminal: string;\n dataURL: string;\n raw: string;\n}\n\nexport type ConnectionStatus = \"connecting\" | \"open\" | \"close\";\n\nexport interface UnifiedMessage {\n id: string;\n from: string;\n timestamp: number;\n type: \"text\" | \"image\" | \"audio\" | \"video\" | \"document\";\n content: string;\n}\n\n/**\n * Send reaction parameters.\n */\nexport interface SendReactionParams {\n to: string;\n messageId: string;\n emoji: string;\n}\n\n/**\n * Send reaction result.\n */\nexport interface SendReactionResult {\n success: boolean;\n messageId?: string;\n error?: string;\n}\n\n/**\n * WhatsApp event types.\n */\nexport enum WhatsAppEventType {\n MESSAGE_RECEIVED = \"WHATSAPP_MESSAGE_RECEIVED\",\n MESSAGE_SENT = \"WHATSAPP_MESSAGE_SENT\",\n MESSAGE_DELIVERED = \"WHATSAPP_MESSAGE_DELIVERED\",\n MESSAGE_READ = \"WHATSAPP_MESSAGE_READ\",\n MESSAGE_FAILED = \"WHATSAPP_MESSAGE_FAILED\",\n REACTION_RECEIVED = \"WHATSAPP_REACTION_RECEIVED\",\n REACTION_SENT = \"WHATSAPP_REACTION_SENT\",\n INTERACTIVE_REPLY = \"WHATSAPP_INTERACTIVE_REPLY\",\n WEBHOOK_VERIFIED = \"WHATSAPP_WEBHOOK_VERIFIED\",\n}\n\n/**\n * Common WhatsApp reaction emojis.\n */\nexport const WHATSAPP_REACTIONS = {\n THUMBS_UP: \"👍\",\n THUMBS_DOWN: \"👎\",\n HEART: \"❤️\",\n LAUGHING: \"😂\",\n SURPRISED: \"😮\",\n SAD: \"😢\",\n PRAYING: \"🙏\",\n CLAPPING: \"👏\",\n FIRE: \"🔥\",\n CELEBRATION: \"🎉\",\n} as const;\n\nexport type WhatsAppReactionEmoji = (typeof WHATSAPP_REACTIONS)[keyof typeof WHATSAPP_REACTIONS];\n"
|
|
21
|
+
],
|
|
22
|
+
"mappings": ";AAAA,yBAAS;;;ACUT;AAEO,IAAM,+BAA+B;AAE5C,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBvB,IAAM,oBAA4B;AAAA,EACvC,MAAM;AAAA,EACN,SAAS,CAAC,iBAAiB,oBAAoB,iBAAiB,uBAAuB;AAAA,EACvF,aAAa;AAAA,EAEP,UAAU,OAAO,SAAc,SAAc,OAAa,YAAoC;AAAA,IACjG,MAAM,cAAc,OAAO,SAAS,SAAS,SAAS,WAAW,QAAQ,QAAQ,OAAO;AAAA,IACxF,MAAM,WAAW,YAAY,YAAY;AAAA,IACzC,MAAM,eAAe,CAAC,YAAY,QAAQ,SAAS;AAAA,IACnD,MAAM,gBACL,aAAa,SAAS,KACtB,aAAa,KAAK,CAAC,OAAO,GAAG,SAAS,KAAK,SAAS,SAAS,EAAE,CAAC;AAAA,IACjE,MAAM,YAAY,IAAI,OAAO,mCAAmC,GAAG;AAAA,IACnE,MAAM,cAAc,UAAU,KAAK,QAAQ;AAAA,IAC3C,MAAM,aAAa,OAAO,SAAS,SAAS,UAAU,SAAS,UAAU,EAAE;AAAA,IAC3E,MAAM,qBAAqB;AAAA,IAC3B,MAAM,eAAe,qBAClB,eAAe,qBACf,QAAQ,cAAc,SAAS,SAAS,WAAW,SAAS,UAAU;AAAA,IACzE,MAAM,cAAc,WAAW,OAAO,YAAY,WAAW,UAAU,CAAC;AAAA,IACxE,MAAM,cACL,SAAS,KAAK,EAAE,SAAS,KACzB,OAAO,KAAK,WAAsC,EAAE,SAAS,KAC7D,QAAQ,SAAS,WAAW,OAAO,QAAQ,YAAY,QAAQ;AAAA,IAEhE,IAAI,EAAE,iBAAiB,eAAe,gBAAgB,cAAc;AAAA,MACnE,OAAO;AAAA,IACR;AAAA,IAEA,MAAM,qBAAqB,OAAO,UAAyB,aAAsC;AAAA,MAClG,MAAM,SAAS,SAAQ,SAAS;AAAA,MAChC,OAAO,WAAW;AAAA;AAAA,IAEjB,IAAI;AAAA,MACH,OAAO,QAAQ,MAAO,mBAA2B,SAAS,SAAS,OAAO,OAAO,CAAC;AAAA,MACjF,MAAM;AAAA,MACP,OAAO;AAAA;AAAA;AAAA,EAIX,SAAS,OACP,SACA,SACA,OACA,UACA,aAC0B;AAAA,IAE1B,MAAM,cAAc,QAAQ,WAAW,uBAAuB;AAAA,IAC9D,MAAM,gBAAgB,QAAQ,WAAW,0BAA0B;AAAA,IACnE,MAAM,aAAc,QAAQ,WAAW,sBAAsB,KAAgB;AAAA,IAE7E,IAAI,CAAC,eAAe,CAAC,eAAe;AAAA,MAClC,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,IAC5D;AAAA,IAEA,MAAM,eAAe,SAAU,MAAM,QAAQ,aAAa,OAAO;AAAA,IAGjE,MAAM,SAAS,uBAAuB;AAAA,MACpC,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AAAA,IAED,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,QAAQ,SAAS,UAAU,YAAY;AAAA,QAC5D;AAAA,MACF,CAAC;AAAA,MAED,MAAM,SAAS,wBAAwB,QAAQ;AAAA,MAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,MAAM,CAAC,OAAO,MAAM;AAAA,QAEzC,MAAM,KAAK,QAAQ,SAAS;AAAA,QAC5B,MAAM,OAAO,aAAa,QAAQ,UAAU,SAAS,KAAK;AAAA,QAE1D,IAAI,CAAC,IAAI;AAAA,UACP,IAAI,UAAU;AAAA,YACZ,MAAM,SAAS;AAAA,cACb,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,UACA,OAAO,EAAE,SAAS,OAAO,OAAO,oBAAoB;AAAA,QACtD;AAAA,QAGA,IAAI,CAAC,QAAQ,KAAK,KAAK,MAAM,IAAI;AAAA,UAC/B,IAAI,UAAU;AAAA,YACZ,MAAM,SAAS;AAAA,cACb,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,UACA,OAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB;AAAA,QACvD;AAAA,QAEA,SAAS,EAAE,IAAI,KAAK;AAAA,MACtB,EAAO;AAAA,QAEL,IAAI,CAAC,OAAO,KAAK,KAAK,GAAG;AAAA,UACvB,IAAI,UAAU;AAAA,YACZ,MAAM,SAAS;AAAA,cACb,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,UACA,OAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB;AAAA,QACvD;AAAA,QACA,SAAS;AAAA;AAAA,MAEX,MAAM;AAAA,MACN,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,OAAO,qCAAqC;AAAA;AAAA,IAIvE,IAAI;AAAA,MACF,MAAM,MAAM,8BAA8B,cAAc;AAAA,MAExD,MAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,eAAe,UAAU;AAAA,UACzB,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,mBAAmB;AAAA,UACnB,gBAAgB;AAAA,UAChB,IAAI,OAAO;AAAA,UACX,MAAM;AAAA,UACN,MAAM;AAAA,YACJ,aAAa;AAAA,YACb,MAAM,OAAO;AAAA,UACf;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,MAED,IAAI,CAAC,SAAS,IAAI;AAAA,QAChB,MAAM,YAAY,MAAM,SAAS,KAAK;AAAA,QACtC,MAAM,IAAI,MAAM,UAAU,OAAO,WAAW,QAAQ,SAAS,QAAQ;AAAA,MACvE;AAAA,MAEA,MAAM,OAAQ,MAAM,SAAS,KAAK;AAAA,MAClC,MAAM,YAAY,KAAK,WAAW,IAAI;AAAA,MAEtC,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM,mBAAmB,OAAO;AAAA,UAChC,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,MAEA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,IAAI,OAAO;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC1E,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM,oCAAoC;AAAA,QAC5C,CAAC;AAAA,MACH;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,OAAO,aAAa;AAAA;AAAA;AAAA,EAIjD,UAAU;AAAA,IACR;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS,CAAC,4BAA4B;AAAA,QACxC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;AC9NA,mCAAS,sCAAwB,uCAAW;AAErC,IAAM,gCAAgC;AAE7C,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBnB,IAAM,qBAA6B;AAAA,EACxC,MAAM;AAAA,EACN,SAAS,CAAC,kBAAkB,kBAAkB,gBAAgB;AAAA,EAC9D,aAAa;AAAA,EAEP,UAAU,OAAO,SAAc,SAAc,OAAa,YAAoC;AAAA,IACjG,MAAM,cAAc,OAAO,SAAS,SAAS,SAAS,WAAW,QAAQ,QAAQ,OAAO;AAAA,IACxF,MAAM,WAAW,YAAY,YAAY;AAAA,IACzC,MAAM,eAAe,CAAC,YAAY,QAAQ,UAAU;AAAA,IACpD,MAAM,gBACL,aAAa,SAAS,KACtB,aAAa,KAAK,CAAC,OAAO,GAAG,SAAS,KAAK,SAAS,SAAS,EAAE,CAAC;AAAA,IACjE,MAAM,YAAY,IAAI,OAAO,oCAAoC,GAAG;AAAA,IACpE,MAAM,cAAc,UAAU,KAAK,QAAQ;AAAA,IAC3C,MAAM,aAAa,OAAO,SAAS,SAAS,UAAU,SAAS,UAAU,EAAE;AAAA,IAC3E,MAAM,qBAAqB;AAAA,IAC3B,MAAM,eAAe,qBAClB,eAAe,qBACf,QAAQ,cAAc,SAAS,SAAS,WAAW,SAAS,UAAU;AAAA,IACzE,MAAM,cAAc,WAAW,OAAO,YAAY,WAAW,UAAU,CAAC;AAAA,IACxE,MAAM,cACL,SAAS,KAAK,EAAE,SAAS,KACzB,OAAO,KAAK,WAAsC,EAAE,SAAS,KAC7D,QAAQ,SAAS,WAAW,OAAO,QAAQ,YAAY,QAAQ;AAAA,IAEhE,IAAI,EAAE,iBAAiB,eAAe,gBAAgB,cAAc;AAAA,MACnE,OAAO;AAAA,IACR;AAAA,IAEA,MAAM,qBAAqB,OAAO,UAAyB,aAAsC;AAAA,MAClG,MAAM,SAAS,SAAQ,SAAS;AAAA,MAChC,OAAO,WAAW;AAAA;AAAA,IAEjB,IAAI;AAAA,MACH,OAAO,QAAQ,MAAO,mBAA2B,SAAS,SAAS,OAAO,OAAO,CAAC;AAAA,MACjF,MAAM;AAAA,MACP,OAAO;AAAA;AAAA;AAAA,EAIX,SAAS,OACP,SACA,SACA,OACA,UACA,aAC0B;AAAA,IAE1B,MAAM,cAAc,QAAQ,WAAW,uBAAuB;AAAA,IAC9D,MAAM,gBAAgB,QAAQ,WAAW,0BAA0B;AAAA,IACnE,MAAM,aAAc,QAAQ,WAAW,sBAAsB,KAAgB;AAAA,IAE7E,IAAI,CAAC,eAAe,CAAC,eAAe;AAAA,MAClC,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,OAAO,0BAA0B;AAAA,IAC5D;AAAA,IAEA,MAAM,eAAe,SAAU,MAAM,QAAQ,aAAa,OAAO;AAAA,IAGjE,MAAM,SAAS,wBAAuB;AAAA,MACpC,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AAAA,IAED,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,QAAQ,SAAS,WAAU,YAAY;AAAA,QAC5D;AAAA,MACF,CAAC;AAAA,MAED,MAAM,SAAS,yBAAwB,QAAQ;AAAA,MAC/C,IAAI,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,OAAO,OAAO;AAAA,QAEjD,MAAM,YAAY,QAAQ,SAAS;AAAA,QACnC,IAAI,CAAC,WAAW;AAAA,UACd,IAAI,UAAU;AAAA,YACZ,MAAM,SAAS;AAAA,cACb,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AAAA,UACA,OAAO,EAAE,SAAS,OAAO,OAAO,qBAAqB;AAAA,QACvD;AAAA,QACA,SAAS,EAAE,WAAW,OAAO,eAAI;AAAA,MACnC,EAAO;AAAA,QACL,SAAS;AAAA;AAAA,MAEX,MAAM;AAAA,MACN,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,OAAO,sCAAsC;AAAA;AAAA,IAIxE,MAAM,KAAK,QAAQ,SAAS;AAAA,IAC5B,IAAI,CAAC,IAAI;AAAA,MACP,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,OAAO,oBAAoB;AAAA,IACtD;AAAA,IAGA,IAAI;AAAA,MACF,MAAM,MAAM,8BAA8B,cAAc;AAAA,MAExD,MAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,eAAe,UAAU;AAAA,UACzB,gBAAgB;AAAA,QAClB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,mBAAmB;AAAA,UACnB,gBAAgB;AAAA,UAChB;AAAA,UACA,MAAM;AAAA,UACN,UAAU;AAAA,YACR,YAAY,OAAO;AAAA,YACnB,OAAO,OAAO;AAAA,UAChB;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,MAED,IAAI,CAAC,SAAS,IAAI;AAAA,QAChB,MAAM,YAAY,MAAM,SAAS,KAAK;AAAA,QACtC,MAAM,IAAI,MAAM,UAAU,OAAO,WAAW,QAAQ,SAAS,QAAQ;AAAA,MACvE;AAAA,MAEA,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM,gBAAgB,OAAO;AAAA,UAC7B,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,MAEA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,WAAW,OAAO;AAAA,UAClB,OAAO,OAAO;AAAA,QAChB;AAAA,MACF;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC1E,IAAI,UAAU;AAAA,QACZ,MAAM,SAAS;AAAA,UACb,MAAM,4BAA4B;AAAA,QACpC,CAAC;AAAA,MACH;AAAA,MACA,OAAO,EAAE,SAAS,OAAO,OAAO,aAAa;AAAA;AAAA;AAAA,EAIjD,UAAU;AAAA,IACR;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS,CAAC,6BAA6B;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;AC1NA;AACA;AAeA,IAAM,sBAAsB;AAAA;AAErB,MAAM,uBAAuB,aAAwC;AAAA,EAClE;AAAA,EACA;AAAA,EACA,mBAAqC;AAAA,EAE7C,WAAW,CAAC,QAAwB;AAAA,IAClC,MAAM;AAAA,IACN,KAAK,SAAS;AAAA,IACd,MAAM,aAAa,OAAO,cAAc;AAAA,IAExC,KAAK,SAAS,MAAM,OAAO;AAAA,MACzB,SAAS,8BAA8B;AAAA,MACvC,SAAS;AAAA,QACP,eAAe,UAAU,OAAO;AAAA,QAChC,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC;AAAA;AAAA,OAGG,MAAK,GAAkB;AAAA,IAC3B,KAAK,mBAAmB;AAAA,IACxB,KAAK,KAAK,cAAc,MAAM;AAAA,IAC9B,KAAK,KAAK,OAAO;AAAA;AAAA,OAGb,KAAI,GAAkB;AAAA,IAC1B,KAAK,mBAAmB;AAAA,IACxB,KAAK,KAAK,cAAc,OAAO;AAAA;AAAA,EAGjC,mBAAmB,GAAqB;AAAA,IACtC,OAAO,KAAK;AAAA;AAAA,EAMd,gBAAgB,GAAW;AAAA,IACzB,OAAO,KAAK,OAAO;AAAA;AAAA,OAMf,YAAW,CAAC,SAA2E;AAAA,IAC3F,MAAM,WAAW,IAAI,KAAK,OAAO;AAAA,IACjC,MAAM,UAAU,KAAK,oBAAoB,OAAO;AAAA,IAChD,OAAO,KAAK,OAAO,KAAK,UAAU,OAAO;AAAA;AAAA,OAMrC,gBAAe,CACnB,IACA,MACA,cAAc,OACmC;AAAA,IACjD,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA;AAAA,OAMG,aAAY,CAAC,QAAyD;AAAA,IAC1E,MAAM,WAAW,IAAI,KAAK,OAAO;AAAA,IAEjC,MAAM,UAAU;AAAA,MACd,mBAAmB;AAAA,MACnB,gBAAgB;AAAA,MAChB,IAAI,OAAO;AAAA,MACX,MAAM;AAAA,MACN,UAAU;AAAA,QACR,YAAY,OAAO;AAAA,QACnB,OAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,KAAK,OAAO,KAA8B,UAAU,OAAO;AAAA,MAClF,OAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW,SAAS,KAAK,WAAW,IAAI;AAAA,MAC1C;AAAA,MACA,OAAO,OAAO;AAAA,MACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC1E,OAAO;AAAA,QACL,SAAS;AAAA,QACT,OAAO;AAAA,MACT;AAAA;AAAA;AAAA,OAOE,eAAc,CAAC,IAAY,WAAgD;AAAA,IAC/E,OAAO,KAAK,aAAa;AAAA,MACvB;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT,CAAC;AAAA;AAAA,OAMG,UAAS,CACb,IACA,UACA,SACiD;AAAA,IACjD,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,QACN;AAAA,MACF;AAAA,IACF,CAAC;AAAA;AAAA,OAMG,UAAS,CACb,IACA,UACA,SACiD;AAAA,IACjD,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,QACN;AAAA,MACF;AAAA,IACF,CAAC;AAAA;AAAA,OAMG,UAAS,CAAC,IAAY,UAAmE;AAAA,IAC7F,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAAA;AAAA,OAMG,aAAY,CAChB,IACA,aACA,UACA,SACiD;AAAA,IACjD,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA;AAAA,OAMG,aAAY,CAChB,IACA,UACA,WACA,MACA,SACiD;AAAA,IACjD,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA;AAAA,OAMG,kBAAiB,CACrB,IACA,UACA,SACA,YACA,YACiD;AAAA,IACjD,MAAM,cAA0C;AAAA,MAC9C,MAAM;AAAA,MACN,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,QAAQ;AAAA,QACN,SAAS,QAAQ,IAAI,CAAC,SAAS;AAAA,UAC7B,MAAM;AAAA,UACN,OAAO,EAAE,IAAI,IAAI,IAAI,OAAO,IAAI,MAAM;AAAA,QACxC,EAAE;AAAA,MACJ;AAAA,IACF;AAAA,IAEA,IAAI,YAAY;AAAA,MACd,YAAY,SAAS,EAAE,MAAM,QAAQ,MAAM,WAAW;AAAA,IACxD;AAAA,IACA,IAAI,YAAY;AAAA,MACd,YAAY,SAAS,EAAE,MAAM,WAAW;AAAA,IAC1C;AAAA,IAEA,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA;AAAA,OAMG,gBAAe,CACnB,IACA,UACA,YACA,UAIA,YACA,YACiD;AAAA,IACjD,MAAM,cAA0C;AAAA,MAC9C,MAAM;AAAA,MACN,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,QAAQ;AAAA,QACN,QAAQ;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,IAEA,IAAI,YAAY;AAAA,MACd,YAAY,SAAS,EAAE,MAAM,QAAQ,MAAM,WAAW;AAAA,IACxD;AAAA,IACA,IAAI,YAAY;AAAA,MACd,YAAY,SAAS,EAAE,MAAM,WAAW;AAAA,IAC1C;AAAA,IAEA,OAAO,KAAK,YAAY;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,IACX,CAAC;AAAA;AAAA,OAMG,kBAAiB,CAAC,WAAqC;AAAA,IAC3D,MAAM,WAAW,IAAI,KAAK,OAAO;AAAA,IAEjC,MAAM,UAAU;AAAA,MACd,mBAAmB;AAAA,MACnB,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,IAEA,IAAI;AAAA,MACF,MAAM,KAAK,OAAO,KAAK,UAAU,OAAO;AAAA,MACxC,OAAO;AAAA,MACP,MAAM;AAAA,MACN,OAAO;AAAA;AAAA;AAAA,OAOL,YAAW,CAAC,SAAyC;AAAA,IACzD,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,KAAK,OAAO,IAAI,IAAI,SAAS;AAAA,MACpD,OAAO,SAAS,KAAK,OAAO;AAAA,MAC5B,MAAM;AAAA,MACN,OAAO;AAAA;AAAA;AAAA,OAOL,cAAa,CAAC,OAAiC;AAAA,IACnD,OAAO,UAAU,KAAK,OAAO;AAAA;AAAA,EAMvB,mBAAmB,CAAC,SAAmD;AAAA,IAC7E,MAAM,cAAc;AAAA,MAClB,mBAAmB;AAAA,MACnB,gBAAgB;AAAA,MAChB,IAAI,QAAQ;AAAA,MACZ,MAAM,QAAQ;AAAA,IAChB;AAAA,IAGA,MAAM,iBAAiB,QAAQ,mBAC3B,EAAE,SAAS,EAAE,YAAY,QAAQ,iBAAiB,EAAE,IACpD,CAAC;AAAA,IAEL,QAAQ,QAAQ;AAAA,WACT;AAAA,QACH,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,MAAM;AAAA,YACJ,MAAM,QAAQ;AAAA,UAChB;AAAA,QACF;AAAA,WAEG;AAAA,QACH,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,UAAU,QAAQ;AAAA,QACpB;AAAA,WAEG,SAAS;AAAA,QACZ,MAAM,eAAe,QAAQ;AAAA,QAC7B,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,OAAO;AAAA,YACL,MAAM,aAAa;AAAA,YACnB,SAAS,aAAa;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,WAEK,SAAS;AAAA,QACZ,MAAM,eAAe,QAAQ;AAAA,QAC7B,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,OAAO;AAAA,YACL,MAAM,aAAa;AAAA,YACnB,SAAS,aAAa;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,WAEK,SAAS;AAAA,QACZ,MAAM,eAAe,QAAQ;AAAA,QAC7B,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,OAAO;AAAA,YACL,MAAM,aAAa;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,WAEK,YAAY;AAAA,QACf,MAAM,aAAa,QAAQ;AAAA,QAC3B,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,UAAU;AAAA,YACR,MAAM,WAAW;AAAA,YACjB,UAAU,WAAW;AAAA,YACrB,SAAS,WAAW;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,WAEK,YAAY;AAAA,QACf,MAAM,aAAa,QAAQ;AAAA,QAC3B,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,UAAU;AAAA,YACR,UAAU,WAAW;AAAA,YACrB,WAAW,WAAW;AAAA,YACtB,MAAM,WAAW;AAAA,YACjB,SAAS,WAAW;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,WAEK,YAAY;AAAA,QACf,MAAM,kBAAkB,QAAQ;AAAA,QAChC,OAAO;AAAA,aACF;AAAA,UACH,UAAU;AAAA,YACR,YAAY,gBAAgB;AAAA,YAC5B,OAAO,gBAAgB;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,WAEK,eAAe;AAAA,QAClB,MAAM,qBAAqB,QAAQ;AAAA,QACnC,OAAO;AAAA,aACF;AAAA,aACA;AAAA,UACH,aAAa;AAAA,QACf;AAAA,MACF;AAAA;AAAA,QAGE,OAAO;AAAA;AAAA;AAGf;;;AC7bO,SAAS,gBAAgB,CAAC,QAA0E;AAAA,EACzG,MAAM,iBAAkB,OAAoC;AAAA,EAC5D,IAAI,mBAAmB,WAAW;AAAA,IAChC,IAAI,mBAAmB,aAAa,mBAAmB,YAAY;AAAA,MACjE,OAAO;AAAA,IACT;AAAA,IACA,MAAM,IAAI,MACR,wBAAwB,OAAO,cAAc,6CAC/C;AAAA,EACF;AAAA,EAEA,IAAI,aAAa,UAAU,OAAO,SAAS;AAAA,IACzC,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,iBAAiB,UAAU,mBAAmB,QAAQ;AAAA,IACxD,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,MACR,yGACF;AAAA;;;ACvBF,yBAAS;;;ACAT;AAAA;AAGO,MAAM,mBAAmB;AAAA,EACb;AAAA,EACT;AAAA,EACA;AAAA,EAER,WAAW,CAAC,SAAiB;AAAA,IAC3B,KAAK,UAAU;AAAA;AAAA,OAGX,WAAU,GAAiC;AAAA,IAC/C,MAAM,SAAS,MAAM,sBAAsB,KAAK,OAAO;AAAA,IACvD,KAAK,QAAQ,OAAO;AAAA,IACpB,KAAK,YAAY,OAAO;AAAA,IACxB,OAAO,KAAK;AAAA;AAAA,OAGR,KAAI,GAAkB;AAAA,IAC1B,IAAI,KAAK,WAAW;AAAA,MAClB,MAAM,KAAK,UAAU;AAAA,IACvB;AAAA;AAEJ;;;ACxBA;AAEA,yBAAS;AACT;AAAA;AAIO,MAAM,0BAA0B,cAAa;AAAA,EAC1C;AAAA,EACS;AAAA,EACT,mBAAqC;AAAA,EACrC,eAAe;AAAA,EACf,oBAAoB;AAAA,EACX,uBAAuB;AAAA,EAExC,WAAW,CAAC,aAAiC;AAAA,IAC3C,MAAM;AAAA,IACN,KAAK,cAAc;AAAA;AAAA,OAGf,QAAO,GAAsB;AAAA,IACjC,KAAK,mBAAmB;AAAA,IACxB,KAAK,KAAK,cAAc,YAAY;AAAA,IAEpC,MAAM,QAAQ,MAAM,KAAK,YAAY,WAAW;AAAA,IAChD,KAAK,SAAS,aAAa;AAAA,MACzB,MAAM;AAAA,MACN,mBAAmB;AAAA,MACnB,QAAQ,KAAK,EAAE,OAAO,SAAS,CAAC;AAAA,MAChC,SAAS,CAAC,kBAAkB,IAAI,EAAE;AAAA,IACpC,CAAC;AAAA,IAED,KAAK,mBAAmB;AAAA,IACxB,OAAO,KAAK;AAAA;AAAA,EAGN,kBAAkB,GAAS;AAAA,IACjC,IAAI,CAAC,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AAAA,IAEA,KAAK,OAAO,GAAG,GAAG,qBAAqB,OAAO,WAAW;AAAA,MACvD,QAAQ,YAAY,IAAI,mBAAmB;AAAA,MAE3C,IAAI,IAAI;AAAA,QACN,KAAK,KAAK,MAAM,EAAE;AAAA,MACpB;AAAA,MAEA,IAAI,YAAY;AAAA,QACd,KAAK,mBAAmB;AAAA,QACxB,KAAK,KAAK,cAAc,UAAU;AAAA,MACpC;AAAA,MAEA,IAAI,eAAe,QAAQ;AAAA,QACzB,KAAK,oBAAoB;AAAA,QACzB;AAAA,MACF;AAAA,MAEA,IAAI,eAAe,SAAS;AAAA,QAC1B;AAAA,MACF;AAAA,MAEA,MAAM,aAAc,gBAAgB,OAA4B,QAAQ;AAAA,MACxE,MAAM,cAAc,eAAe;AAAA,MACnC,MAAM,kBAAkB,eAAe,iBAAiB,aAAa,eAAe;AAAA,MAEpF,IAAI,gBAAgB,SAAS,CAAC,aAAa;AAAA,QACzC,KAAK,KAAK,SAAS,eAAe,KAAK;AAAA,MACzC;AAAA,MAEA,IAAI,CAAC,iBAAiB;AAAA,QACpB;AAAA,MACF;AAAA,MAEA,IAAI,KAAK,cAAc;AAAA,QACrB;AAAA,MACF;AAAA,MAEA,IAAI,KAAK,qBAAqB,KAAK,sBAAsB;AAAA,QACvD,KAAK,KAAK,SAAS,IAAI,MAAM,mCAAmC,CAAC;AAAA,QACjE;AAAA,MACF;AAAA,MAEA,KAAK,eAAe;AAAA,MACpB,IAAI;AAAA,QACF,KAAK,qBAAqB;AAAA,QAC1B,MAAM,cAAc,cAAc,OAAO;AAAA,QACzC,MAAM,YAAY,KAAK,IACrB,cAAc,KAAK,IAAI,GAAG,KAAK,oBAAoB,CAAC,GACpD,KACF;AAAA,QACA,MAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,SAAS,CAAC;AAAA,QAC7D,MAAM,KAAK,QAAQ;AAAA,QACnB,OAAO,OAAO;AAAA,QACd,KAAK,KAAK,SAAS,KAAK;AAAA,gBACxB;AAAA,QACA,KAAK,eAAe;AAAA;AAAA,KAEvB;AAAA,IAED,KAAK,OAAO,GAAG,GAAG,gBAAgB,YAAY;AAAA,MAC5C,MAAM,KAAK,YAAY,KAAK;AAAA,KAC7B;AAAA,IAED,KAAK,OAAO,GAAG,GAAG,mBAAmB,GAAG,eAAe;AAAA,MACrD,KAAK,KAAK,YAAY,QAAQ;AAAA,KAC/B;AAAA;AAAA,EAGH,SAAS,GAAyB;AAAA,IAChC,OAAO,KAAK;AAAA;AAAA,EAGd,SAAS,GAAqB;AAAA,IAC5B,OAAO,KAAK;AAAA;AAAA,OAGR,WAAU,GAAkB;AAAA,IAChC,IAAI,CAAC,KAAK,QAAQ;AAAA,MAChB;AAAA,IACF;AAAA,IAGE,KAAK,OAAO,GAGZ,mBAAmB;AAAA,IACpB,KAAK,OAAsD,IAAI,QAAQ;AAAA,IACxE,KAAK,SAAS;AAAA,IACd,KAAK,mBAAmB;AAAA,IACxB,KAAK,KAAK,cAAc,OAAO;AAAA;AAEnC;;;AC5HO,MAAM,eAAe;AAAA,EAC1B,SAAS,CAAC,KAA4C;AAAA,IACpD,OAAO;AAAA,MACL,IAAI,IAAI,KAAK,MAAM;AAAA,MACnB,MAAM,IAAI,KAAK,aAAa;AAAA,MAC5B,WAAW,OAAO,IAAI,oBAAoB,CAAC;AAAA,MAC3C,MAAM,KAAK,WAAW,GAAG;AAAA,MACzB,SAAS,KAAK,eAAe,GAAG;AAAA,IAClC;AAAA;AAAA,EAGF,SAAS,CAAC,KAA+C;AAAA,IACvD,QAAQ,IAAI;AAAA,WACL;AAAA,QACH,OAAO,EAAE,MAAM,IAAI,QAAkB;AAAA,WAClC;AAAA,QACH,OAAO,KAAK,iBAAiB,SAAS,IAAI,OAA+B;AAAA,WACtE;AAAA,QACH,OAAO,KAAK,iBAAiB,SAAS,IAAI,OAA+B;AAAA,WACtE;AAAA,QACH,OAAO,KAAK,eAAe,SAAS,IAAI,OAA+B;AAAA,WACpE;AAAA,QACH,OAAO,KAAK,kBAAkB,IAAI,OAA+B;AAAA,WAC9D;AAAA,QACH,OAAO,EAAE,MAAM,KAAK,eAAe,IAAI,OAA2B,EAAE;AAAA;AAAA,QAEpE,MAAM,IAAI,MAAM,gBAAgB,IAAI,uCAAuC;AAAA;AAAA;AAAA,EAIzE,gBAAgB,CACtB,KACA,OACyB;AAAA,IACzB,IAAI,CAAC,OAAO,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM,GAAG,mCAAmC;AAAA,IACxD;AAAA,IACA,OAAO;AAAA,OACJ,MAAM,EAAE,KAAK,MAAM,KAAK;AAAA,SACrB,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IACpD;AAAA;AAAA,EAGM,cAAc,CACpB,KACA,OACyB;AAAA,IACzB,IAAI,CAAC,OAAO,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM,GAAG,mCAAmC;AAAA,IACxD;AAAA,IACA,OAAO,GAAG,MAAM,EAAE,KAAK,MAAM,KAAK,EAAE;AAAA;AAAA,EAG9B,iBAAiB,CAAC,OAAsD;AAAA,IAC9E,IAAI,CAAC,OAAO,MAAM;AAAA,MAChB,MAAM,IAAI,MAAM,wCAAwC;AAAA,IAC1D;AAAA,IACA,OAAO;AAAA,MACL,UAAU,EAAE,KAAK,MAAM,KAAK;AAAA,SACxB,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,SACjD,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,IACpD;AAAA;AAAA,EAGM,UAAU,CAChB,KACmD;AAAA,IACnD,IAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,qBAAqB;AAAA,MACjE,OAAO;AAAA,IACT;AAAA,IACA,IAAI,IAAI,SAAS,cAAc;AAAA,MAC7B,OAAO;AAAA,IACT;AAAA,IACA,IAAI,IAAI,SAAS,cAAc;AAAA,MAC7B,OAAO;AAAA,IACT;AAAA,IACA,IAAI,IAAI,SAAS,cAAc;AAAA,MAC7B,OAAO;AAAA,IACT;AAAA,IACA,IAAI,IAAI,SAAS,iBAAiB;AAAA,MAChC,OAAO;AAAA,IACT;AAAA,IACA,OAAO;AAAA;AAAA,EAGD,cAAc,CAAC,KAAoC;AAAA,IACzD,OAAO,IAAI,SAAS,gBAAgB,IAAI,SAAS,qBAAqB,QAAQ;AAAA;AAAA,EAGxE,cAAc,CAAC,UAAoC;AAAA,IACzD,MAAM,SAAS,SAAS,YAAY,QAAQ,CAAC,cAC3C,UAAU,WAAW,IAAI,CAAC,cAAc,UAAU,IAAI,EAAE,OAAO,OAAO,CACxE;AAAA,IACA,OAAO,UAAU,OAAO,SAAS,IAC7B,GAAG,SAAS,SAAS,OAAO,KAAK,IAAI,MACrC,SAAS;AAAA;AAEjB;;;ACzGA;AACA;AAAA;AAGO,MAAM,gBAAgB;AAAA,OACrB,SAAQ,CAAC,UAAuC;AAAA,IACpD,OAAO;AAAA,MACL,UAAU,MAAM,KAAK,iBAAiB,QAAQ;AAAA,MAC9C,SAAS,MAAM,OAAO,UAAU,QAAQ;AAAA,MACxC,KAAK;AAAA,IACP;AAAA;AAAA,OAGY,iBAAgB,CAAC,IAA6B;AAAA,IAC1D,OAAO,IAAI,QAAQ,CAAC,YAAY;AAAA,MAC9B,eAAe,SAAS,IAAI,EAAE,OAAO,KAAK,GAAG,CAAC,WAAmB;AAAA,QAC/D,QAAQ,MAAM;AAAA,OACf;AAAA,KACF;AAAA;AAEL;;;AJZO,MAAM,sBAAsB,cAAwC;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,WAAW,CAAC,QAAuB;AAAA,IACjC,MAAM;AAAA,IACN,KAAK,SAAS;AAAA,IACd,KAAK,cAAc,IAAI,mBAAmB,OAAO,OAAO;AAAA,IACxD,KAAK,aAAa,IAAI,kBAAkB,KAAK,WAAW;AAAA,IACxD,KAAK,cAAc,IAAI;AAAA,IACvB,KAAK,UAAU,IAAI;AAAA,IACnB,KAAK,qBAAqB;AAAA;AAAA,EAGpB,oBAAoB,GAAS;AAAA,IACnC,KAAK,WAAW,GAAG,MAAM,OAAO,OAAe;AAAA,MAC7C,IAAI;AAAA,QACF,MAAM,SAAS,MAAM,KAAK,YAAY,SAAS,EAAE;AAAA,QACjD,IAAI,KAAK,OAAO,sBAAsB,OAAO;AAAA,UAC3C,QAAQ,IAAI;AAAA;AAAA,CAA0B;AAAA,UACtC,QAAQ,IAAI,OAAO,QAAQ;AAAA,QAC7B;AAAA,QACA,KAAK,KAAK,MAAM,MAAM;AAAA,QACtB,OAAO,OAAO;AAAA,QACd,KAAK,KAAK,SAAS,KAAK;AAAA;AAAA,KAE3B;AAAA,IAED,KAAK,WAAW,GAAG,cAAc,CAAC,WAA6B;AAAA,MAC7D,KAAK,KAAK,cAAc,MAAM;AAAA,MAC9B,IAAI,WAAW,QAAQ;AAAA,QACrB,KAAK,KAAK,OAAO;AAAA,MACnB;AAAA,KACD;AAAA,IAED,KAAK,WAAW,GAAG,YAAY,CAAC,aAAwB;AAAA,MACtD,WAAW,WAAW,UAAU;AAAA,QAC9B,MAAM,QAAQ;AAAA,QACd,IAAI,CAAC,MAAM,KAAK,UAAU,MAAM,SAAS;AAAA,UACvC,KAAK,KAAK,WAAW,KAAK,QAAQ,UAAU,OAAc,CAAC;AAAA,QAC7D;AAAA,MACF;AAAA,KACD;AAAA,IAED,KAAK,WAAW,GAAG,SAAS,CAAC,UAAmB;AAAA,MAC9C,KAAK,KAAK,SAAS,KAAK;AAAA,KACzB;AAAA;AAAA,OAGG,MAAK,GAAkB;AAAA,IAC3B,MAAM,KAAK,WAAW,QAAQ;AAAA;AAAA,OAG1B,KAAI,GAAkB;AAAA,IAC1B,MAAM,KAAK,WAAW,WAAW;AAAA;AAAA,OAG7B,YAAW,CAAC,SAA4D;AAAA,IAC5E,MAAM,SAAS,KAAK,WAAW,UAAU;AAAA,IACzC,IAAI,CAAC,QAAQ;AAAA,MACX,MAAM,IAAI,MAAM,uCAAuC;AAAA,IACzD;AAAA,IAEA,MAAM,UAAU,KAAK,QAAQ,UAAU,OAAO;AAAA,IAC9C,MAAM,SAAS,MAAM,OAAO,YAAY,QAAQ,IAAI,OAAc;AAAA,IAClE,MAAM,KAAK,QAAQ,KAAK,MAAM;AAAA,IAE9B,OAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,UAAU,CAAC,EAAE,OAAO,QAAQ,IAAI,OAAO,QAAQ,GAAG,CAAC;AAAA,MACnD,UAAU,CAAC,EAAE,GAAG,CAAC;AAAA,IACnB;AAAA;AAAA,EAGF,mBAAmB,GAAqB;AAAA,IACtC,OAAO,KAAK,WAAW,UAAU;AAAA;AAErC;;;AKlFO,MAAM,cAAc;AAAA,SAClB,MAAM,CAAC,QAAyC;AAAA,IACrD,MAAM,aAAa,iBAAiB,MAAM;AAAA,IAC1C,IAAI,eAAe,WAAW;AAAA,MAC5B,OAAO,IAAI,cAAc,MAAuB;AAAA,IAClD;AAAA,IACA,OAAO,IAAI,eAAe,MAAwB;AAAA;AAEtD;;;ACXO,MAAM,eAAe;AAAA,EACN;AAAA,EAApB,WAAW,CAAS,QAAyB;AAAA,IAAzB;AAAA;AAAA,OAEd,KAAI,CAAC,SAA4D;AAAA,IACrE,IAAI;AAAA,MACF,MAAM,WAAW,MAAM,KAAK,OAAO,YAAY,OAAO;AAAA,MACtD,IAAI,YAAY,OAAO,aAAa,YAAY,UAAU,UAAU;AAAA,QAClE,OAAQ,SAA+C;AAAA,MACzD;AAAA,MACA,OAAO;AAAA,MACP,OAAO,OAAgB;AAAA,MACvB,IAAI,iBAAiB,OAAO;AAAA,QAC1B,MAAM,IAAI,MAAM,oCAAoC,MAAM,SAAS;AAAA,MACrE;AAAA,MACA,MAAM,IAAI,MAAM,iCAAiC;AAAA;AAAA;AAGvD;;AClBO,MAAM,eAAe;AAAA,OACpB,OAAM,CAAC,OAA4C;AAAA,IACvD,IAAI;AAAA,MAEF,IAAI,MAAM,QAAQ,IAAI,UAAU,IAAI,OAAO,UAAU;AAAA,QACnD,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,GAAG,MAAM;AAAA,QACjD,WAAW,WAAW,UAAU;AAAA,UAC9B,MAAM,KAAK,cAAc,OAAO;AAAA,QAClC;AAAA,MACF;AAAA,MAGA,IAAI,MAAM,QAAQ,IAAI,UAAU,IAAI,OAAO,UAAU;AAAA,QACnD,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,GAAG,MAAM;AAAA,QACjD,WAAW,UAAU,UAAU;AAAA,UAC7B,MAAM,KAAK,aAAa,MAAM;AAAA,QAChC;AAAA,MACF;AAAA,MACA,OAAO,OAAgB;AAAA,MACvB,IAAI,iBAAiB,OAAO;AAAA,QAC1B,MAAM,IAAI,MAAM,oCAAoC,MAAM,SAAS;AAAA,MACrE;AAAA,MACA,MAAM,IAAI,MAAM,iCAAiC;AAAA;AAAA;AAAA,OAIvC,cAAa,CAAC,SAAiD;AAAA,IAG3E,QAAQ,IAAI,qBAAqB,OAAO;AAAA;AAAA,OAG5B,aAAY,CAAC,QAA6C;AAAA,IAGtE,QAAQ,IAAI,2BAA2B,MAAM;AAAA;AAEjD;;ACtCA;AAKO,IAAM,qBAAqB;AAwG3B,SAAS,kBAAkB,CAAC,WAAmC;AAAA,EACpE,IAAI,CAAC,aAAa,OAAO,cAAc,UAAU;AAAA,IAC/C,OAAO;AAAA,EACT;AAAA,EACA,MAAM,UAAU,UAAU,KAAK,EAAE,YAAY;AAAA,EAC7C,IAAI,CAAC,WAAW,YAAY,WAAW;AAAA,IACrC,OAAO;AAAA,EACT;AAAA,EACA,OAAO;AAAA;AAMF,SAAS,qBAAqB,CAAC,SAAoD;AAAA,EACxF,MAAM,oBAAoB,QAAQ,WAAW,UAAU;AAAA,EAIvD,OAAO;AAAA,IACL,SAAS,mBAAmB;AAAA,IAC5B,aAAa,mBAAmB;AAAA,IAChC,eAAe,mBAAmB;AAAA,IAClC,mBAAmB,mBAAmB;AAAA,IACtC,oBAAoB,mBAAmB;AAAA,IACvC,YAAY,mBAAmB;AAAA,IAC/B,UAAU,mBAAmB;AAAA,IAC7B,aAAa,mBAAmB;AAAA,IAChC,YAAY,mBAAmB;AAAA,IAC/B,gBAAgB,mBAAmB;AAAA,IACnC,UAAU,mBAAmB;AAAA,IAC7B,QAAQ,mBAAmB;AAAA,EAC7B;AAAA;AAMK,SAAS,sBAAsB,CAAC,SAAkC;AAAA,EACvE,MAAM,SAAS,sBAAsB,OAAO;AAAA,EAC5C,MAAM,WAAW,OAAO;AAAA,EACxB,MAAM,MAAM,IAAI;AAAA,EAGhB,MAAM,WAAW,QAAQ,WAAW,uBAAuB;AAAA,EAC3D,MAAM,aAAa,QAAQ,WAAW,0BAA0B;AAAA,EAEhE,MAAM,iBAAiB,QAAQ,OAAO,aAAa,KAAK,KAAK,OAAO,eAAe,KAAK,CAAC;AAAA,EACzF,MAAM,gBAAgB,QAAQ,UAAU,KAAK,KAAK,YAAY,KAAK,CAAC;AAAA,EAEpE,IAAI,kBAAkB,eAAe;AAAA,IACnC,IAAI,IAAI,kBAAkB;AAAA,EAC5B;AAAA,EAGA,IAAI,YAAY,OAAO,aAAa,UAAU;AAAA,IAC5C,WAAW,MAAM,OAAO,KAAK,QAAQ,GAAG;AAAA,MACtC,IAAI,IAAI;AAAA,QACN,IAAI,IAAI,mBAAmB,EAAE,CAAC;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,MAAM,KAAK,GAAG;AAAA,EAC7B,IAAI,OAAO,WAAW,GAAG;AAAA,IACvB,OAAO,CAAC,kBAAkB;AAAA,EAC5B;AAAA,EAEA,OAAO,OAAO,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,CAAC,CAAC;AAAA;AAMlD,SAAS,+BAA+B,CAAC,SAAgC;AAAA,EAC9E,MAAM,MAAM,uBAAuB,OAAO;AAAA,EAC1C,IAAI,IAAI,SAAS,kBAAkB,GAAG;AAAA,IACpC,OAAO;AAAA,EACT;AAAA,EACA,OAAO,IAAI,MAAM;AAAA;AAMnB,SAAS,gBAAgB,CACvB,SACA,WAC0C;AAAA,EAC1C,MAAM,SAAS,sBAAsB,OAAO;AAAA,EAC5C,MAAM,WAAW,OAAO;AAAA,EAExB,IAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAAA,IAC7C;AAAA,EACF;AAAA,EAGA,MAAM,SAAS,SAAS;AAAA,EACxB,IAAI,QAAQ;AAAA,IACV,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,aAAa,mBAAmB,SAAS;AAAA,EAC/C,MAAM,WAAW,OAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,QAAQ,mBAAmB,GAAG,MAAM,UAAU;AAAA,EAC3F,OAAO,WAAW,SAAS,YAAY;AAAA;AAMlC,SAAS,oBAAoB,CAClC,SACA,WACyB;AAAA,EACzB,MAAM,cAAc,sBAAsB,OAAO;AAAA,EACjD,MAAM,gBAAgB,iBAAiB,SAAS,SAAS;AAAA,EAGzD,IAAI,eAAe,aAAa,KAAK,GAAG;AAAA,IACtC,OAAO,EAAE,OAAO,cAAc,YAAY,KAAK,GAAG,QAAQ,SAAS;AAAA,EACrE;AAAA,EAGA,IAAI,cAAc,oBAAoB;AAAA,IACpC,IAAI,YAAY,aAAa,KAAK,GAAG;AAAA,MACnC,OAAO,EAAE,OAAO,YAAY,YAAY,KAAK,GAAG,QAAQ,SAAS;AAAA,IACnE;AAAA,IAGA,MAAM,WAAW,QAAQ,WAAW,uBAAuB;AAAA,IAC3D,IAAI,UAAU,KAAK,GAAG;AAAA,MACpB,OAAO,EAAE,OAAO,SAAS,KAAK,GAAG,QAAQ,MAAM;AAAA,IACjD;AAAA,EACF;AAAA,EAEA,OAAO,EAAE,OAAO,IAAI,QAAQ,OAAO;AAAA;AASrC,SAAS,aAA+B,CAAC,KAAoB;AAAA,EAC3D,OAAO,OAAO,YAAY,OAAO,QAAQ,GAAG,EAAE,OAAO,IAAI,OAAO,MAAM,SAAS,CAAC;AAAA;AAGlF,SAAS,0BAA0B,CACjC,SACA,WAC8B;AAAA,EAC9B,MAAM,cAAc,sBAAsB,OAAO;AAAA,EACjD,QAAQ,UAAU,aAAa,eAAe;AAAA,EAC9C,MAAM,gBAAgB,iBAAiB,SAAS,SAAS,KAAK,CAAC;AAAA,EAG/D,MAAM,WAAW,QAAQ,WAAW,uBAAuB;AAAA,EAC3D,MAAM,aAAa,QAAQ,WAAW,0BAA0B;AAAA,EAChE,MAAM,gBAAgB,QAAQ,WAAW,8BAA8B;AAAA,EACvE,MAAM,kBAAkB,QAAQ,WAAW,+BAA+B;AAAA,EAC1E,MAAM,cAAc,QAAQ,WAAW,oBAAoB;AAAA,EAC3D,MAAM,iBAAiB,QAAQ,WAAW,uBAAuB;AAAA,EAEjE,MAAM,YAA0C;AAAA,IAC9C,aAAa,YAAY;AAAA,IACzB,eAAe,cAAc;AAAA,IAC7B,mBAAmB,iBAAiB;AAAA,IACpC,oBAAoB,mBAAmB;AAAA,IACvC,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EAIA,OAAO;AAAA,OACF,cAAc,SAAS;AAAA,OACvB,cAAc,UAAU;AAAA,OACxB,cAAc,aAAa;AAAA,EAChC;AAAA;AAMK,SAAS,sBAAsB,CACpC,SACA,WACyB;AAAA,EACzB,MAAM,sBAAsB,mBAAmB,SAAS;AAAA,EACxD,MAAM,cAAc,sBAAsB,OAAO;AAAA,EAEjD,MAAM,cAAc,YAAY,YAAY;AAAA,EAC5C,MAAM,SAAS,2BAA2B,SAAS,mBAAmB;AAAA,EACtE,MAAM,iBAAiB,OAAO,YAAY;AAAA,EAC1C,MAAM,UAAU,eAAe;AAAA,EAE/B,QAAQ,OAAO,QAAQ,gBAAgB,qBAAqB,SAAS,mBAAmB;AAAA,EACxF,MAAM,gBAAgB,OAAO,eAAe,KAAK,KAAK;AAAA,EAGtD,MAAM,aAAa,QAAQ,SAAS,aAAa;AAAA,EAEjD,OAAO;AAAA,IACL,WAAW;AAAA,IACX;AAAA,IACA,MAAM,OAAO,MAAM,KAAK,KAAK;AAAA,IAC7B,aAAa;AAAA,IACb;AAAA,IACA,mBAAmB,OAAO,mBAAmB,KAAK,KAAK;AAAA,IACvD;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,EACV;AAAA;AAMK,SAAS,2BAA2B,CAAC,SAAmD;AAAA,EAC7F,OAAO,uBAAuB,OAAO,EAClC,IAAI,CAAC,cAAc,uBAAuB,SAAS,SAAS,CAAC,EAC7D,OAAO,CAAC,YAAY,QAAQ,WAAW,QAAQ,UAAU;AAAA;AAMvD,SAAS,qBAAqB,CAAC,SAAiC;AAAA,EACrE,MAAM,WAAW,4BAA4B,OAAO;AAAA,EACpD,OAAO,SAAS,SAAS;AAAA;AAMpB,SAAS,0BAA0B,CACxC,SACA,WACA,SACwC;AAAA,EACxC,MAAM,cAAc,sBAAsB,OAAO;AAAA,EACjD,MAAM,gBAAgB,iBAAiB,SAAS,SAAS;AAAA,EAGzD,MAAM,eAAe,eAAe,SAAS;AAAA,EAC7C,IAAI,cAAc;AAAA,IAChB,OAAO;AAAA,EACT;AAAA,EAGA,OAAO,YAAY,SAAS;AAAA;AAMvB,SAAS,qBAAqB,CAAC,QAM1B;AAAA,EACV,QAAQ,YAAY,eAAe,SAAS,gBAAgB;AAAA,EAE5D,IAAI,SAAS;AAAA,IACX,MAAM,UAAS,cAAc,eAAe;AAAA,IAC5C,IAAI,YAAW,YAAY;AAAA,MACzB,OAAO;AAAA,IACT;AAAA,IAEA,IAAI,YAAW,QAAQ;AAAA,MACrB,OAAO;AAAA,IACT;AAAA,IAGA,IAAI,aAAa,WAAW,QAAQ;AAAA,MAClC,OAAO,YAAY,UAAU,KAAK,CAAC,YAAY,OAAO,OAAO,MAAM,UAAU;AAAA,IAC/E;AAAA,IAGA,IAAI,cAAc,gBAAgB,QAAQ;AAAA,MACxC,OAAO,cAAc,eAAe,KAAK,CAAC,YAAY,OAAO,OAAO,MAAM,UAAU;AAAA,IACtF;AAAA,IAEA,OAAO,YAAW;AAAA,EACpB;AAAA,EAGA,MAAM,SAAS,cAAc,YAAY;AAAA,EACzC,IAAI,WAAW,YAAY;AAAA,IACzB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,WAAW,QAAQ;AAAA,IACrB,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,WAAW,WAAW;AAAA,IACxB,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,cAAc,WAAW,QAAQ;AAAA,IACnC,OAAO,cAAc,UAAU,KAAK,CAAC,YAAY,OAAO,OAAO,MAAM,UAAU;AAAA,EACjF;AAAA,EAEA,OAAO;AAAA;AAMF,SAAS,yBAAyB,CAAC,QAG9B;AAAA,EACV,QAAQ,gBAAgB;AAAA,EACxB,OAAO,aAAa,kBAAkB;AAAA;AA0CxC,eAAsB,uBAAuB,CAAC,QAQP;AAAA,EACrC,QAAQ,SAAS,YAAY,eAAe,SAAS,aAAa,aAAa;AAAA,EAE/E,IAAI,SAAS;AAAA,IAEX,MAAM,UAAS,cAAc,eAAe;AAAA,IAC5C,IAAI,YAAW,YAAY;AAAA,MACzB,OAAO,EAAE,SAAS,MAAM;AAAA,IAC1B;AAAA,IAEA,IAAI,YAAW,QAAQ;AAAA,MACrB,OAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAAA,IAGA,IAAI,aAAa,WAAW,QAAQ;AAAA,MAClC,MAAM,UAAU,YAAY,UAAU,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,UAAU;AAAA,MAC1E,OAAO,EAAE,QAAQ;AAAA,IACnB;AAAA,IAGA,IAAI,cAAc,gBAAgB,QAAQ;AAAA,MACxC,MAAM,UAAU,cAAc,eAAe,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,UAAU;AAAA,MACjF,OAAO,EAAE,QAAQ;AAAA,IACnB;AAAA,IAEA,OAAO,EAAE,SAAS,YAAW,YAAY;AAAA,EAC3C;AAAA,EAGA,MAAM,SAAS,cAAc,YAAY;AAAA,EACzC,IAAI,WAAW,YAAY;AAAA,IACzB,OAAO,EAAE,SAAS,MAAM;AAAA,EAC1B;AAAA,EAEA,IAAI,WAAW,QAAQ;AAAA,IACrB,OAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AAAA,EAEA,IAAI,WAAW,WAAW;AAAA,IAExB,MAAM,SAA6B,MAAM,oBAAoB,SAAS;AAAA,MACpE,SAAS;AAAA,MACT,UAAU;AAAA,MACV;AAAA,IACF,CAAC;AAAA,IAED,OAAO;AAAA,MACL,SAAS,OAAO;AAAA,MAChB,aAAa,OAAO;AAAA,MACpB,mBAAmB,OAAO;AAAA,MAC1B,cAAc,OAAO;AAAA,IACvB;AAAA,EACF;AAAA,EAGA,IAAI,cAAc,WAAW,QAAQ;AAAA,IACnC,MAAM,UAAU,cAAc,UAAU,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,UAAU;AAAA,IAC5E,IAAI,SAAS;AAAA,MACX,OAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAAA,EACF;AAAA,EAGA,MAAM,qBAAqB,MAAM,cAAc,SAAS,YAAY,UAAU;AAAA,EAC9E,OAAO,EAAE,SAAS,mBAAmB;AAAA;;AC9hBhC,IAAM,4BAA4B;AAKzC,IAAM,uBAAuB;AAK7B,IAAM,kBAAkB;AAKxB,SAAS,2BAA2B,CAAC,OAAuB;AAAA,EAC1D,IAAI,YAAY,MAAM,KAAK;AAAA,EAC3B,UAAS;AAAA,IACP,MAAM,SAAS;AAAA,IACf,YAAY,UAAU,QAAQ,eAAe,EAAE,EAAE,KAAK;AAAA,IACtD,IAAI,cAAc,QAAQ;AAAA,MACxB,OAAO;AAAA,IACT;AAAA,EACF;AAAA;AAMK,SAAS,aAAa,CAAC,OAAuB;AAAA,EACnD,MAAM,WAAW,MAAM,QAAQ,eAAe,EAAE;AAAA,EAChD,MAAM,aAAa,SAAS,QAAQ,WAAW,EAAE;AAAA,EAEjD,IAAI,CAAC,YAAY;AAAA,IACf,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,WAAW,WAAW,GAAG,GAAG;AAAA,IAC9B,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,WAAW,WAAW,IAAI,GAAG;AAAA,IAC/B,OAAO,IAAI,WAAW,MAAM,CAAC;AAAA,EAC/B;AAAA,EAGA,IAAI,WAAW,UAAU,IAAI;AAAA,IAC3B,OAAO,IAAI;AAAA,EACb;AAAA,EAGA,OAAO;AAAA;AAMF,SAAS,kBAAkB,CAAC,OAAwB;AAAA,EACzD,MAAM,YAAY,4BAA4B,KAAK;AAAA,EACnD,MAAM,QAAQ,UAAU,YAAY;AAAA,EACpC,IAAI,CAAC,MAAM,SAAS,OAAO,GAAG;AAAA,IAC5B,OAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY,UAAU,MAAM,GAAG,UAAU,SAAS,QAAQ,MAAM;AAAA,EACtE,IAAI,CAAC,aAAa,UAAU,SAAS,GAAG,GAAG;AAAA,IACzC,OAAO;AAAA,EACT;AAAA,EACA,OAAO,qBAAqB,KAAK,SAAS;AAAA;AAOrC,SAAS,oBAAoB,CAAC,OAAwB;AAAA,EAC3D,MAAM,YAAY,4BAA4B,KAAK;AAAA,EACnD,OAAO,qBAAqB,KAAK,SAAS,KAAK,gBAAgB,KAAK,SAAS;AAAA;AAQ/E,SAAS,mBAAmB,CAAC,KAA4B;AAAA,EACvD,MAAM,YAAY,IAAI,MAAM,oBAAoB;AAAA,EAChD,IAAI,WAAW;AAAA,IACb,OAAO,UAAU;AAAA,EACnB;AAAA,EACA,MAAM,WAAW,IAAI,MAAM,eAAe;AAAA,EAC1C,IAAI,UAAU;AAAA,IACZ,OAAO,SAAS;AAAA,EAClB;AAAA,EACA,OAAO;AAAA;AAOF,SAAS,uBAAuB,CAAC,OAA8B;AAAA,EACpE,MAAM,YAAY,4BAA4B,KAAK;AAAA,EACnD,IAAI,CAAC,WAAW;AAAA,IACd,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,mBAAmB,SAAS,GAAG;AAAA,IACjC,MAAM,YAAY,UAAU,MAAM,GAAG,UAAU,SAAS,QAAQ,MAAM;AAAA,IACtE,OAAO,GAAG;AAAA,EACZ;AAAA,EAGA,IAAI,qBAAqB,SAAS,GAAG;AAAA,IACnC,MAAM,QAAQ,oBAAoB,SAAS;AAAA,IAC3C,IAAI,CAAC,OAAO;AAAA,MACV,OAAO;AAAA,IACT;AAAA,IACA,MAAM,cAAa,cAAc,KAAK;AAAA,IACtC,OAAO,YAAW,SAAS,IAAI,cAAa;AAAA,EAC9C;AAAA,EAIA,IAAI,UAAU,SAAS,GAAG,GAAG;AAAA,IAC3B,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,aAAa,cAAc,SAAS;AAAA,EAC1C,OAAO,WAAW,SAAS,IAAI,aAAa;AAAA;AAMvC,SAAS,gBAAgB,CAAC,IAAoB;AAAA,EACnD,IAAI,mBAAmB,EAAE,GAAG;AAAA,IAC1B,OAAO,SAAS;AAAA,EAClB;AAAA,EACA,MAAM,aAAa,wBAAwB,EAAE;AAAA,EAC7C,OAAO,cAAc;AAAA;AAMhB,SAAS,eAAe,CAAC,IAAqB;AAAA,EACnD,OAAO,mBAAmB,EAAE;AAAA;AAMvB,SAAS,mBAAmB,CAAC,IAA8B;AAAA,EAChE,OAAO,mBAAmB,EAAE,IAAI,UAAU;AAAA;AAMrC,SAAS,oBAAoB,CAAC,aAA6B;AAAA,EAChE,MAAM,aAAa,cAAc,WAAW;AAAA,EAC5C,MAAM,SAAS,WAAW,QAAQ,OAAO,EAAE;AAAA,EAC3C,OAAO,GAAG;AAAA;AAaZ,SAAS,iBAAiB,CAAC,MAAc,OAAqD;AAAA,EAC5F,IAAI,KAAK,UAAU,OAAO;AAAA,IACxB,OAAO,EAAE,OAAO,MAAM,WAAW,GAAG;AAAA,EACtC;AAAA,EAEA,MAAM,aAAa,KAAK,MAAM,GAAG,KAAK;AAAA,EAGtC,MAAM,gBAAgB,WAAW,YAAY;AAAA;AAAA,CAAM;AAAA,EACnD,IAAI,gBAAgB,QAAQ,KAAK;AAAA,IAC/B,OAAO;AAAA,MACL,OAAO,KAAK,MAAM,GAAG,aAAa,EAAE,QAAQ;AAAA,MAC5C,WAAW,KAAK,MAAM,gBAAgB,CAAC,EAAE,UAAU;AAAA,IACrD;AAAA,EACF;AAAA,EAGA,MAAM,gBAAgB,WAAW,YAAY;AAAA,CAAI;AAAA,EACjD,IAAI,gBAAgB,QAAQ,KAAK;AAAA,IAC/B,OAAO;AAAA,MACL,OAAO,KAAK,MAAM,GAAG,aAAa,EAAE,QAAQ;AAAA,MAC5C,WAAW,KAAK,MAAM,gBAAgB,CAAC,EAAE,UAAU;AAAA,IACrD;AAAA,EACF;AAAA,EAGA,MAAM,cAAc,KAAK,IACvB,WAAW,YAAY,IAAI,GAC3B,WAAW,YAAY,IAAI,GAC3B,WAAW,YAAY,IAAI,CAC7B;AAAA,EACA,IAAI,cAAc,QAAQ,KAAK;AAAA,IAC7B,OAAO;AAAA,MACL,OAAO,KAAK,MAAM,GAAG,cAAc,CAAC,EAAE,QAAQ;AAAA,MAC9C,WAAW,KAAK,MAAM,cAAc,CAAC,EAAE,UAAU;AAAA,IACnD;AAAA,EACF;AAAA,EAGA,MAAM,QAAQ,WAAW,YAAY,GAAG;AAAA,EACxC,IAAI,QAAQ,QAAQ,KAAK;AAAA,IACvB,OAAO;AAAA,MACL,OAAO,KAAK,MAAM,GAAG,KAAK,EAAE,QAAQ;AAAA,MACpC,WAAW,KAAK,MAAM,QAAQ,CAAC,EAAE,UAAU;AAAA,IAC7C;AAAA,EACF;AAAA,EAGA,OAAO;AAAA,IACL,OAAO,KAAK,MAAM,GAAG,KAAK;AAAA,IAC1B,WAAW,KAAK,MAAM,KAAK;AAAA,EAC7B;AAAA;AAMK,SAAS,iBAAiB,CAAC,MAAc,OAA8B,CAAC,GAAa;AAAA,EAC1F,MAAM,QAAQ,KAAK,SAAS;AAAA,EAE5B,IAAI,CAAC,MAAM,KAAK,GAAG;AAAA,IACjB,OAAO,CAAC;AAAA,EACV;AAAA,EAEA,MAAM,iBAAiB,KAAK,KAAK;AAAA,EACjC,IAAI,eAAe,UAAU,OAAO;AAAA,IAClC,OAAO,CAAC,cAAc;AAAA,EACxB;AAAA,EAEA,MAAM,SAAmB,CAAC;AAAA,EAC1B,IAAI,YAAY;AAAA,EAEhB,OAAO,UAAU,SAAS,GAAG;AAAA,IAC3B,QAAQ,OAAO,cAAc,kBAAkB,WAAW,KAAK;AAAA,IAC/D,IAAI,OAAO;AAAA,MACT,OAAO,KAAK,KAAK;AAAA,IACnB;AAAA,IACA,YAAY;AAAA,EACd;AAAA,EAEA,OAAO,OAAO,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA;AAMnC,SAAS,YAAY,CAAC,MAAc,WAA2B;AAAA,EACpE,IAAI,KAAK,UAAU,WAAW;AAAA,IAC5B,OAAO;AAAA,EACT;AAAA,EACA,IAAI,aAAa,GAAG;AAAA,IAClB,OAAO,MAAM,MAAM,GAAG,SAAS;AAAA,EACjC;AAAA,EACA,OAAO,GAAG,KAAK,MAAM,GAAG,YAAY,CAAC;AAAA;AAMhC,SAAS,6BAA6B,CAAC,QAInC;AAAA,EACT,QAAQ,UAAU,QAAQ,aAAa;AAAA,EACvC,MAAM,OAAO,YAAY,OAAO,MAAM,GAAG,CAAC;AAAA,EAC1C,OAAO,YAAY,YAAY;AAAA;AAM1B,SAAS,qBAAqB,CAAC,OAAwB;AAAA,EAC5D,MAAM,aAAa,wBAAwB,KAAK;AAAA,EAChD,IAAI,CAAC,YAAY;AAAA,IACf,OAAO;AAAA,EACT;AAAA,EAEA,IAAI,CAAC,WAAW,WAAW,GAAG,GAAG;AAAA,IAC/B,OAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS,WAAW,QAAQ,OAAO,EAAE;AAAA,EAC3C,OAAO,cAAc,KAAK,MAAM;AAAA;AAM3B,SAAS,yBAAyB,CAAC,aAA6B;AAAA,EACrE,MAAM,aAAa,cAAc,WAAW;AAAA,EAC5C,IAAI,CAAC,YAAY;AAAA,IACf,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,SAAS,WAAW,QAAQ,OAAO,EAAE;AAAA,EAC3C,IAAI,OAAO,UAAU,IAAI;AAAA,IACvB,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,OAAO,MAAM,GAAG,OAAO,SAAS,EAAE;AAAA,EACtD,MAAM,OAAO,OAAO,MAAM,GAAG;AAAA,EAC7B,OAAO,IAAI,eAAe,KAAK,MAAM,GAAG,CAAC,KAAK,KAAK,MAAM,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC;AAAA;;AC8CzE,IAAK;AAAA,CAAL,CAAK,uBAAL;AAAA,EACL,yCAAmB;AAAA,EACnB,qCAAe;AAAA,EACf,0CAAoB;AAAA,EACpB,qCAAe;AAAA,EACf,uCAAiB;AAAA,EACjB,0CAAoB;AAAA,EACpB,sCAAgB;AAAA,EAChB,0CAAoB;AAAA,EACpB,yCAAmB;AAAA,GATT;AAeL,IAAM,qBAAqB;AAAA,EAChC,WAAW;AAAA,EACX,aAAa;AAAA,EACb,OAAO;AAAA,EACP,UAAU;AAAA,EACV,WAAW;AAAA,EACX,KAAK;AAAA,EACL,SAAS;AAAA,EACT,UAAU;AAAA,EACV,MAAM;AAAA,EACN,aAAa;AACf;;;Af7XO,MAAM,uBAAuB,cAA+B;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EAEjB;AAAA,EACA;AAAA,EACA,UAAU,CAAC,mBAAmB,kBAAkB;AAAA,EAEhD,WAAW,CAAC,QAAwB;AAAA,IAClC,MAAM;AAAA,IACN,KAAK,OAAO;AAAA,IACZ,KAAK,cAAc;AAAA,IACnB,KAAK,SAAS,cAAc,OAAO,MAAM;AAAA,IACzC,KAAK,iBAAiB,IAAI,eAAe,KAAK,MAAM;AAAA,IACpD,KAAK,iBAAiB,IAAI;AAAA,IAC1B,KAAK,qBAAqB;AAAA;AAAA,EAGpB,oBAAoB,GAAS;AAAA,IACnC,KAAK,OAAO,GAAG,WAAW,CAAC,YAAY,KAAK,KAAK,WAAW,OAAO,CAAC;AAAA,IACpE,KAAK,OAAO,GAAG,MAAM,CAAC,YAAY,KAAK,KAAK,MAAM,OAAO,CAAC;AAAA,IAC1D,KAAK,OAAO,GAAG,SAAS,MAAM,KAAK,KAAK,OAAO,CAAC;AAAA,IAChD,KAAK,OAAO,GAAG,cAAc,CAAC,WAAW,KAAK,KAAK,cAAc,MAAM,CAAC;AAAA,IACxE,KAAK,OAAO,GAAG,SAAS,CAAC,UAAU,KAAK,KAAK,SAAS,KAAK,CAAC;AAAA;AAAA,OAGxD,MAAK,GAAkB;AAAA,IAC3B,MAAM,KAAK,OAAO,MAAM;AAAA;AAAA,OAGpB,KAAI,GAAkB;AAAA,IAC1B,MAAM,KAAK,OAAO,KAAK;AAAA;AAAA,EAGzB,mBAAmB,GAAqB;AAAA,IACtC,OAAO,KAAK,OAAO,oBAAoB;AAAA;AAAA,OAGnC,YAAW,CAAC,UAA4D;AAAA,IAC5E,OAAO,KAAK,eAAe,KAAK,QAAO;AAAA;AAAA,OAGnC,cAAa,CAAC,OAA4C;AAAA,IAC9D,OAAO,KAAK,eAAe,OAAO,KAAK;AAAA;AAAA,OAGnC,cAAa,CAAC,OAAiC;AAAA,IACnD,IAAI,CAAC,KAAK,OAAO,eAAe;AAAA,MAC9B,MAAM,IAAI,MAAM,6DAA6D;AAAA,IAC/E;AAAA,IACA,OAAO,KAAK,OAAO,cAAc,KAAK;AAAA;AAE1C;AAEA,IAAM,iBAAyB;AAAA,EAC7B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS,CAAC,mBAAmB,kBAAkB;AACjD;AAEA,IAAe;",
|
|
23
|
+
"debugId": "A662ECA311FECE2F64756E2164756E21",
|
|
24
|
+
"names": []
|
|
25
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { IAgentRuntime } from "@elizaos/core";
|
|
2
|
+
/**
|
|
3
|
+
* Default account identifier used when no specific account is configured
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_ACCOUNT_ID = "default";
|
|
6
|
+
/**
|
|
7
|
+
* Token source indicator
|
|
8
|
+
*/
|
|
9
|
+
export type WhatsAppTokenSource = "config" | "env" | "character" | "none";
|
|
10
|
+
/**
|
|
11
|
+
* Group-specific runtime configuration (for account resolution)
|
|
12
|
+
*/
|
|
13
|
+
export interface WhatsAppGroupRuntimeConfig {
|
|
14
|
+
/** If false, ignore messages from this group */
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
/** Allowlist for users in this group */
|
|
17
|
+
allowFrom?: Array<string | number>;
|
|
18
|
+
/** Require bot mention to respond */
|
|
19
|
+
requireMention?: boolean;
|
|
20
|
+
/** Custom system prompt for this group */
|
|
21
|
+
systemPrompt?: string;
|
|
22
|
+
/** Skills enabled for this group */
|
|
23
|
+
skills?: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Configuration for a single WhatsApp account (runtime resolution)
|
|
27
|
+
*/
|
|
28
|
+
export interface WhatsAppAccountRuntimeConfig {
|
|
29
|
+
/** Optional display name for this account */
|
|
30
|
+
name?: string;
|
|
31
|
+
/** If false, do not start this WhatsApp account */
|
|
32
|
+
enabled?: boolean;
|
|
33
|
+
/** WhatsApp Cloud API access token */
|
|
34
|
+
accessToken?: string;
|
|
35
|
+
/** Phone number ID from WhatsApp Business */
|
|
36
|
+
phoneNumberId?: string;
|
|
37
|
+
/** Business account ID */
|
|
38
|
+
businessAccountId?: string;
|
|
39
|
+
/** Webhook verification token */
|
|
40
|
+
webhookVerifyToken?: string;
|
|
41
|
+
/** API version to use */
|
|
42
|
+
apiVersion?: string;
|
|
43
|
+
/** Allowlist for DM senders */
|
|
44
|
+
allowFrom?: Array<string | number>;
|
|
45
|
+
/** Allowlist for groups */
|
|
46
|
+
groupAllowFrom?: Array<string | number>;
|
|
47
|
+
/** DM access policy */
|
|
48
|
+
dmPolicy?: "open" | "allowlist" | "pairing" | "disabled";
|
|
49
|
+
/** Group message access policy */
|
|
50
|
+
groupPolicy?: "open" | "allowlist" | "disabled";
|
|
51
|
+
/** Max media size in MB */
|
|
52
|
+
mediaMaxMb?: number;
|
|
53
|
+
/** Text chunk limit for messages */
|
|
54
|
+
textChunkLimit?: number;
|
|
55
|
+
/** Group-specific configurations */
|
|
56
|
+
groups?: Record<string, WhatsAppGroupRuntimeConfig>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Multi-account WhatsApp configuration structure
|
|
60
|
+
*/
|
|
61
|
+
export interface WhatsAppMultiAccountConfig {
|
|
62
|
+
/** Default/base configuration applied to all accounts */
|
|
63
|
+
enabled?: boolean;
|
|
64
|
+
accessToken?: string;
|
|
65
|
+
phoneNumberId?: string;
|
|
66
|
+
businessAccountId?: string;
|
|
67
|
+
webhookVerifyToken?: string;
|
|
68
|
+
apiVersion?: string;
|
|
69
|
+
dmPolicy?: "open" | "allowlist" | "pairing" | "disabled";
|
|
70
|
+
groupPolicy?: "open" | "allowlist" | "disabled";
|
|
71
|
+
mediaMaxMb?: number;
|
|
72
|
+
textChunkLimit?: number;
|
|
73
|
+
/** Per-account configuration overrides */
|
|
74
|
+
accounts?: Record<string, WhatsAppAccountRuntimeConfig>;
|
|
75
|
+
/** Group configurations at base level */
|
|
76
|
+
groups?: Record<string, WhatsAppGroupRuntimeConfig>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Token resolution result
|
|
80
|
+
*/
|
|
81
|
+
export interface WhatsAppTokenResolution {
|
|
82
|
+
token: string;
|
|
83
|
+
source: WhatsAppTokenSource;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolved WhatsApp account with all configuration merged
|
|
87
|
+
*/
|
|
88
|
+
export interface ResolvedWhatsAppAccount {
|
|
89
|
+
accountId: string;
|
|
90
|
+
enabled: boolean;
|
|
91
|
+
name?: string;
|
|
92
|
+
accessToken: string;
|
|
93
|
+
phoneNumberId: string;
|
|
94
|
+
businessAccountId?: string;
|
|
95
|
+
tokenSource: WhatsAppTokenSource;
|
|
96
|
+
configured: boolean;
|
|
97
|
+
config: WhatsAppAccountRuntimeConfig;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Normalizes an account ID, returning the default if not provided
|
|
101
|
+
*/
|
|
102
|
+
export declare function normalizeAccountId(accountId?: string | null): string;
|
|
103
|
+
/**
|
|
104
|
+
* Gets the multi-account configuration from runtime settings
|
|
105
|
+
*/
|
|
106
|
+
export declare function getMultiAccountConfig(runtime: IAgentRuntime): WhatsAppMultiAccountConfig;
|
|
107
|
+
/**
|
|
108
|
+
* Lists all configured account IDs
|
|
109
|
+
*/
|
|
110
|
+
export declare function listWhatsAppAccountIds(runtime: IAgentRuntime): string[];
|
|
111
|
+
/**
|
|
112
|
+
* Resolves the default account ID to use
|
|
113
|
+
*/
|
|
114
|
+
export declare function resolveDefaultWhatsAppAccountId(runtime: IAgentRuntime): string;
|
|
115
|
+
/**
|
|
116
|
+
* Resolves the access token for a WhatsApp account
|
|
117
|
+
*/
|
|
118
|
+
export declare function resolveWhatsAppToken(runtime: IAgentRuntime, accountId: string): WhatsAppTokenResolution;
|
|
119
|
+
/**
|
|
120
|
+
* Resolves a complete WhatsApp account configuration
|
|
121
|
+
*/
|
|
122
|
+
export declare function resolveWhatsAppAccount(runtime: IAgentRuntime, accountId?: string | null): ResolvedWhatsAppAccount;
|
|
123
|
+
/**
|
|
124
|
+
* Lists all enabled WhatsApp accounts
|
|
125
|
+
*/
|
|
126
|
+
export declare function listEnabledWhatsAppAccounts(runtime: IAgentRuntime): ResolvedWhatsAppAccount[];
|
|
127
|
+
/**
|
|
128
|
+
* Checks if multi-account mode is enabled
|
|
129
|
+
*/
|
|
130
|
+
export declare function isMultiAccountEnabled(runtime: IAgentRuntime): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Resolves group configuration for a specific group
|
|
133
|
+
*/
|
|
134
|
+
export declare function resolveWhatsAppGroupConfig(runtime: IAgentRuntime, accountId: string, groupId: string): WhatsAppGroupRuntimeConfig | undefined;
|
|
135
|
+
/**
|
|
136
|
+
* Checks if a user is allowed based on policy and allowlist
|
|
137
|
+
*/
|
|
138
|
+
export declare function isWhatsAppUserAllowed(params: {
|
|
139
|
+
identifier: string;
|
|
140
|
+
accountConfig: WhatsAppAccountRuntimeConfig;
|
|
141
|
+
isGroup: boolean;
|
|
142
|
+
groupId?: string;
|
|
143
|
+
groupConfig?: WhatsAppGroupRuntimeConfig;
|
|
144
|
+
}): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* Checks if mention is required in a group
|
|
147
|
+
*/
|
|
148
|
+
export declare function isWhatsAppMentionRequired(params: {
|
|
149
|
+
accountConfig: WhatsAppAccountRuntimeConfig;
|
|
150
|
+
groupConfig?: WhatsAppGroupRuntimeConfig;
|
|
151
|
+
}): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Result of an async WhatsApp access check
|
|
154
|
+
*/
|
|
155
|
+
export interface WhatsAppAccessCheckResult {
|
|
156
|
+
/** Whether the sender is allowed to proceed */
|
|
157
|
+
allowed: boolean;
|
|
158
|
+
/** If not allowed (pairing policy), the pairing code */
|
|
159
|
+
pairingCode?: string;
|
|
160
|
+
/** Whether a new pairing request was created */
|
|
161
|
+
newPairingRequest?: boolean;
|
|
162
|
+
/** Human-readable message to send to the user when blocked */
|
|
163
|
+
replyMessage?: string;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Checks if a user is allowed based on policy and allowlist, with async pairing support.
|
|
167
|
+
*
|
|
168
|
+
* For non-pairing policies, this behaves identically to `isWhatsAppUserAllowed`.
|
|
169
|
+
* For the "pairing" policy, this actually checks the PairingService allowlist
|
|
170
|
+
* and creates pairing requests when needed.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* const result = await checkWhatsAppUserAccess({
|
|
175
|
+
* runtime,
|
|
176
|
+
* identifier: message.from,
|
|
177
|
+
* accountConfig,
|
|
178
|
+
* isGroup: false,
|
|
179
|
+
* metadata: { name: contact.name },
|
|
180
|
+
* });
|
|
181
|
+
*
|
|
182
|
+
* if (!result.allowed) {
|
|
183
|
+
* if (result.replyMessage) {
|
|
184
|
+
* await sendMessage(result.replyMessage);
|
|
185
|
+
* }
|
|
186
|
+
* return; // Block message processing
|
|
187
|
+
* }
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
export declare function checkWhatsAppUserAccess(params: {
|
|
191
|
+
runtime: IAgentRuntime;
|
|
192
|
+
identifier: string;
|
|
193
|
+
accountConfig: WhatsAppAccountRuntimeConfig;
|
|
194
|
+
isGroup: boolean;
|
|
195
|
+
groupId?: string;
|
|
196
|
+
groupConfig?: WhatsAppGroupRuntimeConfig;
|
|
197
|
+
metadata?: Record<string, string>;
|
|
198
|
+
}): Promise<WhatsAppAccessCheckResult>;
|
|
199
|
+
//# sourceMappingURL=accounts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/accounts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendMessage.d.ts","sourceRoot":"","sources":["../../../src/actions/sendMessage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAQP,MAAM,eAAe,CAAC;AAGvB,eAAO,MAAM,4BAA4B,0BAA0B,CAAC;AAyBpE,eAAO,MAAM,iBAAiB,EAAE,MAmM/B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendReaction.d.ts","sourceRoot":"","sources":["../../../src/actions/sendReaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAQP,MAAM,eAAe,CAAC;AAGvB,eAAO,MAAM,6BAA6B,2BAA2B,CAAC;AAyBtE,eAAO,MAAM,kBAAkB,EAAE,MAqLhC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AuthenticationState } from "@whiskeysockets/baileys";
|
|
2
|
+
export declare class BaileysAuthManager {
|
|
3
|
+
private readonly authDir;
|
|
4
|
+
private state?;
|
|
5
|
+
private saveCreds?;
|
|
6
|
+
constructor(authDir: string);
|
|
7
|
+
initialize(): Promise<AuthenticationState>;
|
|
8
|
+
save(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/baileys/auth.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,KAAK,CAAC,CAAsB;IACpC,OAAO,CAAC,SAAS,CAAC,CAAsB;gBAE5B,OAAO,EAAE,MAAM;IAIrB,UAAU,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAO1C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAK5B"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type WASocket } from "@whiskeysockets/baileys";
|
|
2
|
+
import { EventEmitter } from "node:events";
|
|
3
|
+
import type { BaileysAuthManager } from "./auth";
|
|
4
|
+
import type { ConnectionStatus } from "../types";
|
|
5
|
+
export declare class BaileysConnection extends EventEmitter {
|
|
6
|
+
private socket?;
|
|
7
|
+
private readonly authManager;
|
|
8
|
+
private connectionStatus;
|
|
9
|
+
private reconnecting;
|
|
10
|
+
private reconnectAttempts;
|
|
11
|
+
private readonly maxReconnectAttempts;
|
|
12
|
+
constructor(authManager: BaileysAuthManager);
|
|
13
|
+
connect(): Promise<WASocket>;
|
|
14
|
+
private setupEventHandlers;
|
|
15
|
+
getSocket(): WASocket | undefined;
|
|
16
|
+
getStatus(): ConnectionStatus;
|
|
17
|
+
disconnect(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/baileys/connection.ts"],"names":[],"mappings":"AAAA,OAAqB,EAAoB,KAAK,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAExF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD,qBAAa,iBAAkB,SAAQ,YAAY;IACjD,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAM;gBAE/B,WAAW,EAAE,kBAAkB;IAKrC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;IAgBlC,OAAO,CAAC,kBAAkB;IAyE1B,SAAS,IAAI,QAAQ,GAAG,SAAS;IAIjC,SAAS,IAAI,gBAAgB;IAIvB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAelC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/baileys/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,WAAW,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { proto } from "@whiskeysockets/baileys";
|
|
2
|
+
import type { UnifiedMessage, WhatsAppMessage } from "../types";
|
|
3
|
+
export declare class MessageAdapter {
|
|
4
|
+
toUnified(msg: proto.IWebMessageInfo): UnifiedMessage;
|
|
5
|
+
toBaileys(msg: WhatsAppMessage): Record<string, unknown>;
|
|
6
|
+
private mediaWithCaption;
|
|
7
|
+
private mediaNoCaption;
|
|
8
|
+
private mediaWithFilename;
|
|
9
|
+
private detectType;
|
|
10
|
+
private extractContent;
|
|
11
|
+
private renderTemplate;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=message-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-adapter.d.ts","sourceRoot":"","sources":["../../../src/baileys/message-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,KAAK,EACV,cAAc,EAEd,eAAe,EAEhB,MAAM,UAAU,CAAC;AAElB,qBAAa,cAAc;IACzB,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC,eAAe,GAAG,cAAc;IAUrD,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAmBxD,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,UAAU;IAqBlB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,cAAc;CAQvB"}
|