@masons/agent-network 0.4.16 → 0.4.17
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/channel.d.ts.map +1 -1
- package/dist/channel.js +154 -195
- package/dist/connector-client.d.ts +46 -24
- package/dist/connector-client.d.ts.map +1 -1
- package/dist/connector-client.js +123 -76
- package/dist/conversation-manager.d.ts +40 -33
- package/dist/conversation-manager.d.ts.map +1 -1
- package/dist/conversation-manager.js +103 -80
- package/dist/handle-utils.d.ts +16 -0
- package/dist/handle-utils.d.ts.map +1 -0
- package/dist/handle-utils.js +25 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/owner-session-state.d.ts +11 -18
- package/dist/owner-session-state.d.ts.map +1 -1
- package/dist/owner-session-state.js +17 -26
- package/dist/tools.d.ts +1 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +2 -33
- package/dist/types.d.ts +47 -58
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +18 -33
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/connector-client.js
CHANGED
|
@@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { EventEmitter } from "node:events";
|
|
3
3
|
import createDebug from "debug";
|
|
4
4
|
import WebSocket from "ws";
|
|
5
|
-
import { CURRENT_PROTOCOL_VERSION,
|
|
5
|
+
import { CURRENT_PROTOCOL_VERSION, isAddressedMessage, isDeliveryPending, isRegisterAck, isSendAck, isStructuredError, REGISTER_ACK_TIMEOUT_MS, SEND_ACK_TIMEOUT_MS, } from "./types.js";
|
|
6
6
|
import { PLUGIN_VERSION } from "./version.js";
|
|
7
7
|
const dbg = createDebug("agent-network:connector");
|
|
8
8
|
const dbgMsg = createDebug("agent-network:connector:msg");
|
|
@@ -11,6 +11,21 @@ const BACKOFF_INITIAL_MS = 1_000;
|
|
|
11
11
|
const BACKOFF_MAX_MS = 30_000;
|
|
12
12
|
const ALREADY_CONNECTED_RETRY_MS = 2_000;
|
|
13
13
|
const ALREADY_CONNECTED_MAX_RETRIES = 30;
|
|
14
|
+
// --- Error class for structured errors ---
|
|
15
|
+
/**
|
|
16
|
+
* Error with machine-readable `code` from Connector structured errors.
|
|
17
|
+
* Thrown by `send()` when the Connector responds with ERROR { code }.
|
|
18
|
+
*/
|
|
19
|
+
export class ConnectorError extends Error {
|
|
20
|
+
code;
|
|
21
|
+
to;
|
|
22
|
+
constructor(message, code, to) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = "ConnectorError";
|
|
25
|
+
this.code = code;
|
|
26
|
+
this.to = to;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
14
29
|
// --- ConnectorClient ---
|
|
15
30
|
export class ConnectorClient extends EventEmitter {
|
|
16
31
|
url;
|
|
@@ -23,6 +38,8 @@ export class ConnectorClient extends EventEmitter {
|
|
|
23
38
|
registerResolve = null;
|
|
24
39
|
registerReject = null;
|
|
25
40
|
registerTimer = null;
|
|
41
|
+
/** Pending SEND_ACK correlation map for address-based sends. */
|
|
42
|
+
pendingSends = new Map();
|
|
26
43
|
constructor(url, token) {
|
|
27
44
|
super();
|
|
28
45
|
this.url = url;
|
|
@@ -49,58 +66,54 @@ export class ConnectorClient extends EventEmitter {
|
|
|
49
66
|
wsToClose.close(1000, "Client disconnect");
|
|
50
67
|
}
|
|
51
68
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
dbg("createSession target=%s requestId=%s sent=%s", target, requestId, sent);
|
|
63
|
-
return { requestId, sent };
|
|
64
|
-
}
|
|
65
|
-
sendMessage(sessionId, content, opts) {
|
|
69
|
+
// --- Messaging ---
|
|
70
|
+
/**
|
|
71
|
+
* Send a message to a routable address. Returns a Promise that resolves
|
|
72
|
+
* with the SEND_ACK from the Connector, or rejects with a ConnectorError
|
|
73
|
+
* (structured error code) or a plain Error (timeout / disconnect).
|
|
74
|
+
*
|
|
75
|
+
* The messageId is generated internally and used for ACK correlation.
|
|
76
|
+
*/
|
|
77
|
+
send(to, content, contentType = "text", metadata) {
|
|
78
|
+
const messageId = randomUUID();
|
|
66
79
|
const event = {
|
|
67
80
|
event: "SEND_MESSAGE",
|
|
68
|
-
|
|
81
|
+
messageId,
|
|
82
|
+
to,
|
|
69
83
|
content,
|
|
70
|
-
contentType
|
|
71
|
-
metadata
|
|
72
|
-
};
|
|
73
|
-
const sent = this.send(event);
|
|
74
|
-
dbgMsg("sendMessage sessionId=%s contentLength=%d sent=%s", sessionId, content.length, sent);
|
|
75
|
-
return sent;
|
|
76
|
-
}
|
|
77
|
-
endSession(sessionId, reason) {
|
|
78
|
-
const event = {
|
|
79
|
-
event: "END_SESSION",
|
|
80
|
-
sessionId,
|
|
81
|
-
reason,
|
|
84
|
+
contentType,
|
|
85
|
+
metadata,
|
|
82
86
|
};
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
event
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
const timer = setTimeout(() => {
|
|
89
|
+
this.pendingSends.delete(messageId);
|
|
90
|
+
reject(new Error("SEND_ACK timeout"));
|
|
91
|
+
}, SEND_ACK_TIMEOUT_MS);
|
|
92
|
+
this.pendingSends.set(messageId, { resolve, reject, timer });
|
|
93
|
+
const sent = this.sendEvent(event);
|
|
94
|
+
if (!sent) {
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
this.pendingSends.delete(messageId);
|
|
97
|
+
reject(new Error("WebSocket not connected"));
|
|
98
|
+
}
|
|
99
|
+
});
|
|
95
100
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
/**
|
|
102
|
+
* Send a typing indicator to a routable address.
|
|
103
|
+
*/
|
|
104
|
+
sendTyping(to, isTyping) {
|
|
105
|
+
const event = { event: "TYPING", to, isTyping };
|
|
106
|
+
const sent = this.sendEvent(event);
|
|
107
|
+
dbg("sendTyping to=%s isTyping=%s sent=%s", to, isTyping, sent);
|
|
99
108
|
return sent;
|
|
100
109
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Acknowledge delivery of stored messages up to a timestamp.
|
|
112
|
+
*/
|
|
113
|
+
ackDelivery(upTo) {
|
|
114
|
+
const event = { event: "DELIVERY_ACK", upTo };
|
|
115
|
+
const sent = this.sendEvent(event);
|
|
116
|
+
dbg("ackDelivery upTo=%s sent=%s", upTo, sent);
|
|
104
117
|
return sent;
|
|
105
118
|
}
|
|
106
119
|
on(event, listener) {
|
|
@@ -138,7 +151,7 @@ export class ConnectorClient extends EventEmitter {
|
|
|
138
151
|
protocolVersion: CURRENT_PROTOCOL_VERSION,
|
|
139
152
|
clientVersion: PLUGIN_VERSION,
|
|
140
153
|
};
|
|
141
|
-
this.
|
|
154
|
+
this.sendEvent(event);
|
|
142
155
|
}
|
|
143
156
|
startRegisterTimeout() {
|
|
144
157
|
this.registerTimer = setTimeout(() => {
|
|
@@ -178,40 +191,46 @@ export class ConnectorClient extends EventEmitter {
|
|
|
178
191
|
this.emit("error", new Error("Received non-JSON message from Connector"));
|
|
179
192
|
return;
|
|
180
193
|
}
|
|
194
|
+
// REGISTER_ACK is version-agnostic — always handled first
|
|
181
195
|
if (isRegisterAck(parsed)) {
|
|
182
196
|
this.handleRegisterAck(parsed);
|
|
183
197
|
return;
|
|
184
198
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
199
|
+
this.dispatchAddressed(parsed);
|
|
200
|
+
};
|
|
201
|
+
/** Dispatch inbound address-based events. */
|
|
202
|
+
dispatchAddressed(parsed) {
|
|
203
|
+
if (isSendAck(parsed)) {
|
|
204
|
+
dbg("SEND_ACK messageId=%s status=%s", parsed.messageId, parsed.status);
|
|
205
|
+
this.handleSendAck(parsed);
|
|
188
206
|
return;
|
|
189
207
|
}
|
|
190
|
-
if (
|
|
191
|
-
dbgMsg("MESSAGE_RECEIVED
|
|
208
|
+
if (isAddressedMessage(parsed)) {
|
|
209
|
+
dbgMsg("MESSAGE_RECEIVED from=%s contentLength=%d", parsed.from, parsed.content.length);
|
|
192
210
|
this.emit("message_received", parsed);
|
|
193
211
|
return;
|
|
194
212
|
}
|
|
195
|
-
if (
|
|
196
|
-
dbg("
|
|
197
|
-
this.emit("
|
|
213
|
+
if (isDeliveryPending(parsed)) {
|
|
214
|
+
dbg("DELIVERY_PENDING count=%d upTo=%s", parsed.count, parsed.upTo);
|
|
215
|
+
this.emit("delivery_pending", parsed);
|
|
198
216
|
return;
|
|
199
217
|
}
|
|
200
|
-
if (
|
|
201
|
-
dbg("
|
|
202
|
-
this.
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (isErrorEvent(parsed)) {
|
|
206
|
-
dbg("ERROR message=%s", parsed.message);
|
|
207
|
-
this.handleErrorEvent(parsed);
|
|
218
|
+
if (isStructuredError(parsed)) {
|
|
219
|
+
dbg("ERROR code=%s message=%s", parsed.code, parsed.message);
|
|
220
|
+
this.handleStructuredError(parsed);
|
|
208
221
|
return;
|
|
209
222
|
}
|
|
210
223
|
// Unknown event type — silently ignore (forward compatibility)
|
|
211
|
-
}
|
|
224
|
+
}
|
|
212
225
|
handleRegisterAck(ack) {
|
|
213
|
-
dbg("REGISTER_ACK status=%s", ack.status);
|
|
226
|
+
dbg("REGISTER_ACK status=%s protocolVersion=%d", ack.status, ack.protocolVersion);
|
|
214
227
|
if (ack.status === "ok") {
|
|
228
|
+
// Defensive: verify the negotiated version matches what we requested.
|
|
229
|
+
// Current Connector rejects unsupported versions outright (no downgrade),
|
|
230
|
+
// so this check is future-proofing against silent protocol desync.
|
|
231
|
+
if (ack.protocolVersion !== CURRENT_PROTOCOL_VERSION) {
|
|
232
|
+
dbg("WARN: server negotiated protocolVersion=%d, expected=%d", ack.protocolVersion, CURRENT_PROTOCOL_VERSION);
|
|
233
|
+
}
|
|
215
234
|
this.backoffMs = BACKOFF_INITIAL_MS;
|
|
216
235
|
this.alreadyConnectedRetries = 0;
|
|
217
236
|
this.resolveRegister();
|
|
@@ -235,17 +254,38 @@ export class ConnectorClient extends EventEmitter {
|
|
|
235
254
|
this.ws?.close(4001, reason);
|
|
236
255
|
}
|
|
237
256
|
}
|
|
238
|
-
|
|
239
|
-
|
|
257
|
+
// --- Address-based handlers ---
|
|
258
|
+
/**
|
|
259
|
+
* Resolve the pending send promise matching this SEND_ACK.
|
|
260
|
+
* Also emits `send_ack` for listeners that want to observe all ACKs.
|
|
261
|
+
*/
|
|
262
|
+
handleSendAck(ack) {
|
|
263
|
+
this.emit("send_ack", ack);
|
|
264
|
+
const pending = this.pendingSends.get(ack.messageId);
|
|
265
|
+
if (pending) {
|
|
266
|
+
clearTimeout(pending.timer);
|
|
267
|
+
this.pendingSends.delete(ack.messageId);
|
|
268
|
+
pending.resolve(ack);
|
|
269
|
+
}
|
|
240
270
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Structured ERROR: message-scoped errors reject pending sends,
|
|
273
|
+
* connection-scoped errors emit generic event.
|
|
274
|
+
*/
|
|
275
|
+
handleStructuredError(event) {
|
|
276
|
+
this.emit("structured_error", event);
|
|
277
|
+
// Message-scoped: reject the pending send for this messageId
|
|
278
|
+
if (event.messageId) {
|
|
279
|
+
const pending = this.pendingSends.get(event.messageId);
|
|
280
|
+
if (pending) {
|
|
281
|
+
clearTimeout(pending.timer);
|
|
282
|
+
this.pendingSends.delete(event.messageId);
|
|
283
|
+
pending.reject(new ConnectorError(event.message, event.code, event.to));
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
246
286
|
}
|
|
247
|
-
//
|
|
248
|
-
this.emit("error", new Error(event.message));
|
|
287
|
+
// Connection-scoped: emit generic error
|
|
288
|
+
this.emit("error", new Error(`[${event.code}] ${event.message}`));
|
|
249
289
|
}
|
|
250
290
|
// --- Connection close ---
|
|
251
291
|
handleClose = () => {
|
|
@@ -320,9 +360,16 @@ export class ConnectorClient extends EventEmitter {
|
|
|
320
360
|
clearTimeout(this.registerTimer);
|
|
321
361
|
this.registerTimer = null;
|
|
322
362
|
}
|
|
363
|
+
// Reject all pending address-based sends on disconnect
|
|
364
|
+
for (const [, pending] of this.pendingSends) {
|
|
365
|
+
clearTimeout(pending.timer);
|
|
366
|
+
pending.reject(new Error("Connection closed"));
|
|
367
|
+
}
|
|
368
|
+
this.pendingSends.clear();
|
|
323
369
|
}
|
|
324
|
-
// ---
|
|
325
|
-
|
|
370
|
+
// --- Wire helpers ---
|
|
371
|
+
/** Send an event over the WebSocket. */
|
|
372
|
+
sendEvent(event) {
|
|
326
373
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
327
374
|
this.ws.send(JSON.stringify(event));
|
|
328
375
|
return true;
|
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
* Conversation Manager — maps contacts to conversations.
|
|
3
3
|
*
|
|
4
4
|
* Owns the identity-based API that the Tool Interface and Inbound Dispatcher
|
|
5
|
-
* call.
|
|
5
|
+
* call. Sends messages directly to routable addresses via ConnectorClient.send().
|
|
6
6
|
*
|
|
7
|
-
* Contact resolution: handle
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* Contact resolution: handle → `mstps://${connectorHost}/${handle}`
|
|
8
|
+
* Address schemes: MSTP (`mstps://`), handle (bare), passport (`passport:@`)
|
|
9
|
+
* Internal key: routable address.
|
|
10
|
+
* One conversation per contact, in-memory only (D3).
|
|
11
11
|
*
|
|
12
|
-
* @see docs/
|
|
12
|
+
* @see docs/connector/gateway-v2-consumer-adaptation-plan.md PR 2
|
|
13
13
|
*/
|
|
14
|
-
import type
|
|
15
|
-
import { SessionLifecycle } from "./session-lifecycle.js";
|
|
14
|
+
import { type ConnectorClient } from "./connector-client.js";
|
|
16
15
|
export interface SendResult {
|
|
17
16
|
status: "sent" | "failed";
|
|
18
17
|
error?: string;
|
|
18
|
+
/** Machine-readable error code from Connector (when status === "failed"). */
|
|
19
|
+
errorCode?: string;
|
|
19
20
|
}
|
|
20
21
|
export interface ConversationEntry {
|
|
21
22
|
contact: string;
|
|
@@ -31,37 +32,37 @@ export interface ConversationSummary {
|
|
|
31
32
|
initiatedBy: "local" | "remote";
|
|
32
33
|
}
|
|
33
34
|
export declare class ConversationManager {
|
|
34
|
-
readonly sessionLifecycle: SessionLifecycle;
|
|
35
35
|
private readonly client;
|
|
36
36
|
private readonly connectorHost;
|
|
37
|
-
/** Conversations keyed by
|
|
37
|
+
/** Conversations keyed by routable address */
|
|
38
38
|
private readonly conversations;
|
|
39
39
|
constructor(client: ConnectorClient, connectorHost: string);
|
|
40
40
|
/**
|
|
41
|
-
* Send a message to a contact.
|
|
42
|
-
*
|
|
41
|
+
* Send a message to a contact. Sends directly to the resolved address —
|
|
42
|
+
* no session management needed.
|
|
43
43
|
*
|
|
44
|
-
*
|
|
44
|
+
* Returns a structured result with status and optional error.
|
|
45
|
+
* ConnectorError codes (ADDRESS_NOT_FOUND, ACCESS_DENIED, etc.) are
|
|
46
|
+
* mapped to human-readable messages for LLM tool results.
|
|
47
|
+
*
|
|
48
|
+
* @param contact - Handle, MSTP address, or passport address of the target.
|
|
45
49
|
* @param content - Message content to send.
|
|
46
50
|
*/
|
|
47
51
|
send(contact: string, content: string): Promise<SendResult>;
|
|
48
52
|
/**
|
|
49
|
-
* Register an inbound
|
|
50
|
-
* Called by the channel adapter
|
|
51
|
-
*/
|
|
52
|
-
registerInbound(sessionId: string, contact: string, address: string): void;
|
|
53
|
-
/**
|
|
54
|
-
* Resolve a sessionId to a contact handle.
|
|
55
|
-
* Used by the inbound dispatcher to derive sender identity from a message event.
|
|
53
|
+
* Register an inbound conversation (remote agent or visitor initiated).
|
|
54
|
+
* Called by the channel adapter when a message arrives from a new address.
|
|
56
55
|
*/
|
|
57
|
-
|
|
56
|
+
registerInbound(contact: string, address: string): void;
|
|
58
57
|
/**
|
|
59
|
-
* Resolve a
|
|
60
|
-
* Used by the
|
|
58
|
+
* Resolve a routable address to a contact handle.
|
|
59
|
+
* Used by the inbound dispatcher to derive sender identity from MESSAGE_RECEIVED.from.
|
|
61
60
|
*/
|
|
62
|
-
|
|
61
|
+
getContactByAddress(address: string): string | undefined;
|
|
63
62
|
/**
|
|
64
63
|
* List all conversations with metadata.
|
|
64
|
+
* `active` is always true for address-based protocol — there is no session
|
|
65
|
+
* lifecycle. Conversations persist until explicitly ended or Plugin restarts.
|
|
65
66
|
*/
|
|
66
67
|
listConversations(): ConversationSummary[];
|
|
67
68
|
/**
|
|
@@ -74,25 +75,31 @@ export declare class ConversationManager {
|
|
|
74
75
|
hasConversation(contact: string): boolean;
|
|
75
76
|
/**
|
|
76
77
|
* End the conversation with a contact.
|
|
77
|
-
*
|
|
78
|
+
* Removes the conversation entry. No END_SESSION needed — the Connector
|
|
79
|
+
* manages connection lifecycle (idle timeout).
|
|
78
80
|
*/
|
|
79
81
|
endConversation(contact: string): void;
|
|
80
82
|
/**
|
|
81
|
-
* Resolve a contact (handle or
|
|
83
|
+
* Resolve a contact (handle, MSTP address, or passport address) to a
|
|
84
|
+
* routable address.
|
|
82
85
|
*
|
|
83
86
|
* Resolution order:
|
|
84
|
-
* 1.
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
87
|
+
* 1. MSTP address (starts with mstps:// or mstp://) → return as-is.
|
|
88
|
+
* 2. Passport address (starts with passport:) → return as-is (already routable).
|
|
89
|
+
* 3. Already a key in the conversations map → return as-is.
|
|
90
|
+
* 4. Reverse lookup: if any existing conversation has this handle as its
|
|
91
|
+
* contact, use that conversation's address. This ensures replies to a
|
|
92
|
+
* cross-Connector sender route to the sender's original address, not to
|
|
93
|
+
* a locally-constructed address.
|
|
94
|
+
* 5. Otherwise treat as handle → construct `mstps://${connectorHost}/${handle}`.
|
|
89
95
|
*/
|
|
90
96
|
resolveAddress(contact: string): string;
|
|
91
97
|
/**
|
|
92
|
-
* Extract handle from
|
|
93
|
-
*
|
|
98
|
+
* Extract a display-friendly handle from any address scheme.
|
|
99
|
+
* Delegates to shared utility — single source of truth.
|
|
94
100
|
*/
|
|
95
101
|
extractHandle(address: string): string;
|
|
102
|
+
private ensureConversationEntry;
|
|
96
103
|
/** @internal Reset for test isolation. */
|
|
97
104
|
_resetForTesting(): void;
|
|
98
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversation-manager.d.ts","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"conversation-manager.d.ts","sourceRoot":"","sources":["../src/conversation-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,uBAAuB,CAAC;AAS7E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,GAAG,QAAQ,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,OAAO,GAAG,QAAQ,CAAC;CACjC;AAwBD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IAEvC,8CAA8C;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwC;gBAE1D,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM;IAS1D;;;;;;;;;;OAUG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA0CjE;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAKvD;;;OAGG;IACH,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAaxD;;;;OAIG;IACH,iBAAiB,IAAI,mBAAmB,EAAE;IAc1C;;;;;;OAMG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAKzC;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAUtC;;;;;;;;;;;;;OAaG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAoBvC;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAQtC,OAAO,CAAC,uBAAuB;IAwB/B,0CAA0C;IAC1C,gBAAgB,IAAI,IAAI;CAGzB"}
|