@wirecat/whatsapp-cli 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +204 -0
- package/README.md +282 -2
- package/dist/adapter/adapter.d.ts +9 -0
- package/dist/adapter/adapter.d.ts.map +1 -0
- package/dist/adapter/adapter.js +326 -0
- package/dist/adapter/adapter.js.map +1 -0
- package/dist/adapter/checks.d.ts +7 -0
- package/dist/adapter/checks.d.ts.map +1 -0
- package/dist/adapter/checks.js +3 -0
- package/dist/adapter/checks.js.map +1 -0
- package/dist/adapter/errors.d.ts +18 -0
- package/dist/adapter/errors.d.ts.map +1 -0
- package/dist/adapter/errors.js +40 -0
- package/dist/adapter/errors.js.map +1 -0
- package/dist/adapter/format-markdown.d.ts +8 -0
- package/dist/adapter/format-markdown.d.ts.map +1 -0
- package/dist/adapter/format-markdown.js +80 -0
- package/dist/adapter/format-markdown.js.map +1 -0
- package/dist/adapter/groups.d.ts +21 -0
- package/dist/adapter/groups.d.ts.map +1 -0
- package/dist/adapter/groups.js +210 -0
- package/dist/adapter/groups.js.map +1 -0
- package/dist/adapter/map.d.ts +9 -0
- package/dist/adapter/map.d.ts.map +1 -0
- package/dist/adapter/map.js +72 -0
- package/dist/adapter/map.js.map +1 -0
- package/dist/adapter/polls.d.ts +21 -0
- package/dist/adapter/polls.d.ts.map +1 -0
- package/dist/adapter/polls.js +103 -0
- package/dist/adapter/polls.js.map +1 -0
- package/dist/app.d.ts +6 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +16 -0
- package/dist/app.js.map +1 -0
- package/dist/bin/wa.d.ts +3 -0
- package/dist/bin/wa.d.ts.map +1 -0
- package/dist/bin/wa.js +27 -0
- package/dist/bin/wa.js.map +1 -0
- package/dist/commands/answer.d.ts +7 -0
- package/dist/commands/answer.d.ts.map +1 -0
- package/dist/commands/answer.js +11 -0
- package/dist/commands/answer.js.map +1 -0
- package/dist/commands/session.d.ts +37 -0
- package/dist/commands/session.d.ts.map +1 -0
- package/dist/commands/session.js +202 -0
- package/dist/commands/session.js.map +1 -0
- package/dist/commands/setup.d.ts +3 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +192 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +36 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/diagnose.d.ts +77 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +84 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/engine/contract.d.ts +617 -0
- package/dist/engine/contract.d.ts.map +1 -0
- package/dist/engine/contract.js +186 -0
- package/dist/engine/contract.js.map +1 -0
- package/dist/engine/events.d.ts +9 -0
- package/dist/engine/events.d.ts.map +1 -0
- package/dist/engine/events.js +23 -0
- package/dist/engine/events.js.map +1 -0
- package/dist/engine/go-engine.d.ts +23 -0
- package/dist/engine/go-engine.d.ts.map +1 -0
- package/dist/engine/go-engine.js +238 -0
- package/dist/engine/go-engine.js.map +1 -0
- package/dist/engine/groups.d.ts +159 -0
- package/dist/engine/groups.d.ts.map +1 -0
- package/dist/engine/groups.js +64 -0
- package/dist/engine/groups.js.map +1 -0
- package/dist/engine-binary.d.ts +5 -0
- package/dist/engine-binary.d.ts.map +1 -0
- package/dist/engine-binary.js +18 -0
- package/dist/engine-binary.js.map +1 -0
- package/dist/install/postinstall.d.ts +8 -0
- package/dist/install/postinstall.d.ts.map +1 -0
- package/dist/install/postinstall.js +62 -0
- package/dist/install/postinstall.js.map +1 -0
- package/dist/messenger.d.ts +64 -0
- package/dist/messenger.d.ts.map +1 -0
- package/dist/messenger.js +171 -0
- package/dist/messenger.js.map +1 -0
- package/dist/paths.d.ts +5 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +7 -0
- package/dist/paths.js.map +1 -0
- package/dist/program.d.ts +8 -0
- package/dist/program.d.ts.map +1 -0
- package/dist/program.js +114 -0
- package/dist/program.js.map +1 -0
- package/dist/reasons.d.ts +4 -0
- package/dist/reasons.d.ts.map +1 -0
- package/dist/reasons.js +13 -0
- package/dist/reasons.js.map +1 -0
- package/dist/update.d.ts +8 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +26 -0
- package/dist/update.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/install/postinstall.mjs +3 -0
- package/install/windows.ps1 +161 -0
- package/package.json +89 -4
- package/skills/whatsapp-cli/SKILL.md +290 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
/**
|
|
3
|
+
* What the engine and the adapter say to each other, in WhatsApp's own terms. The Go engine speaks it as JSON
|
|
4
|
+
* lines; `FakeEngine` speaks it in memory. Bump `PROTOCOL` on any change an older peer would misread — the
|
|
5
|
+
* adapter refuses an engine whose hello names another version.
|
|
6
|
+
*
|
|
7
|
+
* Ids are JIDs as strings. A one-to-one chat is always in its LID form (`…@lid`) when WhatsApp has one for the
|
|
8
|
+
* user, never in phone form: cli-core cannot merge two stored chats, so the engine picks the one id before it
|
|
9
|
+
* emits a chat (cli-private plans/2026-10-16-whatsapp-foundation.md, decision 3). Names are what the address book or the
|
|
10
|
+
* person set; a phone number is never a name.
|
|
11
|
+
*/
|
|
12
|
+
export const PROTOCOL = 10;
|
|
13
|
+
const jid = v.pipe(v.string(), v.includes("@"));
|
|
14
|
+
const time = v.pipe(v.string(), v.isoTimestamp());
|
|
15
|
+
export const waChat = v.strictObject({
|
|
16
|
+
jid,
|
|
17
|
+
name: v.nullable(v.string()),
|
|
18
|
+
kind: v.picklist(["dm", "self", "group", "newsletter", "broadcast"]),
|
|
19
|
+
unread: v.nullable(v.number()),
|
|
20
|
+
lastMessageAt: v.nullable(time),
|
|
21
|
+
participants: v.nullable(v.number()),
|
|
22
|
+
archived: v.optional(v.boolean()),
|
|
23
|
+
muted: v.optional(v.boolean()),
|
|
24
|
+
});
|
|
25
|
+
export const waContact = v.strictObject({ jid, name: v.nullable(v.string()) });
|
|
26
|
+
/**
|
|
27
|
+
* What whatsmeow needs to fetch and decrypt a file again, base64 where it is bytes. Stored as the attachment's opaque
|
|
28
|
+
* `providerRef`, so a download or a forward needs only the store. A channel's files are not encrypted and have no keys.
|
|
29
|
+
*/
|
|
30
|
+
export const waMediaRef = v.strictObject({
|
|
31
|
+
media: v.picklist(["image", "video", "audio", "document", "sticker"]),
|
|
32
|
+
directPath: v.pipe(v.string(), v.nonEmpty()),
|
|
33
|
+
mediaKey: v.optional(v.string()),
|
|
34
|
+
fileSha256: v.optional(v.string()),
|
|
35
|
+
fileEncSha256: v.optional(v.string()),
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* cli-core's Attachment in WhatsApp's terms: `photo`, `video`, `voice`, `audio`, `document`, `sticker`, `location`
|
|
39
|
+
* (`url` is a `geo:` link), `contact` (its name only — the card holds a phone number). `ref` only for a file.
|
|
40
|
+
*/
|
|
41
|
+
export const waAttachment = v.strictObject({
|
|
42
|
+
kind: v.picklist(["photo", "video", "voice", "audio", "document", "sticker", "location", "contact"]),
|
|
43
|
+
url: v.optional(v.string()),
|
|
44
|
+
width: v.optional(v.number()),
|
|
45
|
+
height: v.optional(v.number()),
|
|
46
|
+
title: v.optional(v.string()),
|
|
47
|
+
name: v.optional(v.string()),
|
|
48
|
+
size: v.optional(v.number()),
|
|
49
|
+
mime: v.optional(v.string()),
|
|
50
|
+
duration: v.optional(v.number()),
|
|
51
|
+
ref: v.optional(waMediaRef),
|
|
52
|
+
});
|
|
53
|
+
/**
|
|
54
|
+
* A poll as its message carries it. An answer's `id` is the start of the SHA-256 of its text, which is what a vote
|
|
55
|
+
* names on the wire. Votes arrive later, live as `vote` events or in a history push's `votes`; cli-core's store
|
|
56
|
+
* counts them.
|
|
57
|
+
*/
|
|
58
|
+
export const waPoll = v.strictObject({
|
|
59
|
+
question: v.string(),
|
|
60
|
+
answers: v.array(v.strictObject({ id: v.pipe(v.string(), v.nonEmpty()), text: v.string() })),
|
|
61
|
+
multiple: v.boolean(),
|
|
62
|
+
});
|
|
63
|
+
export const waMessage = v.strictObject({
|
|
64
|
+
id: v.pipe(v.string(), v.nonEmpty()),
|
|
65
|
+
chat: jid,
|
|
66
|
+
sender: v.nullable(jid),
|
|
67
|
+
senderName: v.nullable(v.string()),
|
|
68
|
+
fromMe: v.boolean(),
|
|
69
|
+
timestamp: time,
|
|
70
|
+
editedAt: v.nullable(time),
|
|
71
|
+
text: v.string(),
|
|
72
|
+
replyTo: v.nullable(v.string()),
|
|
73
|
+
attachments: v.optional(v.array(waAttachment)),
|
|
74
|
+
poll: v.optional(waPoll),
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* One person's newest choice in a poll: `selected` is the full SHA-256 of each chosen answer's text, and none takes
|
|
78
|
+
* the vote back. `voter` is in LID form like a sender, and the account's own vote is under `self()`. A vote in a
|
|
79
|
+
* history push carries its `poll`, since the push may not hold that poll; a live `vote` event has none. `votedAt` is
|
|
80
|
+
* when the voter cast it, by WhatsApp's clock: the store keeps a voter's newest vote by it.
|
|
81
|
+
*/
|
|
82
|
+
export const waVote = v.strictObject({
|
|
83
|
+
chat: jid,
|
|
84
|
+
message: v.pipe(v.string(), v.nonEmpty()),
|
|
85
|
+
voter: jid,
|
|
86
|
+
voterName: v.nullable(v.string()),
|
|
87
|
+
selected: v.array(v.string()),
|
|
88
|
+
votedAt: time,
|
|
89
|
+
poll: v.optional(waPoll),
|
|
90
|
+
});
|
|
91
|
+
/**
|
|
92
|
+
* One push from the phone. `kind` follows whatsmeow's sync types; the adapter treats them all alike. `votes` are the
|
|
93
|
+
* votes in the pushed polls, which the store saves with the push, not as `vote` events.
|
|
94
|
+
*/
|
|
95
|
+
export const waHistory = v.strictObject({
|
|
96
|
+
kind: v.picklist(["bootstrap", "recent", "full", "on_demand", "push_name", "other"]),
|
|
97
|
+
chats: v.array(waChat),
|
|
98
|
+
contacts: v.array(waContact),
|
|
99
|
+
messages: v.array(waMessage),
|
|
100
|
+
votes: v.array(waVote),
|
|
101
|
+
});
|
|
102
|
+
/**
|
|
103
|
+
* The phone's answer to `older`: the chat's messages sent before the anchor, as many as were asked or fewer. No
|
|
104
|
+
* messages and `more: false` is the chat's start. The engine never answers no messages with `more: true`: a batch of
|
|
105
|
+
* only messages the contract skips is asked past, since cli-core reads any empty page as the start.
|
|
106
|
+
*/
|
|
107
|
+
export const waOlder = v.strictObject({ messages: v.array(waMessage), more: v.boolean() });
|
|
108
|
+
/** `outdated`: WhatsApp refuses this engine's version. `stopped`: the engine process ended without being asked. */
|
|
109
|
+
export const connectionState = v.picklist([
|
|
110
|
+
"connected",
|
|
111
|
+
"disconnected",
|
|
112
|
+
"logged_out",
|
|
113
|
+
"replaced",
|
|
114
|
+
"banned",
|
|
115
|
+
"outdated",
|
|
116
|
+
"stopped",
|
|
117
|
+
]);
|
|
118
|
+
export const engineEvent = v.variant("event", [
|
|
119
|
+
v.strictObject({ event: v.literal("history"), history: waHistory }),
|
|
120
|
+
v.strictObject({ event: v.literal("message"), message: waMessage }),
|
|
121
|
+
v.strictObject({ event: v.literal("edit"), message: waMessage }),
|
|
122
|
+
v.strictObject({ event: v.literal("delete"), chat: jid, id: v.string() }),
|
|
123
|
+
v.strictObject({ event: v.literal("vote"), vote: waVote }),
|
|
124
|
+
v.strictObject({ event: v.literal("connection"), state: connectionState }),
|
|
125
|
+
]);
|
|
126
|
+
export const engineErrorCode = v.picklist([
|
|
127
|
+
"validation_error",
|
|
128
|
+
"authentication_error",
|
|
129
|
+
"permission_error",
|
|
130
|
+
"not_found",
|
|
131
|
+
"rate_limited",
|
|
132
|
+
"timeout",
|
|
133
|
+
"network_error",
|
|
134
|
+
"provider_error",
|
|
135
|
+
"provider_unavailable",
|
|
136
|
+
"outcome_unknown",
|
|
137
|
+
]);
|
|
138
|
+
/**
|
|
139
|
+
* Why, for the refusals an agent recovers from differently than their code says: another process holds the device
|
|
140
|
+
* (`device.in-use`), WhatsApp handed the login to another connection (`device.replaced`), logged the device out, refuses
|
|
141
|
+
* this version (`client.outdated`), banned the account, or asked it to slow down (`account.rate-limited`, never the
|
|
142
|
+
* engine's own lookup pace). The CLI registers each one (`src/reasons.ts`).
|
|
143
|
+
*/
|
|
144
|
+
export const engineReason = v.picklist([
|
|
145
|
+
"device.in-use",
|
|
146
|
+
"device.replaced",
|
|
147
|
+
"device.logged-out",
|
|
148
|
+
"client.outdated",
|
|
149
|
+
"account.banned",
|
|
150
|
+
"account.rate-limited",
|
|
151
|
+
]);
|
|
152
|
+
export const engineError = v.strictObject({
|
|
153
|
+
code: engineErrorCode,
|
|
154
|
+
message: v.string(),
|
|
155
|
+
reason: v.optional(engineReason),
|
|
156
|
+
});
|
|
157
|
+
/** The engine's first line: its protocol and the linked account (`self()`), or `null` before a login. */
|
|
158
|
+
export const hello = v.strictObject({
|
|
159
|
+
protocol: v.number(),
|
|
160
|
+
engine: v.string(),
|
|
161
|
+
version: v.string(),
|
|
162
|
+
self: v.nullable(jid),
|
|
163
|
+
});
|
|
164
|
+
export const waAccount = v.strictObject({ jid, name: v.nullable(v.string()) });
|
|
165
|
+
export const waChatCard = v.strictObject({ chat: waChat, members: v.nullable(v.array(waContact)) });
|
|
166
|
+
/**
|
|
167
|
+
* A code to show while linking: `qr` is the text of a QR code to draw, `pair` the eight characters to type on the
|
|
168
|
+
* phone. Either one links the account for as long as it is valid, so it is shown and never stored or logged.
|
|
169
|
+
*/
|
|
170
|
+
export const loginCode = v.strictObject({ login: v.picklist(["qr", "pair"]), code: v.pipe(v.string(), v.nonEmpty()) });
|
|
171
|
+
/** The most messages one `older` request asks the phone for, as WhatsApp's own clients ask. */
|
|
172
|
+
export const OLDER_MAX = 50;
|
|
173
|
+
/**
|
|
174
|
+
* A refusal from the engine, already in the closed list of codes. Its message is fixed wording: it never repeats a
|
|
175
|
+
* chat name, a JID or anything typed, since errors reach logs and run records.
|
|
176
|
+
*/
|
|
177
|
+
export class EngineError extends Error {
|
|
178
|
+
code;
|
|
179
|
+
reason;
|
|
180
|
+
constructor(code, message, reason) {
|
|
181
|
+
super(message);
|
|
182
|
+
this.code = code;
|
|
183
|
+
this.reason = reason;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/engine/contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EngineEvent } from "./contract.js";
|
|
2
|
+
type Kind = EngineEvent["event"];
|
|
3
|
+
/** Fans events out by kind, and keeps each one nobody listens for until a listener of its kind arrives. */
|
|
4
|
+
export declare const eventHub: () => {
|
|
5
|
+
emit: (event: EngineEvent) => void;
|
|
6
|
+
listen: (kinds: readonly Kind[], onEvent: (event: EngineEvent) => void) => (() => void);
|
|
7
|
+
};
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/engine/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,KAAK,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;AAOhC,2GAA2G;AAC3G,eAAO,MAAM,QAAQ;kBAIE,WAAW,KAAG,IAAI;oBAMhB,SAAS,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,KAAG,CAAC,MAAM,IAAI,CAAC;CAU7F,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Fans events out by kind, and keeps each one nobody listens for until a listener of its kind arrives. */
|
|
2
|
+
export const eventHub = () => {
|
|
3
|
+
const listeners = new Set();
|
|
4
|
+
let kept = [];
|
|
5
|
+
const emit = (event) => {
|
|
6
|
+
const takers = [...listeners].filter((listener) => listener.kinds.has(event.event));
|
|
7
|
+
if (takers.length === 0)
|
|
8
|
+
kept.push(event);
|
|
9
|
+
for (const listener of takers)
|
|
10
|
+
listener.onEvent(event);
|
|
11
|
+
};
|
|
12
|
+
const listen = (kinds, onEvent) => {
|
|
13
|
+
const listener = { kinds: new Set(kinds), onEvent };
|
|
14
|
+
listeners.add(listener);
|
|
15
|
+
const mine = kept.filter((event) => listener.kinds.has(event.event));
|
|
16
|
+
kept = kept.filter((event) => !listener.kinds.has(event.event));
|
|
17
|
+
for (const event of mine)
|
|
18
|
+
onEvent(event);
|
|
19
|
+
return () => listeners.delete(listener);
|
|
20
|
+
};
|
|
21
|
+
return { emit, listen };
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/engine/events.ts"],"names":[],"mappings":"AASA,2GAA2G;AAC3G,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAA;IACrC,IAAI,IAAI,GAAkB,EAAE,CAAA;IAE5B,MAAM,IAAI,GAAG,CAAC,KAAkB,EAAQ,EAAE;QACxC,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;QACnF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACzC,KAAK,MAAM,QAAQ,IAAI,MAAM;YAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACxD,CAAC,CAAA;IAED,MAAM,MAAM,GAAG,CAAC,KAAsB,EAAE,OAAqC,EAAgB,EAAE;QAC7F,MAAM,QAAQ,GAAa,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAA;QAC7D,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACvB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;QACpE,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;QAC/D,KAAK,MAAM,KAAK,IAAI,IAAI;YAAE,OAAO,CAAC,KAAK,CAAC,CAAA;QACxC,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACzC,CAAC,CAAA;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;AACzB,CAAC,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type WhatsAppEngine } from "./contract.js";
|
|
2
|
+
export interface GoEngineOptions {
|
|
3
|
+
/** The profile's `private.db`. */
|
|
4
|
+
storePath: string;
|
|
5
|
+
/** Who holds the connection — `serve`, `messages send` — named to anyone the lock refuses. */
|
|
6
|
+
holder: string;
|
|
7
|
+
/** Allows an empty store: this run links a new device. */
|
|
8
|
+
link?: boolean;
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
/** The engine's own diagnostics, fixed wording only. */
|
|
11
|
+
warn?: (line: string) => void;
|
|
12
|
+
/** Tests run a stand-in: the program, and the arguments before the engine's own. */
|
|
13
|
+
command?: {
|
|
14
|
+
file: string;
|
|
15
|
+
args: string[];
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Runs the Go engine as a child process and speaks JSON lines with it. It starts the engine and waits for its hello;
|
|
20
|
+
* a refusal there (the lock is held, the profile is not linked) rejects with the engine's own code and wording.
|
|
21
|
+
*/
|
|
22
|
+
export declare const startGoEngine: (options: GoEngineOptions) => Promise<WhatsAppEngine>;
|
|
23
|
+
//# sourceMappingURL=go-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go-engine.d.ts","sourceRoot":"","sources":["../../src/engine/go-engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAWL,KAAK,cAAc,EAMpB,MAAM,eAAe,CAAA;AAItB,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,SAAS,EAAE,MAAM,CAAA;IACjB,8FAA8F;IAC9F,MAAM,EAAE,MAAM,CAAA;IACd,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,wDAAwD;IACxD,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7B,oFAAoF;IACpF,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAA;CAC3C;AAkDD;;;GAGG;AACH,eAAO,MAAM,aAAa,YAAmB,eAAe,KAAG,OAAO,CAAC,cAAc,CAgLpF,CAAA"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createInterface } from "node:readline";
|
|
3
|
+
import * as v from "valibot";
|
|
4
|
+
import { engineBinary, enginePackage } from "../engine-binary.js";
|
|
5
|
+
import { EngineError, engineError, engineEvent, hello, loginCode, PROTOCOL, waAccount, waChat, waChatCard, waMessage, waOlder, } from "./contract.js";
|
|
6
|
+
import { eventHub } from "./events.js";
|
|
7
|
+
import { goGroups } from "./groups.js";
|
|
8
|
+
const HELLO_WAIT_MS = 15_000;
|
|
9
|
+
const CLOSE_WAIT_MS = 5_000;
|
|
10
|
+
const STOPPED = () => new EngineError("provider_unavailable", "the WhatsApp engine stopped unexpectedly", "engine.stopped");
|
|
11
|
+
/** Requests that change something on WhatsApp: cut by the engine's end, they may have gone out. */
|
|
12
|
+
const WRITES = new Set([
|
|
13
|
+
"send",
|
|
14
|
+
"sendMedia",
|
|
15
|
+
"forward",
|
|
16
|
+
"edit",
|
|
17
|
+
"revoke",
|
|
18
|
+
"react",
|
|
19
|
+
"read",
|
|
20
|
+
"createPoll",
|
|
21
|
+
"vote",
|
|
22
|
+
"createGroup",
|
|
23
|
+
"join",
|
|
24
|
+
"leave",
|
|
25
|
+
"updateGroup",
|
|
26
|
+
"resetLink",
|
|
27
|
+
"participants",
|
|
28
|
+
"answerRequest",
|
|
29
|
+
"block",
|
|
30
|
+
"logout",
|
|
31
|
+
]);
|
|
32
|
+
const CUT = () => new EngineError("outcome_unknown", "the WhatsApp engine stopped before WhatsApp confirmed the change; it may have gone through — check first", "engine.stopped-mid-write");
|
|
33
|
+
const missing = () => new EngineError("provider_unavailable", `the WhatsApp engine is not installed — ${enginePackage()} is missing: reinstall @wirecat/whatsapp-cli ` +
|
|
34
|
+
"without --omit=optional, or set WA_ENGINE to the engine's path");
|
|
35
|
+
/**
|
|
36
|
+
* Runs the Go engine as a child process and speaks JSON lines with it. It starts the engine and waits for its hello;
|
|
37
|
+
* a refusal there (the lock is held, the profile is not linked) rejects with the engine's own code and wording.
|
|
38
|
+
*/
|
|
39
|
+
export const startGoEngine = async (options) => {
|
|
40
|
+
const env = options.env ?? process.env;
|
|
41
|
+
const command = options.command ?? { file: engineBinary(env), args: [] };
|
|
42
|
+
const args = [
|
|
43
|
+
...command.args,
|
|
44
|
+
"--store",
|
|
45
|
+
options.storePath,
|
|
46
|
+
"--holder",
|
|
47
|
+
options.holder,
|
|
48
|
+
...(options.link ? ["--link"] : []),
|
|
49
|
+
];
|
|
50
|
+
const child = spawn(command.file, args, { env, stdio: ["pipe", "pipe", "pipe"], windowsHide: true });
|
|
51
|
+
const hub = eventHub();
|
|
52
|
+
const pending = new Map();
|
|
53
|
+
let nextId = 1;
|
|
54
|
+
let self = null;
|
|
55
|
+
let closing = false;
|
|
56
|
+
let exited = false;
|
|
57
|
+
let onCode;
|
|
58
|
+
let greet;
|
|
59
|
+
// A binary that never started fires "error" and no "exit".
|
|
60
|
+
const exit = new Promise((resolve) => {
|
|
61
|
+
child.once("close", () => resolve());
|
|
62
|
+
child.once("error", () => resolve());
|
|
63
|
+
});
|
|
64
|
+
const failAll = (error) => {
|
|
65
|
+
greet?.reject(error());
|
|
66
|
+
for (const waiting of pending.values())
|
|
67
|
+
waiting.reject(WRITES.has(waiting.op) ? CUT() : error());
|
|
68
|
+
pending.clear();
|
|
69
|
+
};
|
|
70
|
+
child.once("error", (error) => {
|
|
71
|
+
exited = true;
|
|
72
|
+
failAll(error.code === "ENOENT" || error.code === "EACCES" ? missing : STOPPED);
|
|
73
|
+
});
|
|
74
|
+
// "close", not "exit": an answer the engine wrote just before it ended is still in the pipe at "exit".
|
|
75
|
+
child.once("close", () => {
|
|
76
|
+
exited = true;
|
|
77
|
+
failAll(STOPPED);
|
|
78
|
+
if (!closing)
|
|
79
|
+
hub.emit({ event: "connection", state: "stopped" });
|
|
80
|
+
});
|
|
81
|
+
child.stdin?.on("error", () => { });
|
|
82
|
+
createInterface({ input: child.stderr }).on("line", (line) => options.warn?.(line));
|
|
83
|
+
const onLine = (line) => {
|
|
84
|
+
let value;
|
|
85
|
+
try {
|
|
86
|
+
value = JSON.parse(line);
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if ("hello" in value) {
|
|
92
|
+
const said = v.parse(hello, value.hello);
|
|
93
|
+
if (said.protocol !== PROTOCOL) {
|
|
94
|
+
greet?.reject(new EngineError("provider_unavailable", `the WhatsApp engine speaks protocol ${said.protocol}, this wa needs ${PROTOCOL} — reinstall wa`));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
self = said.self;
|
|
98
|
+
greet?.resolve();
|
|
99
|
+
}
|
|
100
|
+
else if ("refused" in value) {
|
|
101
|
+
const refused = v.parse(engineError, value.refused);
|
|
102
|
+
greet?.reject(new EngineError(refused.code, refused.message, refused.reason));
|
|
103
|
+
}
|
|
104
|
+
else if ("login" in value) {
|
|
105
|
+
onCode?.(v.parse(loginCode, value));
|
|
106
|
+
}
|
|
107
|
+
else if ("event" in value) {
|
|
108
|
+
const event = v.safeParse(engineEvent, value);
|
|
109
|
+
if (event.success)
|
|
110
|
+
hub.emit(event.output);
|
|
111
|
+
else
|
|
112
|
+
options.warn?.("the WhatsApp engine sent an event this wa cannot read; it was skipped");
|
|
113
|
+
}
|
|
114
|
+
else if (typeof value.id === "number") {
|
|
115
|
+
const waiting = pending.get(value.id);
|
|
116
|
+
pending.delete(value.id);
|
|
117
|
+
if (!waiting)
|
|
118
|
+
return;
|
|
119
|
+
if ("error" in value) {
|
|
120
|
+
const refused = v.parse(engineError, value.error);
|
|
121
|
+
waiting.reject(new EngineError(refused.code, refused.message, refused.reason));
|
|
122
|
+
}
|
|
123
|
+
else
|
|
124
|
+
waiting.resolve(value.ok);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
createInterface({ input: child.stdout }).on("line", onLine);
|
|
128
|
+
const request = (op, fields, schema) => {
|
|
129
|
+
if (exited)
|
|
130
|
+
return Promise.reject(STOPPED());
|
|
131
|
+
const id = nextId++;
|
|
132
|
+
const answer = new Promise((resolve, reject) => pending.set(id, { op, resolve, reject }));
|
|
133
|
+
child.stdin?.write(`${JSON.stringify({ id, op, ...fields })}\n`);
|
|
134
|
+
return answer.then((value) => v.parse(schema, value));
|
|
135
|
+
};
|
|
136
|
+
const close = async () => {
|
|
137
|
+
if (closing)
|
|
138
|
+
return exit;
|
|
139
|
+
closing = true;
|
|
140
|
+
if (!exited) {
|
|
141
|
+
const asked = request("close", {}, v.unknown()).catch(() => { });
|
|
142
|
+
child.stdin?.end();
|
|
143
|
+
await Promise.race([asked.then(() => exit), delay(CLOSE_WAIT_MS)]);
|
|
144
|
+
if (!exited)
|
|
145
|
+
child.kill("SIGKILL");
|
|
146
|
+
}
|
|
147
|
+
await exit;
|
|
148
|
+
};
|
|
149
|
+
try {
|
|
150
|
+
await new Promise((resolve, reject) => {
|
|
151
|
+
greet = { resolve, reject };
|
|
152
|
+
setTimeout(() => reject(new EngineError("timeout", "the WhatsApp engine did not start in time")), HELLO_WAIT_MS).unref();
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
await close();
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
greet = undefined;
|
|
161
|
+
}
|
|
162
|
+
let connecting;
|
|
163
|
+
const nothing = v.nullable(v.unknown());
|
|
164
|
+
return {
|
|
165
|
+
self: () => self,
|
|
166
|
+
ready: async (signal) => {
|
|
167
|
+
connecting ??= request("connect", {}, nothing);
|
|
168
|
+
await Promise.race([connecting, aborted(signal)]);
|
|
169
|
+
},
|
|
170
|
+
me: () => request("me", {}, waAccount),
|
|
171
|
+
directory: () => request("directory", {}, v.array(waChat)),
|
|
172
|
+
chat: (jid) => request("chat", { jid }, waChatCard),
|
|
173
|
+
send: ({ chat, text, id, replyTo, quoted }) => request("send", { chat, text, sendId: id, ...replyFields(replyTo, quoted) }, waMessage),
|
|
174
|
+
edit: (key, text) => request("edit", { ...keyFields(key), text }, waMessage),
|
|
175
|
+
revoke: async (key) => {
|
|
176
|
+
await request("revoke", keyFields(key), nothing);
|
|
177
|
+
},
|
|
178
|
+
react: async (key, emoji) => {
|
|
179
|
+
await request("react", { ...keyFields(key), emoji }, nothing);
|
|
180
|
+
},
|
|
181
|
+
markRead: async (key) => {
|
|
182
|
+
await request("read", keyFields(key), nothing);
|
|
183
|
+
},
|
|
184
|
+
sendMedia: ({ chat, text, id, replyTo, quoted, file }) => request("sendMedia", { chat, text, sendId: id, file, ...replyFields(replyTo, quoted) }, waMessage),
|
|
185
|
+
download: async (attachment, path) => {
|
|
186
|
+
await request("download", { attachment, path }, nothing);
|
|
187
|
+
},
|
|
188
|
+
forward: ({ chat, id, text, attachment }) => request("forward", { chat, sendId: id, text, ...(attachment ? { attachment } : {}) }, waMessage),
|
|
189
|
+
older: (anchor, count) => request("older", { ...keyFields(anchor), timestamp: anchor.timestamp, count }, waOlder),
|
|
190
|
+
createPoll: ({ chat, id, question, answers, multiple }) => request("createPoll", { chat, sendId: id, question, answers, ...(multiple ? { multiple } : {}) }, waMessage),
|
|
191
|
+
vote: async (key, answers) => {
|
|
192
|
+
await request("vote", { ...keyFields(key), answers }, nothing);
|
|
193
|
+
},
|
|
194
|
+
link: async (linking, show) => {
|
|
195
|
+
onCode = show;
|
|
196
|
+
try {
|
|
197
|
+
const account = await request("link", { ...linking }, waAccount);
|
|
198
|
+
self = account.jid;
|
|
199
|
+
return account;
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
onCode = undefined;
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
logout: async () => {
|
|
206
|
+
await request("logout", {}, nothing);
|
|
207
|
+
self = null;
|
|
208
|
+
},
|
|
209
|
+
listen: (kinds, onEvent) => hub.listen(kinds, onEvent),
|
|
210
|
+
close,
|
|
211
|
+
...goGroups(request),
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
const replyFields = (replyTo, quoted) => ({
|
|
215
|
+
...(replyTo === undefined ? {} : { replyTo }),
|
|
216
|
+
...(quoted === undefined
|
|
217
|
+
? {}
|
|
218
|
+
: {
|
|
219
|
+
quote: {
|
|
220
|
+
fromMe: quoted.fromMe,
|
|
221
|
+
text: quoted.text,
|
|
222
|
+
...(quoted.sender === null ? {} : { sender: quoted.sender }),
|
|
223
|
+
},
|
|
224
|
+
}),
|
|
225
|
+
});
|
|
226
|
+
const keyFields = ({ chat, id, fromMe, sender }) => ({
|
|
227
|
+
chat,
|
|
228
|
+
message: id,
|
|
229
|
+
fromMe,
|
|
230
|
+
...(sender === null ? {} : { sender }),
|
|
231
|
+
});
|
|
232
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms).unref());
|
|
233
|
+
const aborted = (signal) => new Promise((resolve) => {
|
|
234
|
+
if (signal.aborted)
|
|
235
|
+
resolve();
|
|
236
|
+
signal.addEventListener("abort", () => resolve(), { once: true });
|
|
237
|
+
});
|
|
238
|
+
//# sourceMappingURL=go-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"go-engine.js","sourceRoot":"","sources":["../../src/engine/go-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACjE,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,KAAK,EAEL,SAAS,EACT,QAAQ,EAKR,SAAS,EACT,MAAM,EACN,UAAU,EACV,SAAS,EACT,OAAO,GACR,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAgBtC,MAAM,aAAa,GAAG,MAAM,CAAA;AAC5B,MAAM,aAAa,GAAG,KAAK,CAAA;AAE3B,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,IAAI,WAAW,CAAC,sBAAsB,EAAE,0CAA0C,EAAE,gBAAgB,CAAC,CAAA;AAEvG,mGAAmG;AACnG,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC;IACrB,MAAM;IACN,WAAW;IACX,SAAS;IACT,MAAM;IACN,QAAQ;IACR,OAAO;IACP,MAAM;IACN,YAAY;IACZ,MAAM;IACN,aAAa;IACb,MAAM;IACN,OAAO;IACP,aAAa;IACb,WAAW;IACX,cAAc;IACd,eAAe;IACf,OAAO;IACP,QAAQ;CACT,CAAC,CAAA;AAEF,MAAM,GAAG,GAAG,GAAG,EAAE,CACf,IAAI,WAAW,CACb,iBAAiB,EACjB,0GAA0G,EAC1G,0BAA0B,CAC3B,CAAA;AAEH,MAAM,OAAO,GAAG,GAAG,EAAE,CACnB,IAAI,WAAW,CACb,sBAAsB,EACtB,0CAA0C,aAAa,EAAE,+CAA+C;IACtG,gEAAgE,CACnE,CAAA;AAQH;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,OAAwB,EAA2B,EAAE;IACvF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAA;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;IACxE,MAAM,IAAI,GAAG;QACX,GAAG,OAAO,CAAC,IAAI;QACf,SAAS;QACT,OAAO,CAAC,SAAS;QACjB,UAAU;QACV,OAAO,CAAC,MAAM;QACd,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACpC,CAAA;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAA;IACpG,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAA;IACtB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAA;IAC1C,IAAI,MAAM,GAAG,CAAC,CAAA;IACd,IAAI,IAAI,GAAkB,IAAI,CAAA;IAC9B,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,MAA+C,CAAA;IACnD,IAAI,KAA0E,CAAA;IAC9E,2DAA2D;IAC3D,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACzC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;QACpC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,CAAC,KAAkB,EAAE,EAAE;QACrC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;QACtB,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE;YAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;QAChG,OAAO,CAAC,KAAK,EAAE,CAAA;IACjB,CAAC,CAAA;IAED,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;QACnD,MAAM,GAAG,IAAI,CAAA;QACb,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;IACjF,CAAC,CAAC,CAAA;IACF,uGAAuG;IACvG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;QACvB,MAAM,GAAG,IAAI,CAAA;QACb,OAAO,CAAC,OAAO,CAAC,CAAA;QAChB,IAAI,CAAC,OAAO;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IACF,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;IAClC,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAA+B,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAE5G,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE;QAC9B,IAAI,KAA8B,CAAA;QAClC,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,OAAM;QACR,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;YACxC,IAAI,IAAI,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/B,KAAK,EAAE,MAAM,CACX,IAAI,WAAW,CACb,sBAAsB,EACtB,uCAAuC,IAAI,CAAC,QAAQ,mBAAmB,QAAQ,iBAAiB,CACjG,CACF,CAAA;gBACD,OAAM;YACR,CAAC;YACD,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;YAChB,KAAK,EAAE,OAAO,EAAE,CAAA;QAClB,CAAC;aAAM,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAA;YACnD,KAAK,EAAE,MAAM,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAC/E,CAAC;aAAM,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5B,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAA;QACrC,CAAC;aAAM,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;YAC7C,IAAI,KAAK,CAAC,OAAO;gBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;;gBACpC,OAAO,CAAC,IAAI,EAAE,CAAC,uEAAuE,CAAC,CAAA;QAC9F,CAAC;aAAM,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACxB,IAAI,CAAC,OAAO;gBAAE,OAAM;YACpB,IAAI,OAAO,IAAI,KAAK,EAAE,CAAC;gBACrB,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;gBACjD,OAAO,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;YAChF,CAAC;;gBAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAClC,CAAC;IACH,CAAC,CAAA;IACD,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAA+B,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEpF,MAAM,OAAO,GAAG,CAAI,EAAU,EAAE,MAA+B,EAAE,MAAmC,EAAc,EAAE;QAClH,IAAI,MAAM;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;QAC5C,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;QACnB,MAAM,MAAM,GAAG,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAClG,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAA;QAChE,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IACvD,CAAC,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;QACvB,IAAI,OAAO;YAAE,OAAO,IAAI,CAAA;QACxB,OAAO,GAAG,IAAI,CAAA;QACd,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;YAC/D,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,CAAA;YAClB,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;YAClE,IAAI,CAAC,MAAM;gBAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACpC,CAAC;QACD,MAAM,IAAI,CAAA;IACZ,CAAC,CAAA;IAED,IAAI,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,KAAK,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;YAC3B,UAAU,CACR,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,SAAS,EAAE,2CAA2C,CAAC,CAAC,EACrF,aAAa,CACd,CAAC,KAAK,EAAE,CAAA;QACX,CAAC,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,KAAK,EAAE,CAAA;QACb,MAAM,KAAK,CAAA;IACb,CAAC;YAAS,CAAC;QACT,KAAK,GAAG,SAAS,CAAA;IACnB,CAAC;IAED,IAAI,UAAwC,CAAA;IAC5C,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAA;IAEvC,OAAO;QACL,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACtB,UAAU,KAAK,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;YAC9C,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACnD,CAAC;QACD,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,SAAS,CAAC;QACtC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1D,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC;QACnD,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,CAC5C,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC;QACzF,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,CAAC;QAC5E,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACpB,MAAM,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;QAClD,CAAC;QACD,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;YAC1B,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,CAAA;QAC/D,CAAC;QACD,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACtB,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;QAChD,CAAC;QACD,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CACvD,OAAO,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC;QACpG,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE;YACnC,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAA;QAC1D,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAC1C,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC;QAClG,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC;QACjH,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CACxD,OAAO,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC;QAC9G,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;YAC3B,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAA;QAChE,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAsB,EAAE;YAChD,MAAM,GAAG,IAAI,CAAA;YACb,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,EAAE,SAAS,CAAC,CAAA;gBAChE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAA;gBAClB,OAAO,OAAO,CAAA;YAChB,CAAC;oBAAS,CAAC;gBACT,MAAM,GAAG,SAAS,CAAA;YACpB,CAAC;QACH,CAAC;QACD,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,MAAM,OAAO,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;YACpC,IAAI,GAAG,IAAI,CAAA;QACb,CAAC;QACD,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;QACtD,KAAK;QACL,GAAG,QAAQ,CAAC,OAAO,CAAC;KACrB,CAAA;AACH,CAAC,CAAA;AAED,MAAM,WAAW,GAAG,CAAC,OAA2B,EAAE,MAA2B,EAAE,EAAE,CAAC,CAAC;IACjF,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;IAC7C,GAAG,CAAC,MAAM,KAAK,SAAS;QACtB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC;YACE,KAAK,EAAE;gBACL,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;aAC7D;SACF,CAAC;CACP,CAAC,CAAA;AAEF,MAAM,SAAS,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAS,EAAE,EAAE,CAAC,CAAC;IAC1D,IAAI;IACJ,OAAO,EAAE,EAAE;IACX,MAAM;IACN,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;CACvC,CAAC,CAAA;AAEF,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;AAE7F,MAAM,OAAO,GAAG,CAAC,MAAmB,EAAE,EAAE,CACtC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;IAC5B,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IAC7B,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;AACnE,CAAC,CAAC,CAAA"}
|