@bananapus/nana-sdk-core 2.31.0 → 2.33.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/dist/cjs/review/index.d.ts +1 -0
- package/dist/cjs/review/index.d.ts.map +1 -1
- package/dist/cjs/review/index.js +1 -0
- package/dist/cjs/review/index.js.map +1 -1
- package/dist/cjs/review/messages.d.ts +18 -0
- package/dist/cjs/review/messages.d.ts.map +1 -1
- package/dist/cjs/review/messages.js +19 -1
- package/dist/cjs/review/messages.js.map +1 -1
- package/dist/cjs/review/writeHold.d.ts +211 -0
- package/dist/cjs/review/writeHold.d.ts.map +1 -0
- package/dist/cjs/review/writeHold.js +620 -0
- package/dist/cjs/review/writeHold.js.map +1 -0
- package/dist/cjs/review/writeRecovery.d.ts +113 -9
- package/dist/cjs/review/writeRecovery.d.ts.map +1 -1
- package/dist/cjs/review/writeRecovery.js +357 -49
- package/dist/cjs/review/writeRecovery.js.map +1 -1
- package/dist/cjs/safeService.d.ts +40 -0
- package/dist/cjs/safeService.d.ts.map +1 -1
- package/dist/cjs/safeService.js +69 -12
- package/dist/cjs/safeService.js.map +1 -1
- package/dist/esm/review/index.d.ts +1 -0
- package/dist/esm/review/index.d.ts.map +1 -1
- package/dist/esm/review/index.js +1 -0
- package/dist/esm/review/index.js.map +1 -1
- package/dist/esm/review/messages.d.ts +18 -0
- package/dist/esm/review/messages.d.ts.map +1 -1
- package/dist/esm/review/messages.js +18 -0
- package/dist/esm/review/messages.js.map +1 -1
- package/dist/esm/review/writeHold.d.ts +211 -0
- package/dist/esm/review/writeHold.d.ts.map +1 -0
- package/dist/esm/review/writeHold.js +613 -0
- package/dist/esm/review/writeHold.js.map +1 -0
- package/dist/esm/review/writeRecovery.d.ts +113 -9
- package/dist/esm/review/writeRecovery.d.ts.map +1 -1
- package/dist/esm/review/writeRecovery.js +355 -49
- package/dist/esm/review/writeRecovery.js.map +1 -1
- package/dist/esm/safeService.d.ts +40 -0
- package/dist/esm/safeService.d.ts.map +1 -1
- package/dist/esm/safeService.js +66 -12
- package/dist/esm/safeService.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,620 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WriteHoldBusyError = exports.WriteHoldNonceError = exports.WriteHeldError = void 0;
|
|
4
|
+
exports.createWriteHold = createWriteHold;
|
|
5
|
+
const viem_1 = require("viem");
|
|
6
|
+
const safeService_js_1 = require("../safeService.js");
|
|
7
|
+
const messages_js_1 = require("./messages.js");
|
|
8
|
+
const writeRecovery_js_1 = require("./writeRecovery.js");
|
|
9
|
+
/** A send was refused because the exact call is held; `state` says how. */
|
|
10
|
+
class WriteHeldError extends Error {
|
|
11
|
+
constructor(state) {
|
|
12
|
+
super(state.line);
|
|
13
|
+
this.state = state;
|
|
14
|
+
this.name = "WriteHeldError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.WriteHeldError = WriteHeldError;
|
|
18
|
+
/** The account's nonce couldn't be read, so the wallet never opened. */
|
|
19
|
+
class WriteHoldNonceError extends Error {
|
|
20
|
+
constructor(cause) {
|
|
21
|
+
super(messages_js_1.WRITE_HOLD_NONCE_LINE);
|
|
22
|
+
this.cause = cause;
|
|
23
|
+
this.name = "WriteHoldNonceError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.WriteHoldNonceError = WriteHoldNonceError;
|
|
27
|
+
/** The exact call is already being sent from another flow or tab. */
|
|
28
|
+
class WriteHoldBusyError extends Error {
|
|
29
|
+
constructor() {
|
|
30
|
+
super("This transaction is already open in another window.");
|
|
31
|
+
this.name = "WriteHoldBusyError";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.WriteHoldBusyError = WriteHoldBusyError;
|
|
35
|
+
const SETTLE_POLL_MS = 15_000;
|
|
36
|
+
/** A hash the network still hasn't seen this long after the wallet returned it was almost certainly never broadcast. */
|
|
37
|
+
const UNSEEN_HASH_MS = 30 * 60_000;
|
|
38
|
+
/** The 30 minutes have passed since the wallet returned the hash, or since it was first read. A clock that couldn't be saved (NaN) never runs out. */
|
|
39
|
+
function unseenTooLong(record) {
|
|
40
|
+
return (Date.now() - Number(record.submittedAt ?? record.firstSeenAt) >=
|
|
41
|
+
UNSEEN_HASH_MS);
|
|
42
|
+
}
|
|
43
|
+
/** A Safe write whose nonce another Safe transaction used: never released on its own. */
|
|
44
|
+
function safeReplaced(record) {
|
|
45
|
+
return {
|
|
46
|
+
status: "safe-replaced",
|
|
47
|
+
record,
|
|
48
|
+
hash: record.hash,
|
|
49
|
+
exit: true,
|
|
50
|
+
line: messages_js_1.WRITE_HOLD_SAFE_REPLACED_LINE,
|
|
51
|
+
warning: messages_js_1.WRITE_HOLD_HASHED_EXIT_LINE,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** A Safe write whose follower ended without proof: the exit at once. */
|
|
55
|
+
function safeUnproven(record) {
|
|
56
|
+
return {
|
|
57
|
+
status: "safe-unproven",
|
|
58
|
+
record,
|
|
59
|
+
hash: record.hash,
|
|
60
|
+
exit: true,
|
|
61
|
+
line: messages_js_1.WRITE_HOLD_SAFE_UNPROVEN_LINE,
|
|
62
|
+
warning: messages_js_1.WRITE_HOLD_HASHED_EXIT_LINE,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function unchecked(record) {
|
|
66
|
+
return {
|
|
67
|
+
status: "held-unchecked",
|
|
68
|
+
record,
|
|
69
|
+
hash: record.hash,
|
|
70
|
+
exit: true,
|
|
71
|
+
line: messages_js_1.WRITE_HOLD_UNCHECKED_LINE,
|
|
72
|
+
warning: messages_js_1.WRITE_HOLD_HASHED_EXIT_LINE,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/** About an hour of polls; a later state() looks again. */
|
|
76
|
+
const SETTLE_POLL_ATTEMPTS = 240;
|
|
77
|
+
function listenerKey(call) {
|
|
78
|
+
const scope = call.namespace ??
|
|
79
|
+
`${call.call.to}:${BigInt(call.call.value ?? 0)}:${call.call.data}`;
|
|
80
|
+
return `${call.chainId}:${call.account}:${scope}`.toLowerCase();
|
|
81
|
+
}
|
|
82
|
+
function clear(settled) {
|
|
83
|
+
return settled ? { status: "clear", settled } : { status: "clear" };
|
|
84
|
+
}
|
|
85
|
+
function ranExecuted(record, executionHash = record.executionHash, result) {
|
|
86
|
+
return {
|
|
87
|
+
status: "ran-executed",
|
|
88
|
+
record,
|
|
89
|
+
exit: false,
|
|
90
|
+
line: result === "failed" && !record.safe
|
|
91
|
+
? messages_js_1.WRITE_HOLD_REVERTED_LINE
|
|
92
|
+
: messages_js_1.SAFE_PROPOSAL_EXECUTED_LINE,
|
|
93
|
+
...(executionHash ? { executionHash } : {}),
|
|
94
|
+
...(result ? { result } : {}),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function pendingHash(record) {
|
|
98
|
+
return {
|
|
99
|
+
status: "pending-known-hash",
|
|
100
|
+
record,
|
|
101
|
+
hash: record.hash,
|
|
102
|
+
exit: false,
|
|
103
|
+
line: record.safe ? safeService_js_1.SAFE_PROPOSAL_AWAITING : messages_js_1.WRITE_HOLD_PENDING_LINE,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/** What the saved record alone says, without asking the chain. */
|
|
107
|
+
function classify(record) {
|
|
108
|
+
if (!record)
|
|
109
|
+
return clear();
|
|
110
|
+
if (record.replaced)
|
|
111
|
+
return safeReplaced(record);
|
|
112
|
+
if (record.executed)
|
|
113
|
+
return ranExecuted(record);
|
|
114
|
+
if (record.unproven)
|
|
115
|
+
return safeUnproven(record);
|
|
116
|
+
if (!record.hash)
|
|
117
|
+
return {
|
|
118
|
+
status: "held-no-hash",
|
|
119
|
+
record,
|
|
120
|
+
exit: true,
|
|
121
|
+
line: record.safe ||
|
|
122
|
+
(record.nonce !== undefined && record.fromBlock !== undefined)
|
|
123
|
+
? (0, messages_js_1.writeHeldMessage)()
|
|
124
|
+
: messages_js_1.WRITE_HOLD_UNCHECKED_LINE,
|
|
125
|
+
};
|
|
126
|
+
return pendingHash(record);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* One controller for held wallet writes, framework-free: every app wires its
|
|
130
|
+
* send, receipt and exit through it, so nothing is ever sent twice.
|
|
131
|
+
*
|
|
132
|
+
* - Holds live in the browser's storage, shared by tabs and kept across
|
|
133
|
+
* reloads, or in this tab's memory where storage is refused
|
|
134
|
+
* ({@link createHeldWriteStorage}); {@link reviewLine} is then the line the
|
|
135
|
+
* review shows. The wallet never opens without a hold.
|
|
136
|
+
* - A send checks, reserves and hands the call to the wallet under one lock
|
|
137
|
+
* per exact call (Web Locks, or the SDK's fallback), so two flows or tabs
|
|
138
|
+
* can never both reserve it.
|
|
139
|
+
* - A verified successful receipt releases at once. A revert holds until a
|
|
140
|
+
* canonical finalized block includes it. A Safe proposal proven executed
|
|
141
|
+
* is kept through reload until its execution's receipt settles it; one
|
|
142
|
+
* proven expired releases. One another Safe transaction replaced is never
|
|
143
|
+
* released on its own: the user's exit ends it.
|
|
144
|
+
*/
|
|
145
|
+
function createWriteHold(options = {}) {
|
|
146
|
+
const storage = options.storage ?? (0, writeRecovery_js_1.createHeldWriteStorage)();
|
|
147
|
+
const interval = options.settle?.intervalMs ?? SETTLE_POLL_MS;
|
|
148
|
+
const attempts = options.settle?.attempts ?? SETTLE_POLL_ATTEMPTS;
|
|
149
|
+
const listeners = new Map();
|
|
150
|
+
const peekers = new Map();
|
|
151
|
+
const timers = new Map();
|
|
152
|
+
let onStorage;
|
|
153
|
+
function emit(key, state) {
|
|
154
|
+
for (const listener of listeners.get(key) ?? [])
|
|
155
|
+
listener(state);
|
|
156
|
+
}
|
|
157
|
+
/** Another tab changed a hold: every subscribed call shows what it holds now. */
|
|
158
|
+
function watchTabs() {
|
|
159
|
+
if (onStorage || typeof globalThis.addEventListener !== "function")
|
|
160
|
+
return;
|
|
161
|
+
onStorage = (event) => {
|
|
162
|
+
if (event.key && !event.key.startsWith("nana-sdk:reviewed-write"))
|
|
163
|
+
return;
|
|
164
|
+
for (const [key, peek] of peekers) {
|
|
165
|
+
try {
|
|
166
|
+
emit(key, peek());
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
/* An unreadable record is shown at its next state(). */
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
globalThis.addEventListener("storage", onStorage);
|
|
174
|
+
}
|
|
175
|
+
function open(call) {
|
|
176
|
+
const recovery = (0, writeRecovery_js_1.createBrowserWriteRecovery)(call, {
|
|
177
|
+
storage,
|
|
178
|
+
locks: options.locks,
|
|
179
|
+
});
|
|
180
|
+
const key = listenerKey(call);
|
|
181
|
+
/** The effect read the last state() was given: the exit asks it again. */
|
|
182
|
+
let lastEffect;
|
|
183
|
+
const peek = () => classify(recovery.read());
|
|
184
|
+
const shown = (state) => (emit(key, state), state);
|
|
185
|
+
async function locked(work, wait) {
|
|
186
|
+
let entered = false;
|
|
187
|
+
try {
|
|
188
|
+
return {
|
|
189
|
+
value: await recovery.withLock(async () => {
|
|
190
|
+
entered = true;
|
|
191
|
+
return work();
|
|
192
|
+
}, wait),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
if (entered)
|
|
197
|
+
throw error;
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/** End exactly `record` (read under this lock), committing a hash kept only in memory first. */
|
|
202
|
+
function release(record) {
|
|
203
|
+
try {
|
|
204
|
+
recovery.clear(recovery.submitted(record.hash, record));
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function follow(client, id, left = attempts) {
|
|
212
|
+
if (timers.has(id) || left <= 0)
|
|
213
|
+
return;
|
|
214
|
+
timers.set(id, setTimeout(() => {
|
|
215
|
+
void state(client)
|
|
216
|
+
.catch(() => null)
|
|
217
|
+
.then((next) => {
|
|
218
|
+
timers.delete(id);
|
|
219
|
+
if (next?.status === "ran-executed")
|
|
220
|
+
follow(client, id, left - 1);
|
|
221
|
+
});
|
|
222
|
+
}, interval));
|
|
223
|
+
}
|
|
224
|
+
async function settle(record, receipt, client, proof) {
|
|
225
|
+
const verdict = await (0, writeRecovery_js_1.verifyReviewedWriteReceipt)(client, record, receipt, proof).catch(() => null);
|
|
226
|
+
if (verdict && release(record))
|
|
227
|
+
return clear({
|
|
228
|
+
result: verdict,
|
|
229
|
+
hash: receipt.transactionHash.toLowerCase(),
|
|
230
|
+
});
|
|
231
|
+
if (!record.safe &&
|
|
232
|
+
receipt.status === "reverted" &&
|
|
233
|
+
receipt.transactionHash.toLowerCase() === record.hash) {
|
|
234
|
+
follow(client, record.id);
|
|
235
|
+
return ranExecuted(record, record.hash, "failed");
|
|
236
|
+
}
|
|
237
|
+
// An authenticated Safe failure that isn't final yet: saved, never an exit.
|
|
238
|
+
// (A verified success has already settled above.)
|
|
239
|
+
const ran = record.safe &&
|
|
240
|
+
(await (0, writeRecovery_js_1.verifyReviewedWriteReceipt)(client, record, receipt, proof, { finality: false }).catch(() => null));
|
|
241
|
+
if (ran === "failed") {
|
|
242
|
+
const hash = receipt.transactionHash.toLowerCase();
|
|
243
|
+
const saved = recovery.executed(record, hash);
|
|
244
|
+
follow(client, saved.id);
|
|
245
|
+
return ranExecuted(saved, hash, "failed");
|
|
246
|
+
}
|
|
247
|
+
if (record.executed)
|
|
248
|
+
follow(client, record.id);
|
|
249
|
+
return classify(recovery.read());
|
|
250
|
+
}
|
|
251
|
+
/** The authenticated nonce of a Safe proposal, from Safe's service. */
|
|
252
|
+
async function proposalNonceOf(record) {
|
|
253
|
+
try {
|
|
254
|
+
const proposal = await (0, safeService_js_1.readSafeTransaction)(record.chainId, record.account, record.hash, options.safeService);
|
|
255
|
+
return (0, safeService_js_1.safeTransactionMessage)(proposal).nonce;
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/** Follow a saved execution's receipt; null while the node has none. */
|
|
262
|
+
async function execution(record, client) {
|
|
263
|
+
const receipt = await client
|
|
264
|
+
.getTransactionReceipt({ hash: record.executionHash })
|
|
265
|
+
.catch(() => null);
|
|
266
|
+
return receipt ? settle(record, receipt, client) : null;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* A direct execution whose receipt is gone: another transaction the
|
|
270
|
+
* executor sent at its nonce, at a canonical finalized block, means it
|
|
271
|
+
* never ran. History that can't be read keeps it held, and after 30
|
|
272
|
+
* minutes with the transaction unknown it gets the unchecked exit.
|
|
273
|
+
*/
|
|
274
|
+
async function reconcileDirect(record, client) {
|
|
275
|
+
const used = record.sentFrom && record.sentNonce !== undefined
|
|
276
|
+
? await (0, writeRecovery_js_1.findTransactionAtNonce)(client, record.sentFrom, BigInt(record.sentNonce))
|
|
277
|
+
: null;
|
|
278
|
+
// Another transaction at that nonce may have run the call too.
|
|
279
|
+
if (used && used.hash !== record.hash)
|
|
280
|
+
return safeReplaced(recovery.replacedOnChain(record));
|
|
281
|
+
if (used ||
|
|
282
|
+
!unseenTooLong(record) ||
|
|
283
|
+
!(await client.getTransaction({ hash: record.hash }).then(() => false, (error) => error?.name === "TransactionNotFoundError")))
|
|
284
|
+
return null;
|
|
285
|
+
// A proof that can't be dropped keeps the exit refusing it.
|
|
286
|
+
return unchecked(recovery.unexecuted(record));
|
|
287
|
+
}
|
|
288
|
+
async function safeState(saved, client) {
|
|
289
|
+
let record = saved;
|
|
290
|
+
const hash = record.hash;
|
|
291
|
+
if (!hash || record.replaced)
|
|
292
|
+
return classify(record);
|
|
293
|
+
if (record.submittedAt === undefined)
|
|
294
|
+
record = recovery.firstSeen(record);
|
|
295
|
+
// The wallet's reply may be the execution itself (run at once).
|
|
296
|
+
if (!record.executed) {
|
|
297
|
+
const atOnce = await client
|
|
298
|
+
.getTransactionReceipt({ hash })
|
|
299
|
+
.catch(() => null);
|
|
300
|
+
if (atOnce) {
|
|
301
|
+
const settled = await settle(record, atOnce, client);
|
|
302
|
+
if (settled.status === "clear")
|
|
303
|
+
return settled;
|
|
304
|
+
// It ran; only its verified result (a failure at finality) ends it.
|
|
305
|
+
record = recovery.executed(record, hash);
|
|
306
|
+
// Who sent it at which nonce proves a canonical replacement later.
|
|
307
|
+
const sent = await client.getTransaction({ hash }).catch(() => null);
|
|
308
|
+
if (sent?.hash?.toLowerCase() === hash && (0, viem_1.isAddress)(sent.from))
|
|
309
|
+
record = recovery.sentBy(record, sent.from, BigInt(sent.nonce));
|
|
310
|
+
follow(client, record.id);
|
|
311
|
+
return ranExecuted(record);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
else if (record.executionHash) {
|
|
315
|
+
const settled = await execution(record, client);
|
|
316
|
+
if (settled?.status === "clear")
|
|
317
|
+
return settled;
|
|
318
|
+
if (record.executionHash === hash) {
|
|
319
|
+
if (!settled) {
|
|
320
|
+
const reconciled = await reconcileDirect(record, client);
|
|
321
|
+
if (reconciled)
|
|
322
|
+
return reconciled;
|
|
323
|
+
}
|
|
324
|
+
follow(client, record.id);
|
|
325
|
+
return settled ?? ranExecuted(record);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// The chain's proof, from the proposal's nonce: Safe's service is asked
|
|
329
|
+
// only for the nonce, once, and for an expiry.
|
|
330
|
+
if (record.safeNonce === undefined) {
|
|
331
|
+
const nonce = await proposalNonceOf(record);
|
|
332
|
+
if (nonce !== null)
|
|
333
|
+
record = recovery.proposalNonce(record, nonce);
|
|
334
|
+
}
|
|
335
|
+
const end = (record.safeNonce !== undefined &&
|
|
336
|
+
(await (0, safeService_js_1.provenSafeProposalEnd)(client, record.account, hash, BigInt(record.safeNonce)))) ||
|
|
337
|
+
(await (0, safeService_js_1.lookAtSafeProposalEnd)(client, record.chainId, record.account, hash, options.safeService));
|
|
338
|
+
// Another Safe transaction took its nonce, even after a saved execution
|
|
339
|
+
// was reorganized away. It may have run the call too: the exit, never a release.
|
|
340
|
+
if (end.look === "replaced")
|
|
341
|
+
return safeReplaced(recovery.replacedOnChain(record));
|
|
342
|
+
if (end.look === "expired" && !record.executed) {
|
|
343
|
+
const expired = await (0, writeRecovery_js_1.verifyReviewedWriteExpiry)(client, record, options.safeService).catch(() => false);
|
|
344
|
+
if (expired && release(record))
|
|
345
|
+
return clear({ result: "expired" });
|
|
346
|
+
}
|
|
347
|
+
if (end.look === "executed" &&
|
|
348
|
+
(!record.executed ||
|
|
349
|
+
(end.execution &&
|
|
350
|
+
end.execution.executionHash !== record.executionHash))) {
|
|
351
|
+
record = recovery.executed(record, end.execution?.executionHash);
|
|
352
|
+
if (record.executionHash) {
|
|
353
|
+
const settled = await execution(record, client);
|
|
354
|
+
if (settled)
|
|
355
|
+
return settled;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (!record.executed &&
|
|
359
|
+
!record.unproven &&
|
|
360
|
+
record.safeNonce === undefined &&
|
|
361
|
+
unseenTooLong(record))
|
|
362
|
+
return unchecked(record);
|
|
363
|
+
if (record.executed)
|
|
364
|
+
follow(client, record.id);
|
|
365
|
+
return classify(record);
|
|
366
|
+
}
|
|
367
|
+
async function inspect(client, effect) {
|
|
368
|
+
let record = recovery.read();
|
|
369
|
+
if (!record)
|
|
370
|
+
return clear();
|
|
371
|
+
// No evidence from another chain.
|
|
372
|
+
if ((await client.getChainId().catch(() => null)) !== record.chainId)
|
|
373
|
+
return classify(record);
|
|
374
|
+
if (record.safe)
|
|
375
|
+
return safeState(record, client);
|
|
376
|
+
const check = await recovery
|
|
377
|
+
.resolve(client, effect ? { effect } : undefined)
|
|
378
|
+
.catch(() => null);
|
|
379
|
+
record = recovery.read();
|
|
380
|
+
if (!record)
|
|
381
|
+
return clear();
|
|
382
|
+
if (check?.status === "sent") {
|
|
383
|
+
const receipt = await client
|
|
384
|
+
.getTransactionReceipt({ hash: check.hash })
|
|
385
|
+
.catch(() => null);
|
|
386
|
+
return receipt ? settle(record, receipt, client) : pendingHash(record);
|
|
387
|
+
}
|
|
388
|
+
// A hash saved before its clock existed starts it now.
|
|
389
|
+
if (record.hash && record.submittedAt === undefined)
|
|
390
|
+
record = recovery.firstSeen(record);
|
|
391
|
+
// The app's effect read only changes the line, and offers the exit.
|
|
392
|
+
if (check?.status === "pending" && check.effect)
|
|
393
|
+
return {
|
|
394
|
+
status: "looks-done",
|
|
395
|
+
record,
|
|
396
|
+
exit: true,
|
|
397
|
+
line: messages_js_1.WRITE_HOLD_LOOKS_DONE_LINE,
|
|
398
|
+
...(record.hash
|
|
399
|
+
? { hash: record.hash, warning: messages_js_1.WRITE_HOLD_HASHED_EXIT_LINE }
|
|
400
|
+
: {}),
|
|
401
|
+
};
|
|
402
|
+
if (record.hash &&
|
|
403
|
+
record.sentNonce !== undefined &&
|
|
404
|
+
check?.status === "pending" &&
|
|
405
|
+
check.usedBy)
|
|
406
|
+
return {
|
|
407
|
+
status: "dropped-proven",
|
|
408
|
+
record,
|
|
409
|
+
hash: record.hash,
|
|
410
|
+
usedBy: check.usedBy,
|
|
411
|
+
exit: true,
|
|
412
|
+
line: (0, messages_js_1.writeHeldMessage)(),
|
|
413
|
+
warning: messages_js_1.WRITE_HOLD_HASHED_EXIT_LINE,
|
|
414
|
+
};
|
|
415
|
+
if (record.hash &&
|
|
416
|
+
record.sentNonce === undefined &&
|
|
417
|
+
(record.nonce === undefined ||
|
|
418
|
+
record.fromBlock === undefined ||
|
|
419
|
+
unseenTooLong(record)) &&
|
|
420
|
+
(await client.getTransaction({ hash: record.hash }).then(() => false, (error) => error?.name === "TransactionNotFoundError")))
|
|
421
|
+
return unchecked(record);
|
|
422
|
+
return classify(record);
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* The one answer for this call: what is held, asking the chain. A flow
|
|
426
|
+
* sending it right now leaves the saved record's own answer.
|
|
427
|
+
*/
|
|
428
|
+
async function state(client, checks = {}) {
|
|
429
|
+
lastEffect = checks.effect;
|
|
430
|
+
const result = await locked(() => inspect(client, checks.effect), false);
|
|
431
|
+
return shown(result ? result.value : peek());
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
state,
|
|
435
|
+
/** What the saved record alone says, without asking the chain. */
|
|
436
|
+
peek,
|
|
437
|
+
/** Every state this controller reads or makes for the call, and other tabs' changes. */
|
|
438
|
+
subscribe(listener) {
|
|
439
|
+
let set = listeners.get(key);
|
|
440
|
+
if (!set)
|
|
441
|
+
listeners.set(key, (set = new Set()));
|
|
442
|
+
set.add(listener);
|
|
443
|
+
peekers.set(key, peek);
|
|
444
|
+
watchTabs();
|
|
445
|
+
return () => {
|
|
446
|
+
set.delete(listener);
|
|
447
|
+
if (!set.size) {
|
|
448
|
+
listeners.delete(key);
|
|
449
|
+
peekers.delete(key);
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
},
|
|
453
|
+
/**
|
|
454
|
+
* Send the call under its hold. A held call throws
|
|
455
|
+
* {@link WriteHeldError} before anything opens, and another flow or tab
|
|
456
|
+
* sending it throws {@link WriteHoldBusyError}. `run` hands the
|
|
457
|
+
* {@link WriteHoldGate} to its wallet boundary. A write that may have
|
|
458
|
+
* reached the wallet stays held whatever `run` throws.
|
|
459
|
+
*/
|
|
460
|
+
async send(client, run) {
|
|
461
|
+
let attempt;
|
|
462
|
+
const gate = {
|
|
463
|
+
async beforeSend(actualCall) {
|
|
464
|
+
let evidence;
|
|
465
|
+
if (!call.safe) {
|
|
466
|
+
// The nonce proves later what became of the write: one retry, or nothing is sent.
|
|
467
|
+
const read = () => (0, writeRecovery_js_1.readReviewedWriteNonce)(client, call.account);
|
|
468
|
+
try {
|
|
469
|
+
evidence = await read().catch(read);
|
|
470
|
+
}
|
|
471
|
+
catch (cause) {
|
|
472
|
+
throw new WriteHoldNonceError(cause);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
try {
|
|
476
|
+
attempt = recovery.reserve(actualCall, evidence);
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
const now = peek();
|
|
480
|
+
if (now.status !== "clear")
|
|
481
|
+
throw new WriteHeldError(now);
|
|
482
|
+
throw error;
|
|
483
|
+
}
|
|
484
|
+
shown(peek());
|
|
485
|
+
},
|
|
486
|
+
afterSubmit(hash, proposal) {
|
|
487
|
+
if (!attempt)
|
|
488
|
+
throw new Error("Hold the write before the wallet opens.");
|
|
489
|
+
try {
|
|
490
|
+
attempt = recovery.submitted(hash, attempt);
|
|
491
|
+
}
|
|
492
|
+
catch (error) {
|
|
493
|
+
if (!(error instanceof writeRecovery_js_1.SubmittedWritePersistenceError))
|
|
494
|
+
throw error;
|
|
495
|
+
attempt = error.record;
|
|
496
|
+
}
|
|
497
|
+
// The proposal the app made, if it hashes to the reply: its nonce.
|
|
498
|
+
if (call.safe && proposal)
|
|
499
|
+
try {
|
|
500
|
+
(0, safeService_js_1.canonicalSafeTxHash)(call.chainId, call.account, proposal, hash);
|
|
501
|
+
attempt = recovery.proposalNonce(attempt, (0, safeService_js_1.safeTransactionMessage)(proposal).nonce);
|
|
502
|
+
}
|
|
503
|
+
catch {
|
|
504
|
+
/* Not this proposal: the service is asked later. */
|
|
505
|
+
}
|
|
506
|
+
shown(classify(attempt));
|
|
507
|
+
},
|
|
508
|
+
onRejected() {
|
|
509
|
+
recovery.rejected();
|
|
510
|
+
attempt = undefined;
|
|
511
|
+
shown(peek());
|
|
512
|
+
},
|
|
513
|
+
};
|
|
514
|
+
const result = await locked(async () => {
|
|
515
|
+
const now = shown(await inspect(client));
|
|
516
|
+
if (now.status !== "clear")
|
|
517
|
+
throw new WriteHeldError(now);
|
|
518
|
+
return run(gate);
|
|
519
|
+
}, false);
|
|
520
|
+
if (!result)
|
|
521
|
+
throw new WriteHoldBusyError();
|
|
522
|
+
return result.value;
|
|
523
|
+
},
|
|
524
|
+
/**
|
|
525
|
+
* The user checked their wallet. Only an exit-offered `snapshot`, the
|
|
526
|
+
* state the user saw, is released, after the chain is asked once more:
|
|
527
|
+
* any change refuses it, and a confirmation that landed meanwhile wins.
|
|
528
|
+
* `released` true: send again.
|
|
529
|
+
*/
|
|
530
|
+
async exit(snapshot, acknowledgement, client) {
|
|
531
|
+
if (acknowledgement?.checkedWallet !== true)
|
|
532
|
+
throw new Error("Release a held write only after the user confirms they checked their wallet.");
|
|
533
|
+
const result = await locked(async () => {
|
|
534
|
+
const now = await inspect(client, lastEffect);
|
|
535
|
+
if (snapshot.status === "clear" ||
|
|
536
|
+
now.status === "clear" ||
|
|
537
|
+
!now.exit ||
|
|
538
|
+
now.status !== snapshot.status ||
|
|
539
|
+
JSON.stringify(now.record) !== JSON.stringify(snapshot.record))
|
|
540
|
+
return { released: false, state: now };
|
|
541
|
+
try {
|
|
542
|
+
recovery.abandon(snapshot.record, { checkedWallet: true });
|
|
543
|
+
}
|
|
544
|
+
catch {
|
|
545
|
+
return { released: false, state: peek() };
|
|
546
|
+
}
|
|
547
|
+
return { released: true, state: clear() };
|
|
548
|
+
}, true);
|
|
549
|
+
const ended = result?.value ?? { released: false, state: peek() };
|
|
550
|
+
shown(ended.state);
|
|
551
|
+
return ended;
|
|
552
|
+
},
|
|
553
|
+
/**
|
|
554
|
+
* A receipt for the held write: an ordinary write's own hash, or a Safe
|
|
555
|
+
* proposal's execution (`proof`: its whole batch). It releases only once
|
|
556
|
+
* verified, and a revert only once final.
|
|
557
|
+
*/
|
|
558
|
+
async onReceipt(receipt, client, proof) {
|
|
559
|
+
const result = await locked(async () => {
|
|
560
|
+
const record = recovery.read();
|
|
561
|
+
if (!record ||
|
|
562
|
+
(!record.safe &&
|
|
563
|
+
record.hash !== receipt?.transactionHash?.toLowerCase()))
|
|
564
|
+
return classify(record);
|
|
565
|
+
return settle(record, receipt, client, proof);
|
|
566
|
+
}, true);
|
|
567
|
+
return shown(result?.value ?? peek());
|
|
568
|
+
},
|
|
569
|
+
/**
|
|
570
|
+
* The app's Safe follower ended without proof (its watch gave up, or
|
|
571
|
+
* the service lost the proposal). `proposalHash`, when given, must name
|
|
572
|
+
* the held one. It is held with the exit at once, through reloads;
|
|
573
|
+
* authenticated evidence that arrives later still settles it.
|
|
574
|
+
*/
|
|
575
|
+
async onUnproven(client, proposalHash) {
|
|
576
|
+
const result = await locked(async () => {
|
|
577
|
+
const record = recovery.read();
|
|
578
|
+
if (record?.safe &&
|
|
579
|
+
record.hash &&
|
|
580
|
+
(proposalHash === undefined ||
|
|
581
|
+
proposalHash.toLowerCase() === record.hash))
|
|
582
|
+
recovery.unprovenEnd(record);
|
|
583
|
+
return inspect(client);
|
|
584
|
+
}, true);
|
|
585
|
+
return shown(result?.value ?? peek());
|
|
586
|
+
},
|
|
587
|
+
/**
|
|
588
|
+
* The app's own proof that the held Safe proposal ran, with its
|
|
589
|
+
* execution's transaction when known. Kept until its result settles it.
|
|
590
|
+
*/
|
|
591
|
+
async onExecuted(client, executionHash) {
|
|
592
|
+
const result = await locked(async () => {
|
|
593
|
+
const record = recovery.read();
|
|
594
|
+
if (!record?.safe || !record.hash)
|
|
595
|
+
return classify(record);
|
|
596
|
+
recovery.executed(record, executionHash);
|
|
597
|
+
return inspect(client);
|
|
598
|
+
}, true);
|
|
599
|
+
return shown(result?.value ?? peek());
|
|
600
|
+
},
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
return {
|
|
604
|
+
open,
|
|
605
|
+
/** Whether holds outlive this tab right now. */
|
|
606
|
+
durable: () => storage.durable(),
|
|
607
|
+
/** The review's line while holds last only in this tab, or null. */
|
|
608
|
+
reviewLine: () => (storage.durable() ? null : messages_js_1.WRITE_HOLD_IN_TAB_LINE),
|
|
609
|
+
/** Stop every settle poll and the tab listener (tests, teardown). */
|
|
610
|
+
dispose() {
|
|
611
|
+
for (const timer of timers.values())
|
|
612
|
+
clearTimeout(timer);
|
|
613
|
+
timers.clear();
|
|
614
|
+
if (onStorage)
|
|
615
|
+
globalThis.removeEventListener?.("storage", onStorage);
|
|
616
|
+
onStorage = undefined;
|
|
617
|
+
},
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
//# sourceMappingURL=writeHold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeHold.js","sourceRoot":"","sources":["../../../src/review/writeHold.ts"],"names":[],"mappings":";;;AAgSA,0CAikBC;AAj2BD,+BAKc;AACd,sDAS2B;AAC3B,+CAYuB;AACvB,yDAW4B;AAkF5B,2EAA2E;AAC3E,MAAa,cAAe,SAAQ,KAAK;IAEvC,YAAqB,KAAqB;QACxC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QADC,UAAK,GAAL,KAAK,CAAgB;QADjC,SAAI,GAAG,gBAAgB,CAAC;IAGjC,CAAC;CACF;AALD,wCAKC;AAED,wEAAwE;AACxE,MAAa,mBAAoB,SAAQ,KAAK;IAE5C,YAAqB,KAAc;QACjC,KAAK,CAAC,mCAAqB,CAAC,CAAC;QADV,UAAK,GAAL,KAAK,CAAS;QAD1B,SAAI,GAAG,qBAAqB,CAAC;IAGtC,CAAC;CACF;AALD,kDAKC;AAED,qEAAqE;AACrE,MAAa,kBAAmB,SAAQ,KAAK;IAE3C;QACE,KAAK,CAAC,qDAAqD,CAAC,CAAC;QAFtD,SAAI,GAAG,oBAAoB,CAAC;IAGrC,CAAC;CACF;AALD,gDAKC;AAmBD,MAAM,cAAc,GAAG,MAAM,CAAC;AAC9B,wHAAwH;AACxH,MAAM,cAAc,GAAG,EAAE,GAAG,MAAM,CAAC;AAEnC,sJAAsJ;AACtJ,SAAS,aAAa,CAAC,MAAmC;IACxD,OAAO,CACL,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;QAC7D,cAAc,CACf,CAAC;AACJ,CAAC;AAED,yFAAyF;AACzF,SAAS,YAAY,CAAC,MAAmC;IACvD,OAAO;QACL,MAAM,EAAE,eAAe;QACvB,MAAM;QACN,IAAI,EAAE,MAAM,CAAC,IAAK;QAClB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,2CAA6B;QACnC,OAAO,EAAE,yCAA2B;KACrC,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,SAAS,YAAY,CAAC,MAAmC;IACvD,OAAO;QACL,MAAM,EAAE,eAAe;QACvB,MAAM;QACN,IAAI,EAAE,MAAM,CAAC,IAAK;QAClB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,2CAA6B;QACnC,OAAO,EAAE,yCAA2B;KACrC,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,MAAmC;IACpD,OAAO;QACL,MAAM,EAAE,gBAAgB;QACxB,MAAM;QACN,IAAI,EAAE,MAAM,CAAC,IAAK;QAClB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,uCAAyB;QAC/B,OAAO,EAAE,yCAA2B;KACrC,CAAC;AACJ,CAAC;AACD,2DAA2D;AAC3D,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,SAAS,WAAW,CAAC,IAAgC;IACnD,MAAM,KAAK,GACT,IAAI,CAAC,SAAS;QACd,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACtE,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;AAClE,CAAC;AAED,SAAS,KAAK,CAAC,OAA0B;IACvC,OAAO,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACtE,CAAC;AAED,SAAS,WAAW,CAClB,MAAmC,EACnC,aAAa,GAAG,MAAM,CAAC,aAAa,EACpC,MAAiB;IAEjB,OAAO;QACL,MAAM,EAAE,cAAc;QACtB,MAAM;QACN,IAAI,EAAE,KAAK;QACX,IAAI,EACF,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI;YACjC,CAAC,CAAC,sCAAwB;YAC1B,CAAC,CAAC,yCAA2B;QACjC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,MAAmC;IACtD,OAAO;QACL,MAAM,EAAE,oBAAoB;QAC5B,MAAM;QACN,IAAI,EAAE,MAAM,CAAC,IAAK;QAClB,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,uCAAsB,CAAC,CAAC,CAAC,qCAAuB;KACrE,CAAC;AACJ,CAAC;AAED,kEAAkE;AAClE,SAAS,QAAQ,CAAC,MAA0C;IAC1D,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,EAAE,CAAC;IAC5B,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,QAAQ;QAAE,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,IAAI;QACd,OAAO;YACL,MAAM,EAAE,cAAc;YACtB,MAAM;YACN,IAAI,EAAE,IAAI;YACV,IAAI,EACF,MAAM,CAAC,IAAI;gBACX,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC;gBAC5D,CAAC,CAAC,IAAA,8BAAgB,GAAE;gBACpB,CAAC,CAAC,uCAAyB;SAChC,CAAC;IACJ,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,eAAe,CAC7B,UAMI,EAAE;IAEN,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAA,yCAAsB,GAAE,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,UAAU,IAAI,cAAc,CAAC;IAC9D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,IAAI,oBAAoB,CAAC;IAClE,MAAM,SAAS,GAAG,IAAI,GAAG,EAAgD,CAAC;IAC1E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAgC,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyC,CAAC;IAChE,IAAI,SAAsD,CAAC;IAE3D,SAAS,IAAI,CAAC,GAAW,EAAE,KAAqB;QAC9C,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,iFAAiF;IACjF,SAAS,SAAS;QAChB,IAAI,SAAS,IAAI,OAAO,UAAU,CAAC,gBAAgB,KAAK,UAAU;YAAE,OAAO;QAC3E,SAAS,GAAG,CAAC,KAAK,EAAE,EAAE;YACpB,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,yBAAyB,CAAC;gBAAE,OAAO;YAC1E,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,OAAO,EAAE,CAAC;gBAClC,IAAI,CAAC;oBACH,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;gBACpB,CAAC;gBAAC,MAAM,CAAC;oBACP,wDAAwD;gBAC1D,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QACF,UAAU,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,SAAS,IAAI,CAAC,IAAgC;QAC5C,MAAM,QAAQ,GAAG,IAAA,6CAA0B,EAAC,IAAI,EAAE;YAChD,OAAO;YACP,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,CAAC,CAAC;QACH,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAC9B,0EAA0E;QAC1E,IAAI,UAA+D,CAAC;QACpE,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,CAAC,KAAqB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC;QAEnE,KAAK,UAAU,MAAM,CACnB,IAAsB,EACtB,IAAa;YAEb,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,IAAI,CAAC;gBACH,OAAO;oBACL,KAAK,EAAE,MAAM,QAAQ,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE;wBACxC,OAAO,GAAG,IAAI,CAAC;wBACf,OAAO,IAAI,EAAE,CAAC;oBAChB,CAAC,EAAE,IAAI,CAAC;iBACT,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,OAAO;oBAAE,MAAM,KAAK,CAAC;gBACzB,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,gGAAgG;QAChG,SAAS,OAAO,CAAC,MAAmC;YAClD,IAAI,CAAC;gBACH,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,IAAK,EAAE,MAAM,CAAC,CAAC,CAAC;gBACzD,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,SAAS,MAAM,CAAC,MAAuB,EAAE,EAAU,EAAE,IAAI,GAAG,QAAQ;YAClE,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,IAAI,CAAC;gBAAE,OAAO;YACxC,MAAM,CAAC,GAAG,CACR,EAAE,EACF,UAAU,CAAC,GAAG,EAAE;gBACd,KAAK,KAAK,CAAC,MAAM,CAAC;qBACf,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;qBACjB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;oBACb,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBAClB,IAAI,IAAI,EAAE,MAAM,KAAK,cAAc;wBAAE,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;gBACpE,CAAC,CAAC,CAAC;YACP,CAAC,EAAE,QAAQ,CAAC,CACb,CAAC;QACJ,CAAC;QAED,KAAK,UAAU,MAAM,CACnB,MAAmC,EACnC,OAA2B,EAC3B,MAAuB,EACvB,KAAwD;YAExD,MAAM,OAAO,GAAG,MAAM,IAAA,6CAA0B,EAC9C,MAAe,EACf,MAAM,EACN,OAAO,EACP,KAAK,CACN,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACpB,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;gBAC5B,OAAO,KAAK,CAAC;oBACX,MAAM,EAAE,OAAO;oBACf,IAAI,EAAE,OAAO,CAAC,eAAe,CAAC,WAAW,EAAS;iBACnD,CAAC,CAAC;YACL,IACE,CAAC,MAAM,CAAC,IAAI;gBACZ,OAAO,CAAC,MAAM,KAAK,UAAU;gBAC7B,OAAO,CAAC,eAAe,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,EACrD,CAAC;gBACD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC1B,OAAO,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACpD,CAAC;YACD,4EAA4E;YAC5E,kDAAkD;YAClD,MAAM,GAAG,GACP,MAAM,CAAC,IAAI;gBACX,CAAC,MAAM,IAAA,6CAA0B,EAC/B,MAAe,EACf,MAAM,EACN,OAAO,EACP,KAAK,EACL,EAAE,QAAQ,EAAE,KAAK,EAAE,CACpB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;YACvB,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,OAAO,CAAC,eAAe,CAAC,WAAW,EAAS,CAAC;gBAC1D,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBAC9C,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;gBACzB,OAAO,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC5C,CAAC;YACD,IAAI,MAAM,CAAC,QAAQ;gBAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/C,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;QAED,uEAAuE;QACvE,KAAK,UAAU,eAAe,CAC5B,MAAmC;YAEnC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAA,oCAAmB,EACxC,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,IAAK,EACZ,OAAO,CAAC,WAAW,CACpB,CAAC;gBACF,OAAO,IAAA,uCAAsB,EAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,KAAK,UAAU,SAAS,CACtB,MAAmC,EACnC,MAAuB;YAEvB,MAAM,OAAO,GAAG,MAAM,MAAM;iBACzB,qBAAqB,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,aAAc,EAAE,CAAC;iBACtD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACrB,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1D,CAAC;QAED;;;;;WAKG;QACH,KAAK,UAAU,eAAe,CAC5B,MAAmC,EACnC,MAAuB;YAEvB,MAAM,IAAI,GACR,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;gBAC/C,CAAC,CAAC,MAAM,IAAA,yCAAsB,EAC1B,MAAM,EACN,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CACzB;gBACH,CAAC,CAAC,IAAI,CAAC;YACX,+DAA+D;YAC/D,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI;gBACnC,OAAO,YAAY,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YACxD,IACE,IAAI;gBACJ,CAAC,aAAa,CAAC,MAAM,CAAC;gBACtB,CAAC,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAK,EAAE,CAAC,CAAC,IAAI,CACxD,GAAG,EAAE,CAAC,KAAK,EACX,CAAC,KAAgC,EAAE,EAAE,CACnC,KAAK,EAAE,IAAI,KAAK,0BAA0B,CAC7C,CAAC;gBAEF,OAAO,IAAI,CAAC;YACd,4DAA4D;YAC5D,OAAO,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAChD,CAAC;QAED,KAAK,UAAU,SAAS,CACtB,KAAkC,EAClC,MAAuB;YAEvB,IAAI,MAAM,GAAG,KAAK,CAAC;YACnB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACzB,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ;gBAAE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;YACtD,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;gBAAE,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC1E,gEAAgE;YAChE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACrB,MAAM,MAAM,GAAG,MAAM,MAAM;qBACxB,qBAAqB,CAAC,EAAE,IAAI,EAAE,CAAC;qBAC/B,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;gBACrB,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;oBACrD,IAAI,OAAO,CAAC,MAAM,KAAK,OAAO;wBAAE,OAAO,OAAO,CAAC;oBAC/C,oEAAoE;oBACpE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBACzC,mEAAmE;oBACnE,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;oBACrE,IAAI,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,IAAI,IAAA,gBAAS,EAAC,IAAI,CAAC,IAAI,CAAC;wBAC5D,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;oBAClE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;oBAC1B,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBAChD,IAAI,OAAO,EAAE,MAAM,KAAK,OAAO;oBAAE,OAAO,OAAO,CAAC;gBAChD,IAAI,MAAM,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;oBAClC,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;wBACzD,IAAI,UAAU;4BAAE,OAAO,UAAU,CAAC;oBACpC,CAAC;oBACD,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;oBAC1B,OAAO,OAAO,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;YACD,wEAAwE;YACxE,+CAA+C;YAC/C,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;gBAC5C,IAAI,KAAK,KAAK,IAAI;oBAAE,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACrE,CAAC;YACD,MAAM,GAAG,GACP,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS;gBAC7B,CAAC,MAAM,IAAA,sCAAqB,EAC1B,MAAM,EACN,MAAM,CAAC,OAAO,EACd,IAAI,EACJ,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CACzB,CAAC,CAAC;gBACL,CAAC,MAAM,IAAA,sCAAqB,EAC1B,MAAe,EACf,MAAM,CAAC,OAAO,EACd,MAAM,CAAC,OAAO,EACd,IAAI,EACJ,OAAO,CAAC,WAAW,CACpB,CAAC,CAAC;YACL,wEAAwE;YACxE,iFAAiF;YACjF,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU;gBACzB,OAAO,YAAY,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;YACxD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAC/C,MAAM,OAAO,GAAG,MAAM,IAAA,4CAAyB,EAC7C,MAAM,EACN,MAAM,EACN,OAAO,CAAC,WAAW,CACpB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;gBACrB,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;oBAAE,OAAO,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YACtE,CAAC;YACD,IACE,GAAG,CAAC,IAAI,KAAK,UAAU;gBACvB,CAAC,CAAC,MAAM,CAAC,QAAQ;oBACf,CAAC,GAAG,CAAC,SAAS;wBACZ,GAAG,CAAC,SAAS,CAAC,aAAa,KAAK,MAAM,CAAC,aAAa,CAAC,CAAC,EAC1D,CAAC;gBACD,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;gBACjE,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBAChD,IAAI,OAAO;wBAAE,OAAO,OAAO,CAAC;gBAC9B,CAAC;YACH,CAAC;YACD,IACE,CAAC,MAAM,CAAC,QAAQ;gBAChB,CAAC,MAAM,CAAC,QAAQ;gBAChB,MAAM,CAAC,SAAS,KAAK,SAAS;gBAC9B,aAAa,CAAC,MAAM,CAAC;gBAErB,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3B,IAAI,MAAM,CAAC,QAAQ;gBAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/C,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAED,KAAK,UAAU,OAAO,CACpB,MAAuB,EACvB,MAA8C;YAE9C,IAAI,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM;gBAAE,OAAO,KAAK,EAAE,CAAC;YAC5B,kCAAkC;YAClC,IAAI,CAAC,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC,OAAO;gBAClE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC1B,IAAI,MAAM,CAAC,IAAI;gBAAE,OAAO,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,KAAK,GAAG,MAAM,QAAQ;iBACzB,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;iBAChD,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACrB,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM;gBAAE,OAAO,KAAK,EAAE,CAAC;YAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,MAAM,MAAM;qBACzB,qBAAqB,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;qBAC3C,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;gBACrB,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YACzE,CAAC;YACD,uDAAuD;YACvD,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;gBACjD,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACtC,oEAAoE;YACpE,IAAI,KAAK,EAAE,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM;gBAC7C,OAAO;oBACL,MAAM,EAAE,YAAY;oBACpB,MAAM;oBACN,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,wCAA0B;oBAChC,GAAG,CAAC,MAAM,CAAC,IAAI;wBACb,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,yCAA2B,EAAE;wBAC7D,CAAC,CAAC,EAAE,CAAC;iBACR,CAAC;YACJ,IACE,MAAM,CAAC,IAAI;gBACX,MAAM,CAAC,SAAS,KAAK,SAAS;gBAC9B,KAAK,EAAE,MAAM,KAAK,SAAS;gBAC3B,KAAK,CAAC,MAAM;gBAEZ,OAAO;oBACL,MAAM,EAAE,gBAAgB;oBACxB,MAAM;oBACN,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,IAAA,8BAAgB,GAAE;oBACxB,OAAO,EAAE,yCAA2B;iBACrC,CAAC;YACJ,IACE,MAAM,CAAC,IAAI;gBACX,MAAM,CAAC,SAAS,KAAK,SAAS;gBAC9B,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS;oBACzB,MAAM,CAAC,SAAS,KAAK,SAAS;oBAC9B,aAAa,CAAC,MAAM,CAAC,CAAC;gBACxB,CAAC,MAAM,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CACtD,GAAG,EAAE,CAAC,KAAK,EACX,CAAC,KAAgC,EAAE,EAAE,CACnC,KAAK,EAAE,IAAI,KAAK,0BAA0B,CAC7C,CAAC;gBAEF,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC;YAC3B,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;QAED;;;WAGG;QACH,KAAK,UAAU,KAAK,CAClB,MAAuB,EACvB,SAA6D,EAAE;YAE/D,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC;YACzE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO;YACL,KAAK;YACL,kEAAkE;YAClE,IAAI;YACJ,wFAAwF;YACxF,SAAS,CAAC,QAAyC;gBACjD,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC7B,IAAI,CAAC,GAAG;oBAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;gBAChD,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACvB,SAAS,EAAE,CAAC;gBACZ,OAAO,GAAG,EAAE;oBACV,GAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACtB,IAAI,CAAC,GAAI,CAAC,IAAI,EAAE,CAAC;wBACf,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBACtB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACtB,CAAC;gBACH,CAAC,CAAC;YACJ,CAAC;YACD;;;;;;eAMG;YACH,KAAK,CAAC,IAAI,CACR,MAAuB,EACvB,GAAwC;gBAExC,IAAI,OAAgD,CAAC;gBACrD,MAAM,IAAI,GAAkB;oBAC1B,KAAK,CAAC,UAAU,CAAC,UAAU;wBACzB,IAAI,QAES,CAAC;wBACd,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;4BACf,kFAAkF;4BAClF,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAA,yCAAsB,EAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;4BAChE,IAAI,CAAC;gCACH,QAAQ,GAAG,MAAM,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;4BACtC,CAAC;4BAAC,OAAO,KAAK,EAAE,CAAC;gCACf,MAAM,IAAI,mBAAmB,CAAC,KAAK,CAAC,CAAC;4BACvC,CAAC;wBACH,CAAC;wBACD,IAAI,CAAC;4BACH,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;wBACnD,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,MAAM,GAAG,GAAG,IAAI,EAAE,CAAC;4BACnB,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO;gCAAE,MAAM,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;4BAC1D,MAAM,KAAK,CAAC;wBACd,CAAC;wBACD,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;oBAChB,CAAC;oBACD,WAAW,CAAC,IAAI,EAAE,QAAQ;wBACxB,IAAI,CAAC,OAAO;4BACV,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;wBAC7D,IAAI,CAAC;4BACH,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;wBAC9C,CAAC;wBAAC,OAAO,KAAK,EAAE,CAAC;4BACf,IAAI,CAAC,CAAC,KAAK,YAAY,iDAA8B,CAAC;gCACpD,MAAM,KAAK,CAAC;4BACd,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;wBACzB,CAAC;wBACD,mEAAmE;wBACnE,IAAI,IAAI,CAAC,IAAI,IAAI,QAAQ;4BACvB,IAAI,CAAC;gCACH,IAAA,oCAAmB,EAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gCAChE,OAAO,GAAG,QAAQ,CAAC,aAAa,CAC9B,OAAO,EACP,IAAA,uCAAsB,EAAC,QAAQ,CAAC,CAAC,KAAK,CACvC,CAAC;4BACJ,CAAC;4BAAC,MAAM,CAAC;gCACP,oDAAoD;4BACtD,CAAC;wBACH,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC3B,CAAC;oBACD,UAAU;wBACR,QAAQ,CAAC,QAAQ,EAAE,CAAC;wBACpB,OAAO,GAAG,SAAS,CAAC;wBACpB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;oBAChB,CAAC;iBACF,CAAC;gBACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;oBACrC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;oBACzC,IAAI,GAAG,CAAC,MAAM,KAAK,OAAO;wBAAE,MAAM,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;oBAC1D,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC;gBACnB,CAAC,EAAE,KAAK,CAAC,CAAC;gBACV,IAAI,CAAC,MAAM;oBAAE,MAAM,IAAI,kBAAkB,EAAE,CAAC;gBAC5C,OAAO,MAAM,CAAC,KAAK,CAAC;YACtB,CAAC;YACD;;;;;eAKG;YACH,KAAK,CAAC,IAAI,CACR,QAAwB,EACxB,eAAwC,EACxC,MAAuB;gBAEvB,IAAI,eAAe,EAAE,aAAa,KAAK,IAAI;oBACzC,MAAM,IAAI,KAAK,CACb,8EAA8E,CAC/E,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;oBACrC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;oBAC9C,IACE,QAAQ,CAAC,MAAM,KAAK,OAAO;wBAC3B,GAAG,CAAC,MAAM,KAAK,OAAO;wBACtB,CAAC,GAAG,CAAC,IAAI;wBACT,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;wBAC9B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAE9D,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;oBACzC,IAAI,CAAC;wBACH,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC7D,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;oBAC5C,CAAC;oBACD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC5C,CAAC,EAAE,IAAI,CAAC,CAAC;gBACT,MAAM,KAAK,GAAG,MAAM,EAAE,KAAK,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;gBAClE,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACnB,OAAO,KAAK,CAAC;YACf,CAAC;YACD;;;;eAIG;YACH,KAAK,CAAC,SAAS,CACb,OAA2B,EAC3B,MAAuB,EACvB,KAAwD;gBAExD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;oBACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAC/B,IACE,CAAC,MAAM;wBACP,CAAC,CAAC,MAAM,CAAC,IAAI;4BACX,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;wBAE1D,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;oBAC1B,OAAO,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;gBAChD,CAAC,EAAE,IAAI,CAAC,CAAC;gBACT,OAAO,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;YACxC,CAAC;YACD;;;;;eAKG;YACH,KAAK,CAAC,UAAU,CACd,MAAuB,EACvB,YAAkB;gBAElB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;oBACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAC/B,IACE,MAAM,EAAE,IAAI;wBACZ,MAAM,CAAC,IAAI;wBACX,CAAC,YAAY,KAAK,SAAS;4BACzB,YAAY,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC;wBAE7C,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBAC/B,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;gBACzB,CAAC,EAAE,IAAI,CAAC,CAAC;gBACT,OAAO,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;YACxC,CAAC;YACD;;;eAGG;YACH,KAAK,CAAC,UAAU,CACd,MAAuB,EACvB,aAAmB;gBAEnB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,IAAI,EAAE;oBACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;oBAC/B,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI;wBAAE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;oBAC3D,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;oBACzC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC;gBACzB,CAAC,EAAE,IAAI,CAAC,CAAC;gBACT,OAAO,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,IAAI,EAAE,CAAC,CAAC;YACxC,CAAC;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,IAAI;QACJ,gDAAgD;QAChD,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;QAChC,oEAAoE;QACpE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,oCAAsB,CAAC;QACrE,qEAAqE;QACrE,OAAO;YACL,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YACzD,MAAM,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,SAAS;gBAAE,UAAU,CAAC,mBAAmB,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACtE,SAAS,GAAG,SAAS,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
|