@algorandfoundation/algokit-utils 9.1.1-beta.3 → 9.1.1-beta.4
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/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"**"
|
|
7
7
|
],
|
|
8
8
|
"name": "@algorandfoundation/algokit-utils",
|
|
9
|
-
"version": "9.1.1-beta.
|
|
9
|
+
"version": "9.1.1-beta.4",
|
|
10
10
|
"private": false,
|
|
11
11
|
"description": "A set of core Algorand utilities written in TypeScript and released via npm that make it easier to build solutions on Algorand.",
|
|
12
12
|
"author": "Algorand Foundation",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var algosdk = require('algosdk');
|
|
4
|
+
var config = require('../config.js');
|
|
4
5
|
var indexer = require('./indexer.js');
|
|
5
6
|
|
|
6
7
|
var decodeSignedTransaction = algosdk.decodeSignedTransaction;
|
|
@@ -12,6 +13,13 @@ class TransactionLogger {
|
|
|
12
13
|
constructor() {
|
|
13
14
|
this._sentTransactionIds = [];
|
|
14
15
|
}
|
|
16
|
+
_pushTxn(stxn) {
|
|
17
|
+
const decoded = decodeSignedTransaction(stxn);
|
|
18
|
+
if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {
|
|
19
|
+
this._latestLastValidRound = BigInt(decoded.txn.lastValid);
|
|
20
|
+
}
|
|
21
|
+
this._sentTransactionIds.push(decoded.txn.txID());
|
|
22
|
+
}
|
|
15
23
|
/**
|
|
16
24
|
* The list of transaction IDs that has been logged thus far.
|
|
17
25
|
*/
|
|
@@ -29,14 +37,10 @@ class TransactionLogger {
|
|
|
29
37
|
*/
|
|
30
38
|
logRawTransaction(signedTransactions) {
|
|
31
39
|
if (Array.isArray(signedTransactions)) {
|
|
32
|
-
|
|
33
|
-
const decoded = decodeSignedTransaction(stxn);
|
|
34
|
-
this._sentTransactionIds.push(decoded.txn.txID());
|
|
35
|
-
}
|
|
40
|
+
signedTransactions.forEach((stxn) => this._pushTxn(stxn));
|
|
36
41
|
}
|
|
37
42
|
else {
|
|
38
|
-
|
|
39
|
-
this._sentTransactionIds.push(decoded.txn.txID());
|
|
43
|
+
this._pushTxn(signedTransactions);
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
46
|
/** Return a proxy that wraps the given Algodv2 with this transaction logger.
|
|
@@ -52,7 +56,22 @@ class TransactionLogger {
|
|
|
52
56
|
if (this._sentTransactionIds.length === 0)
|
|
53
57
|
return;
|
|
54
58
|
const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1];
|
|
55
|
-
await indexer.runWhenIndexerCaughtUp(() =>
|
|
59
|
+
await indexer.runWhenIndexerCaughtUp(async () => {
|
|
60
|
+
try {
|
|
61
|
+
await indexer$1.lookupTransactionByID(lastTxId).do();
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
// If the txid lookup failed, then try to look up the last valid round
|
|
65
|
+
// If that round exists, then we know indexer is caught up
|
|
66
|
+
if (this._latestLastValidRound) {
|
|
67
|
+
await indexer$1.lookupBlock(this._latestLastValidRound).do();
|
|
68
|
+
config.Config.getLogger().debug(`waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
throw e;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
56
75
|
}
|
|
57
76
|
}
|
|
58
77
|
class TransactionLoggingAlgodv2ProxyHandler {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-logger.js","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n
|
|
1
|
+
{"version":3,"file":"transaction-logger.js","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { Config } from '../config'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n private _latestLastValidRound?: bigint\n\n private _pushTxn(stxn: Uint8Array) {\n const decoded = decodeSignedTransaction(stxn)\n if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {\n this._latestLastValidRound = BigInt(decoded.txn.lastValid)\n }\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n signedTransactions.forEach((stxn) => this._pushTxn(stxn))\n } else {\n this._pushTxn(signedTransactions)\n }\n }\n\n /** Return a proxy that wraps the given Algodv2 with this transaction logger.\n *\n * @param algod The `Algodv2` to wrap\n * @returns The wrapped `Algodv2`, any transactions sent using this algod instance will be logged by this transaction logger\n */\n capture(algod: Algodv2): Algodv2 {\n return new Proxy<Algodv2>(algod, new TransactionLoggingAlgodv2ProxyHandler(this))\n }\n\n /** Wait until all logged transactions IDs appear in the given `Indexer`. */\n async waitForIndexer(indexer: Indexer) {\n if (this._sentTransactionIds.length === 0) return\n const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1]\n await runWhenIndexerCaughtUp(async () => {\n try {\n await indexer.lookupTransactionByID(lastTxId).do()\n } catch (e) {\n // If the txid lookup failed, then try to look up the last valid round\n // If that round exists, then we know indexer is caught up\n if (this._latestLastValidRound) {\n await indexer.lookupBlock(this._latestLastValidRound).do()\n Config.getLogger().debug(\n `waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`,\n )\n } else {\n throw e\n }\n }\n })\n }\n}\n\nclass TransactionLoggingAlgodv2ProxyHandler implements ProxyHandler<Algodv2> {\n private transactionLogger: TransactionLogger\n\n constructor(transactionLogger: TransactionLogger) {\n this.transactionLogger = transactionLogger\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(target: Algodv2, property: string | symbol, receiver: any) {\n if (property === 'sendRawTransaction') {\n return (stxOrStxs: Uint8Array | Uint8Array[]) => {\n this.transactionLogger.logRawTransaction(stxOrStxs)\n return target[property].call(receiver, stxOrStxs)\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (target as any)[property]\n }\n}\n"],"names":["indexer","runWhenIndexerCaughtUp","Config"],"mappings":";;;;;;AAIA,IAAO,uBAAuB,GAAG,OAAO,CAAC,uBAAuB;AAGhE;;;AAGG;MACU,iBAAiB,CAAA;AAA9B,IAAA,WAAA,GAAA;QACU,IAAmB,CAAA,mBAAA,GAAa,EAAE;;AAGlC,IAAA,QAAQ,CAAC,IAAgB,EAAA;AAC/B,QAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAC7C,QAAA,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YACrE,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;;AAE5D,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;AAGnD;;AAEG;AACH,IAAA,IAAI,kBAAkB,GAAA;QACpB,OAAO,IAAI,CAAC,mBAAmB;;AAGjC;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,mBAAmB,GAAG,EAAE;;AAG/B;;AAEG;AACH,IAAA,iBAAiB,CAAC,kBAA6C,EAAA;AAC7D,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;AACrC,YAAA,kBAAkB,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;;aACpD;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;;;AAIrC;;;;AAIG;AACH,IAAA,OAAO,CAAC,KAAc,EAAA;QACpB,OAAO,IAAI,KAAK,CAAU,KAAK,EAAE,IAAI,qCAAqC,CAAC,IAAI,CAAC,CAAC;;;IAInF,MAAM,cAAc,CAACA,SAAgB,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC;YAAE;AAC3C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9E,QAAA,MAAMC,8BAAsB,CAAC,YAAW;AACtC,YAAA,IAAI;gBACF,MAAMD,SAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE;;YAClD,OAAO,CAAC,EAAE;;;AAGV,gBAAA,IAAI,IAAI,CAAC,qBAAqB,EAAE;oBAC9B,MAAMA,SAAO,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,EAAE,EAAE;AAC1D,oBAAAE,aAAM,CAAC,SAAS,EAAE,CAAC,KAAK,CACtB,CAAA,qDAAA,EAAwD,IAAI,CAAC,qBAAqB,CAAA,2CAAA,EAA8C,QAAQ,CAAA,gBAAA,CAAkB,CAC3J;;qBACI;AACL,oBAAA,MAAM,CAAC;;;AAGb,SAAC,CAAC;;AAEL;AAED,MAAM,qCAAqC,CAAA;AAGzC,IAAA,WAAA,CAAY,iBAAoC,EAAA;AAC9C,QAAA,IAAI,CAAC,iBAAiB,GAAG,iBAAiB;;;AAI5C,IAAA,GAAG,CAAC,MAAe,EAAE,QAAyB,EAAE,QAAa,EAAA;AAC3D,QAAA,IAAI,QAAQ,KAAK,oBAAoB,EAAE;YACrC,OAAO,CAAC,SAAoC,KAAI;AAC9C,gBAAA,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;AACnD,aAAC;;;AAGH,QAAA,OAAQ,MAAc,CAAC,QAAQ,CAAC;;AAEnC;;;;"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import algosdk from 'algosdk';
|
|
2
|
+
import { Config } from '../config.mjs';
|
|
2
3
|
import { runWhenIndexerCaughtUp } from './indexer.mjs';
|
|
3
4
|
|
|
4
5
|
var decodeSignedTransaction = algosdk.decodeSignedTransaction;
|
|
@@ -10,6 +11,13 @@ class TransactionLogger {
|
|
|
10
11
|
constructor() {
|
|
11
12
|
this._sentTransactionIds = [];
|
|
12
13
|
}
|
|
14
|
+
_pushTxn(stxn) {
|
|
15
|
+
const decoded = decodeSignedTransaction(stxn);
|
|
16
|
+
if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {
|
|
17
|
+
this._latestLastValidRound = BigInt(decoded.txn.lastValid);
|
|
18
|
+
}
|
|
19
|
+
this._sentTransactionIds.push(decoded.txn.txID());
|
|
20
|
+
}
|
|
13
21
|
/**
|
|
14
22
|
* The list of transaction IDs that has been logged thus far.
|
|
15
23
|
*/
|
|
@@ -27,14 +35,10 @@ class TransactionLogger {
|
|
|
27
35
|
*/
|
|
28
36
|
logRawTransaction(signedTransactions) {
|
|
29
37
|
if (Array.isArray(signedTransactions)) {
|
|
30
|
-
|
|
31
|
-
const decoded = decodeSignedTransaction(stxn);
|
|
32
|
-
this._sentTransactionIds.push(decoded.txn.txID());
|
|
33
|
-
}
|
|
38
|
+
signedTransactions.forEach((stxn) => this._pushTxn(stxn));
|
|
34
39
|
}
|
|
35
40
|
else {
|
|
36
|
-
|
|
37
|
-
this._sentTransactionIds.push(decoded.txn.txID());
|
|
41
|
+
this._pushTxn(signedTransactions);
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
/** Return a proxy that wraps the given Algodv2 with this transaction logger.
|
|
@@ -50,7 +54,22 @@ class TransactionLogger {
|
|
|
50
54
|
if (this._sentTransactionIds.length === 0)
|
|
51
55
|
return;
|
|
52
56
|
const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1];
|
|
53
|
-
await runWhenIndexerCaughtUp(() =>
|
|
57
|
+
await runWhenIndexerCaughtUp(async () => {
|
|
58
|
+
try {
|
|
59
|
+
await indexer.lookupTransactionByID(lastTxId).do();
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
// If the txid lookup failed, then try to look up the last valid round
|
|
63
|
+
// If that round exists, then we know indexer is caught up
|
|
64
|
+
if (this._latestLastValidRound) {
|
|
65
|
+
await indexer.lookupBlock(this._latestLastValidRound).do();
|
|
66
|
+
Config.getLogger().debug(`waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
throw e;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
54
73
|
}
|
|
55
74
|
}
|
|
56
75
|
class TransactionLoggingAlgodv2ProxyHandler {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction-logger.mjs","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n
|
|
1
|
+
{"version":3,"file":"transaction-logger.mjs","sources":["../../src/testing/transaction-logger.ts"],"sourcesContent":["import algosdk from 'algosdk'\nimport { Config } from '../config'\nimport { runWhenIndexerCaughtUp } from './indexer'\nimport Algodv2 = algosdk.Algodv2\nimport decodeSignedTransaction = algosdk.decodeSignedTransaction\nimport Indexer = algosdk.Indexer\n\n/**\n * Allows you to keep track of Algorand transaction IDs by wrapping an `Algodv2` in a proxy.\n * Useful for automated tests.\n */\nexport class TransactionLogger {\n private _sentTransactionIds: string[] = []\n private _latestLastValidRound?: bigint\n\n private _pushTxn(stxn: Uint8Array) {\n const decoded = decodeSignedTransaction(stxn)\n if (decoded.txn.lastValid > (this._latestLastValidRound ?? BigInt(0))) {\n this._latestLastValidRound = BigInt(decoded.txn.lastValid)\n }\n this._sentTransactionIds.push(decoded.txn.txID())\n }\n\n /**\n * The list of transaction IDs that has been logged thus far.\n */\n get sentTransactionIds(): Readonly<string[]> {\n return this._sentTransactionIds\n }\n\n /**\n * Clear all logged IDs.\n */\n clear() {\n this._sentTransactionIds = []\n }\n\n /**\n * The method that captures raw transactions and stores the transaction IDs.\n */\n logRawTransaction(signedTransactions: Uint8Array | Uint8Array[]) {\n if (Array.isArray(signedTransactions)) {\n signedTransactions.forEach((stxn) => this._pushTxn(stxn))\n } else {\n this._pushTxn(signedTransactions)\n }\n }\n\n /** Return a proxy that wraps the given Algodv2 with this transaction logger.\n *\n * @param algod The `Algodv2` to wrap\n * @returns The wrapped `Algodv2`, any transactions sent using this algod instance will be logged by this transaction logger\n */\n capture(algod: Algodv2): Algodv2 {\n return new Proxy<Algodv2>(algod, new TransactionLoggingAlgodv2ProxyHandler(this))\n }\n\n /** Wait until all logged transactions IDs appear in the given `Indexer`. */\n async waitForIndexer(indexer: Indexer) {\n if (this._sentTransactionIds.length === 0) return\n const lastTxId = this._sentTransactionIds[this._sentTransactionIds.length - 1]\n await runWhenIndexerCaughtUp(async () => {\n try {\n await indexer.lookupTransactionByID(lastTxId).do()\n } catch (e) {\n // If the txid lookup failed, then try to look up the last valid round\n // If that round exists, then we know indexer is caught up\n if (this._latestLastValidRound) {\n await indexer.lookupBlock(this._latestLastValidRound).do()\n Config.getLogger().debug(\n `waitForIndexer has waited until the last valid round ${this._latestLastValidRound} was indexed, but did not find transaction ${lastTxId} in the indexer.`,\n )\n } else {\n throw e\n }\n }\n })\n }\n}\n\nclass TransactionLoggingAlgodv2ProxyHandler implements ProxyHandler<Algodv2> {\n private transactionLogger: TransactionLogger\n\n constructor(transactionLogger: TransactionLogger) {\n this.transactionLogger = transactionLogger\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n get(target: Algodv2, property: string | symbol, receiver: any) {\n if (property === 'sendRawTransaction') {\n return (stxOrStxs: Uint8Array | Uint8Array[]) => {\n this.transactionLogger.logRawTransaction(stxOrStxs)\n return target[property].call(receiver, stxOrStxs)\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return (target as any)[property]\n }\n}\n"],"names":[],"mappings":";;;;AAIA,IAAO,uBAAuB,GAAG,OAAO,CAAC,uBAAuB;AAGhE;;;AAGG;MACU,iBAAiB,CAAA;AAA9B,IAAA,WAAA,GAAA;QACU,IAAmB,CAAA,mBAAA,GAAa,EAAE;;AAGlC,IAAA,QAAQ,CAAC,IAAgB,EAAA;AAC/B,QAAA,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC;AAC7C,QAAA,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,CAAC,qBAAqB,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;YACrE,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;;AAE5D,QAAA,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;;AAGnD;;AAEG;AACH,IAAA,IAAI,kBAAkB,GAAA;QACpB,OAAO,IAAI,CAAC,mBAAmB;;AAGjC;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,mBAAmB,GAAG,EAAE;;AAG/B;;AAEG;AACH,IAAA,iBAAiB,CAAC,kBAA6C,EAAA;AAC7D,QAAA,IAAI,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE;AACrC,YAAA,kBAAkB,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;;aACpD;AACL,YAAA,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC;;;AAIrC;;;;AAIG;AACH,IAAA,OAAO,CAAC,KAAc,EAAA;QACpB,OAAO,IAAI,KAAK,CAAU,KAAK,EAAE,IAAI,qCAAqC,CAAC,IAAI,CAAC,CAAC;;;IAInF,MAAM,cAAc,CAAC,OAAgB,EAAA;AACnC,QAAA,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC;YAAE;AAC3C,QAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9E,QAAA,MAAM,sBAAsB,CAAC,YAAW;AACtC,YAAA,IAAI;gBACF,MAAM,OAAO,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE;;YAClD,OAAO,CAAC,EAAE;;;AAGV,gBAAA,IAAI,IAAI,CAAC,qBAAqB,EAAE;oBAC9B,MAAM,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,EAAE,EAAE;AAC1D,oBAAA,MAAM,CAAC,SAAS,EAAE,CAAC,KAAK,CACtB,CAAA,qDAAA,EAAwD,IAAI,CAAC,qBAAqB,CAAA,2CAAA,EAA8C,QAAQ,CAAA,gBAAA,CAAkB,CAC3J;;qBACI;AACL,oBAAA,MAAM,CAAC;;;AAGb,SAAC,CAAC;;AAEL;AAED,MAAM,qCAAqC,CAAA;AAGzC,IAAA,WAAA,CAAY,iBAAoC,EAAA;AAC9C,QAAA,IAAI,CAAC,iBAAiB,GAAG,iBAAiB;;;AAI5C,IAAA,GAAG,CAAC,MAAe,EAAE,QAAyB,EAAE,QAAa,EAAA;AAC3D,QAAA,IAAI,QAAQ,KAAK,oBAAoB,EAAE;YACrC,OAAO,CAAC,SAAoC,KAAI;AAC9C,gBAAA,IAAI,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACnD,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC;AACnD,aAAC;;;AAGH,QAAA,OAAQ,MAAc,CAAC,QAAQ,CAAC;;AAEnC;;;;"}
|