@witnet/sdk 1.0.0-beta.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 +21 -0
- package/README.md +103 -0
- package/dist/package.json +72 -0
- package/dist/src/bin/helpers.d.ts +91 -0
- package/dist/src/bin/helpers.d.ts.map +1 -0
- package/dist/src/bin/helpers.js +816 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +47 -0
- package/dist/src/lib/crypto/account.d.ts +32 -0
- package/dist/src/lib/crypto/account.d.ts.map +1 -0
- package/dist/src/lib/crypto/account.js +106 -0
- package/dist/src/lib/crypto/coinbase.d.ts +10 -0
- package/dist/src/lib/crypto/coinbase.d.ts.map +1 -0
- package/dist/src/lib/crypto/coinbase.js +28 -0
- package/dist/src/lib/crypto/index.d.ts +8 -0
- package/dist/src/lib/crypto/index.d.ts.map +1 -0
- package/dist/src/lib/crypto/index.js +30 -0
- package/dist/src/lib/crypto/interfaces.d.ts +85 -0
- package/dist/src/lib/crypto/interfaces.d.ts.map +1 -0
- package/dist/src/lib/crypto/interfaces.js +3 -0
- package/dist/src/lib/crypto/payloads/DataRequestPayload.d.ts +55 -0
- package/dist/src/lib/crypto/payloads/DataRequestPayload.d.ts.map +1 -0
- package/dist/src/lib/crypto/payloads/DataRequestPayload.js +339 -0
- package/dist/src/lib/crypto/payloads/StakePayload.d.ts +28 -0
- package/dist/src/lib/crypto/payloads/StakePayload.d.ts.map +1 -0
- package/dist/src/lib/crypto/payloads/StakePayload.js +142 -0
- package/dist/src/lib/crypto/payloads/UnstakePayload.d.ts +36 -0
- package/dist/src/lib/crypto/payloads/UnstakePayload.d.ts.map +1 -0
- package/dist/src/lib/crypto/payloads/UnstakePayload.js +154 -0
- package/dist/src/lib/crypto/payloads/ValueTransferPayload.d.ts +25 -0
- package/dist/src/lib/crypto/payloads/ValueTransferPayload.d.ts.map +1 -0
- package/dist/src/lib/crypto/payloads/ValueTransferPayload.js +128 -0
- package/dist/src/lib/crypto/payloads.d.ts +57 -0
- package/dist/src/lib/crypto/payloads.d.ts.map +1 -0
- package/dist/src/lib/crypto/payloads.js +170 -0
- package/dist/src/lib/crypto/signer.d.ts +33 -0
- package/dist/src/lib/crypto/signer.d.ts.map +1 -0
- package/dist/src/lib/crypto/signer.js +194 -0
- package/dist/src/lib/crypto/transmitters/DataRequests.d.ts +15 -0
- package/dist/src/lib/crypto/transmitters/DataRequests.d.ts.map +1 -0
- package/dist/src/lib/crypto/transmitters/DataRequests.js +23 -0
- package/dist/src/lib/crypto/transmitters/StakeDeposits.d.ts +12 -0
- package/dist/src/lib/crypto/transmitters/StakeDeposits.d.ts.map +1 -0
- package/dist/src/lib/crypto/transmitters/StakeDeposits.js +17 -0
- package/dist/src/lib/crypto/transmitters/StakeWithdrawals.d.ts +18 -0
- package/dist/src/lib/crypto/transmitters/StakeWithdrawals.d.ts.map +1 -0
- package/dist/src/lib/crypto/transmitters/StakeWithdrawals.js +53 -0
- package/dist/src/lib/crypto/transmitters/ValueTransfers.d.ts +11 -0
- package/dist/src/lib/crypto/transmitters/ValueTransfers.d.ts.map +1 -0
- package/dist/src/lib/crypto/transmitters/ValueTransfers.js +16 -0
- package/dist/src/lib/crypto/transmitters.d.ts +47 -0
- package/dist/src/lib/crypto/transmitters.d.ts.map +1 -0
- package/dist/src/lib/crypto/transmitters.js +416 -0
- package/dist/src/lib/crypto/types.d.ts +161 -0
- package/dist/src/lib/crypto/types.d.ts.map +1 -0
- package/dist/src/lib/crypto/types.js +273 -0
- package/dist/src/lib/crypto/utils.d.ts +21 -0
- package/dist/src/lib/crypto/utils.d.ts.map +1 -0
- package/dist/src/lib/crypto/utils.js +156 -0
- package/dist/src/lib/crypto/wallet.d.ts +120 -0
- package/dist/src/lib/crypto/wallet.d.ts.map +1 -0
- package/dist/src/lib/crypto/wallet.js +258 -0
- package/dist/src/lib/index.d.ts +5 -0
- package/dist/src/lib/index.d.ts.map +1 -0
- package/dist/src/lib/index.js +44 -0
- package/dist/src/lib/radon/ccdr/eth.d.ts +160 -0
- package/dist/src/lib/radon/ccdr/eth.d.ts.map +1 -0
- package/dist/src/lib/radon/ccdr/eth.js +272 -0
- package/dist/src/lib/radon/ccdr/index.d.ts +14 -0
- package/dist/src/lib/radon/ccdr/index.d.ts.map +1 -0
- package/dist/src/lib/radon/ccdr/index.js +39 -0
- package/dist/src/lib/radon/ccdr/wit.d.ts +23 -0
- package/dist/src/lib/radon/ccdr/wit.d.ts.map +1 -0
- package/dist/src/lib/radon/ccdr/wit.js +35 -0
- package/dist/src/lib/radon/filters.d.ts +14 -0
- package/dist/src/lib/radon/filters.d.ts.map +1 -0
- package/dist/src/lib/radon/filters.js +45 -0
- package/dist/src/lib/radon/index.d.ts +296 -0
- package/dist/src/lib/radon/index.d.ts.map +1 -0
- package/dist/src/lib/radon/index.js +707 -0
- package/dist/src/lib/radon/reducers.d.ts +29 -0
- package/dist/src/lib/radon/reducers.d.ts.map +1 -0
- package/dist/src/lib/radon/reducers.js +66 -0
- package/dist/src/lib/radon/types.d.ts +521 -0
- package/dist/src/lib/radon/types.d.ts.map +1 -0
- package/dist/src/lib/radon/types.js +936 -0
- package/dist/src/lib/radon/utils.d.ts +53 -0
- package/dist/src/lib/radon/utils.d.ts.map +1 -0
- package/dist/src/lib/radon/utils.js +153 -0
- package/dist/src/lib/rpc/index.d.ts +3 -0
- package/dist/src/lib/rpc/index.d.ts.map +1 -0
- package/dist/src/lib/rpc/index.js +19 -0
- package/dist/src/lib/rpc/nodes.d.ts +40 -0
- package/dist/src/lib/rpc/nodes.d.ts.map +1 -0
- package/dist/src/lib/rpc/nodes.js +293 -0
- package/dist/src/lib/rpc/provider.d.ts +88 -0
- package/dist/src/lib/rpc/provider.d.ts.map +1 -0
- package/dist/src/lib/rpc/provider.js +336 -0
- package/dist/src/lib/rpc/reporter.d.ts +18 -0
- package/dist/src/lib/rpc/reporter.d.ts.map +1 -0
- package/dist/src/lib/rpc/reporter.js +30 -0
- package/dist/src/lib/rpc/types.d.ts +409 -0
- package/dist/src/lib/rpc/types.d.ts.map +1 -0
- package/dist/src/lib/rpc/types.js +81 -0
- package/dist/src/lib/types.d.ts +18 -0
- package/dist/src/lib/types.d.ts.map +1 -0
- package/dist/src/lib/types.js +7 -0
- package/dist/src/lib/utils.d.ts +13 -0
- package/dist/src/lib/utils.d.ts.map +1 -0
- package/dist/src/lib/utils.js +97 -0
- package/dist/witnet/assets/index.d.ts +30 -0
- package/dist/witnet/assets/index.d.ts.map +1 -0
- package/dist/witnet/assets/index.js +6 -0
- package/dist/witnet/assets/modals/index.d.ts +18 -0
- package/dist/witnet/assets/modals/index.d.ts.map +1 -0
- package/dist/witnet/assets/modals/index.js +21 -0
- package/dist/witnet/assets/modals/web3/eth.d.ts +5 -0
- package/dist/witnet/assets/modals/web3/eth.d.ts.map +1 -0
- package/dist/witnet/assets/modals/web3/eth.js +26 -0
- package/dist/witnet/assets/modals/web3/wit.d.ts +4 -0
- package/dist/witnet/assets/modals/web3/wit.d.ts.map +1 -0
- package/dist/witnet/assets/modals/web3/wit.js +20 -0
- package/dist/witnet/assets/requests.d.ts +11 -0
- package/dist/witnet/assets/requests.d.ts.map +1 -0
- package/dist/witnet/assets/requests.js +88 -0
- package/dist/witnet/witnet.proto.json +1325 -0
- package/package.json +72 -0
- package/src/bin/cli/history.js +31 -0
- package/src/bin/cli/inspect.js +359 -0
- package/src/bin/cli/network.js +592 -0
- package/src/bin/cli/nodes.js +364 -0
- package/src/bin/cli/radon.js +814 -0
- package/src/bin/cli/wallet.js +1000 -0
- package/src/bin/helpers.js +829 -0
- package/src/bin/postinstall.js +9 -0
- package/src/bin/toolkit.js +294 -0
- package/witnet/assets/_index.js +8 -0
- package/witnet/assets/_requests.js +25 -0
- package/witnet/assets/_sources.js +36 -0
- package/witnet/assets/_templates.js +36 -0
- package/witnet/assets/index.js +4 -0
- package/witnet/assets/modals/index.js +25 -0
- package/witnet/assets/modals/web3/btc.js +0 -0
- package/witnet/assets/modals/web3/eth.js +29 -0
- package/witnet/assets/modals/web3/sol.js +0 -0
- package/witnet/assets/modals/web3/wit.js +23 -0
- package/witnet/assets/requests.js +94 -0
- package/witnet/witnet.proto.json +1325 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransmitterMultiSig = exports.Transmitter = void 0;
|
|
4
|
+
const promisePoller = require('promise-poller').default;
|
|
5
|
+
const protobufjs_1 = require("protobufjs");
|
|
6
|
+
const protoRoot = protobufjs_1.Root.fromJSON(require("../../../witnet/witnet.proto.json"));
|
|
7
|
+
const rpc_1 = require("../rpc");
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
const types_1 = require("./types");
|
|
10
|
+
class Transmitter {
|
|
11
|
+
constructor(protoTypeName, payload, ledger, changePkh) {
|
|
12
|
+
this._signatures = [];
|
|
13
|
+
this._transactions = [];
|
|
14
|
+
this._protoBuf = protoRoot.lookupType(protoTypeName);
|
|
15
|
+
this._payload = payload;
|
|
16
|
+
this.ledger = ledger;
|
|
17
|
+
if (!ledger.provider.network) {
|
|
18
|
+
throw TypeError(`${this.constructor.name}: ledger's provider is not initialized.`);
|
|
19
|
+
}
|
|
20
|
+
this.changePkh = changePkh || ledger.changePkh;
|
|
21
|
+
if (!ledger.getSigner(this.changePkh)) {
|
|
22
|
+
throw TypeError(`${this.constructor.name}: ledger holds no Signer for change address ${this.changePkh}.`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
get payload() {
|
|
26
|
+
return this._payload.prepared ? this._payload : undefined;
|
|
27
|
+
}
|
|
28
|
+
get provider() {
|
|
29
|
+
return this.ledger.provider;
|
|
30
|
+
}
|
|
31
|
+
get network() {
|
|
32
|
+
return this.provider.network || "mainnet";
|
|
33
|
+
}
|
|
34
|
+
get transactions() {
|
|
35
|
+
return this._transactions;
|
|
36
|
+
}
|
|
37
|
+
get type() {
|
|
38
|
+
return this._payload.constructor.name.split(/([a-z](?=[A-Z]))/g).slice(0, -1).join("");
|
|
39
|
+
}
|
|
40
|
+
get _from() {
|
|
41
|
+
if (this._signatures.length > 0) {
|
|
42
|
+
return this._signatures
|
|
43
|
+
.map(ks => {
|
|
44
|
+
const pkh = types_1.PublicKey.fromProtobuf(ks.public_key).hash().toBech32(this.network);
|
|
45
|
+
return this.ledger.getSigner(pkh)?.pkh || this.ledger.pkh;
|
|
46
|
+
})
|
|
47
|
+
// avoid repetitions
|
|
48
|
+
.filter((pkh, index, array) => index === array.indexOf(pkh));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
get _prepared() {
|
|
55
|
+
return (this._payload.prepared
|
|
56
|
+
&& !!this._signatures
|
|
57
|
+
&& this._signatures.length > 0);
|
|
58
|
+
}
|
|
59
|
+
async sendTransaction(target) {
|
|
60
|
+
let receipt = this._getInflightReceipt();
|
|
61
|
+
if (!receipt || target) {
|
|
62
|
+
// if inflight not yet prepared, or prepared but not yet transmitted,
|
|
63
|
+
// prepare a new inflight either with specified params (if any),
|
|
64
|
+
// or previously prepared inflight (if known).
|
|
65
|
+
receipt = await this.signTransaction(target || receipt);
|
|
66
|
+
}
|
|
67
|
+
if (receipt?.status && receipt.status !== "signed" && !receipt?.error) {
|
|
68
|
+
// if current inflight was already transmitted and it's not yet known to fail ...
|
|
69
|
+
return receipt;
|
|
70
|
+
}
|
|
71
|
+
// if we reach this point is because an inflight transaction is
|
|
72
|
+
// ready to be transmitted
|
|
73
|
+
rpc_1.JsonRpcProvider.receipts[receipt.hash].status = "pending";
|
|
74
|
+
delete rpc_1.JsonRpcProvider.receipts[receipt.hash].error;
|
|
75
|
+
return this.provider
|
|
76
|
+
.sendRawTransaction(this._toJSON(false))
|
|
77
|
+
.catch(err => {
|
|
78
|
+
const error = new types_1.TransmissionError(this._getInflightTransmission(), err);
|
|
79
|
+
rpc_1.JsonRpcProvider.receipts[receipt.hash].error = error;
|
|
80
|
+
throw error;
|
|
81
|
+
})
|
|
82
|
+
.then(accepted => {
|
|
83
|
+
if (accepted) {
|
|
84
|
+
rpc_1.JsonRpcProvider.receipts[receipt.hash].status = "relayed";
|
|
85
|
+
return rpc_1.JsonRpcProvider.receipts[receipt.hash];
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const error = new types_1.TransmissionError(this._getInflightTransmission(), Error(`Rejected for unknown reasons`));
|
|
89
|
+
rpc_1.JsonRpcProvider.receipts[receipt.hash].error = error;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async signTransaction(target, reloadUtxos = false) {
|
|
95
|
+
target = await this._payload.validateTarget(target);
|
|
96
|
+
if (!target) {
|
|
97
|
+
// e.g. if called from this.send() with no params
|
|
98
|
+
throw TypeError(`${this.constructor.name}: cannot sign a transaction if no params were previously specified.`);
|
|
99
|
+
}
|
|
100
|
+
const inflight = this._getInflightReceipt();
|
|
101
|
+
if (inflight) {
|
|
102
|
+
// console.log("sign.pendingReceipt =>", inflight)
|
|
103
|
+
if (!inflight?.status || inflight.status === "signed") {
|
|
104
|
+
// recover input utxos if previously signed params were not even attempted to be sent
|
|
105
|
+
if (!reloadUtxos)
|
|
106
|
+
this._recoverInputUtxos();
|
|
107
|
+
}
|
|
108
|
+
else if (inflight.status === "pending" && !inflight.error) {
|
|
109
|
+
// throw exception if a formerly signed transaction is still waiting to be relayed by a provider
|
|
110
|
+
throw Error(`${this.constructor.name}: in-flight tx being relayed: ${inflight.hash}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// clean current signatures, so new UTXOs can be consumed and therefore a new transaction hash be incepted
|
|
114
|
+
this._cleanSignatures(target);
|
|
115
|
+
// if not yet prepared, try to cover transaction expenses with existing utxos on signers:
|
|
116
|
+
if (!this._payload.prepared) {
|
|
117
|
+
await this._payload.consumeUtxos(this.ledger, reloadUtxos)
|
|
118
|
+
.catch((err) => {
|
|
119
|
+
throw Error(`${this.constructor.name}: cannot consume UTXOs from ${this.ledger.constructor.name} ${this.ledger.pkh}: ${err}.`);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (!this._payload.prepared) {
|
|
123
|
+
// throws exeception if not enough utxos were found to cover transaction expenses:
|
|
124
|
+
throw Error(`${this.constructor.name}: insufficient funds on ${this.ledger.constructor.name} ${this.ledger.pkh}.`);
|
|
125
|
+
}
|
|
126
|
+
// double-check weight does not exceeds block limit...
|
|
127
|
+
if (this._payload.weight > this._payload.maxWeight) {
|
|
128
|
+
throw Error(`${this.constructor.name}: transaction weight exceeded block limit: ${this._payload.weight} > ${this._payload.maxWeight}.`);
|
|
129
|
+
}
|
|
130
|
+
// signing the transaction payload generates the transaction hash, and the receipt
|
|
131
|
+
return this._upsertTransactionReceipt(this._signTransactionPayload(), target, "signed");
|
|
132
|
+
}
|
|
133
|
+
async confirmTransaction(hash, options) {
|
|
134
|
+
let receipt = rpc_1.JsonRpcProvider.receipts[hash];
|
|
135
|
+
if (!receipt || receipt.hash !== hash) {
|
|
136
|
+
throw new Error(`${this.constructor.name}: transaction not found: ${hash}`);
|
|
137
|
+
}
|
|
138
|
+
else if (["signed", "pending"].includes(receipt.status)) {
|
|
139
|
+
throw new Error(`${this.constructor.name}: transaction status "${receipt.status}": ${hash}`);
|
|
140
|
+
}
|
|
141
|
+
else if (receipt.status === "removed") {
|
|
142
|
+
throw new types_1.MempoolError(receipt, `${this.constructor.name}: transaction removed from mempool: ${hash}`);
|
|
143
|
+
}
|
|
144
|
+
else if (receipt.status === "relayed" && options?.onStatusChange)
|
|
145
|
+
try {
|
|
146
|
+
options.onStatusChange(receipt);
|
|
147
|
+
}
|
|
148
|
+
catch { }
|
|
149
|
+
;
|
|
150
|
+
const globalTimer = (start, ms) => {
|
|
151
|
+
return new Promise((_, reject) => {
|
|
152
|
+
setTimeout(() => reject(`${this.constructor.name}: polling timeout after ${Math.floor((Date.now() - start) / 1000)} secs).`), ms);
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
const [confirmations, interval, timeout, globalTimeout] = [
|
|
156
|
+
options?.confirmations || 0,
|
|
157
|
+
10000,
|
|
158
|
+
5000,
|
|
159
|
+
(options?.timeoutSecs || 600) * 1000,
|
|
160
|
+
];
|
|
161
|
+
return Promise.race([
|
|
162
|
+
globalTimer(Date.now(), globalTimeout)
|
|
163
|
+
.catch((reason) => { throw new types_1.TimeoutError(globalTimeout, receipt, reason); }),
|
|
164
|
+
promisePoller({
|
|
165
|
+
taskFn: () => this.provider.getTransaction(hash),
|
|
166
|
+
shouldContinue: (error, report) => {
|
|
167
|
+
const status = receipt.status;
|
|
168
|
+
receipt.error = error;
|
|
169
|
+
if (error instanceof Error && error.message.indexOf("not found") >= 0) {
|
|
170
|
+
receipt.status = "removed";
|
|
171
|
+
}
|
|
172
|
+
else
|
|
173
|
+
switch (receipt.status) {
|
|
174
|
+
case "relayed":
|
|
175
|
+
if (report?.blockHash && (0, utils_1.isHexString)(report.blockHash)) {
|
|
176
|
+
receipt.confirmations = report.confirmations;
|
|
177
|
+
receipt.blockHash = report.blockHash,
|
|
178
|
+
receipt.blockEpoch = report.blockEpoch,
|
|
179
|
+
receipt.blockTimestamp = report.blockTimestamp;
|
|
180
|
+
receipt.status = (report.confirmed
|
|
181
|
+
? "finalized"
|
|
182
|
+
: (report?.confirmations >= confirmations ? "confirmed" : "mined"));
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
185
|
+
case "mined":
|
|
186
|
+
if (!report?.blockHash || report.blockHash !== receipt.blockHash) {
|
|
187
|
+
delete receipt.blockHash;
|
|
188
|
+
delete receipt.blockEpoch;
|
|
189
|
+
delete receipt.blockMiner;
|
|
190
|
+
delete receipt.blockTimestamp;
|
|
191
|
+
receipt.status = "relayed";
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
receipt.status = (report.confirmed
|
|
195
|
+
? "finalized"
|
|
196
|
+
: (report?.confirmations >= confirmations ? "confirmed" : "mined"));
|
|
197
|
+
if (report.confirmations !== receipt.confirmations) {
|
|
198
|
+
receipt.confirmations = report.confirmations;
|
|
199
|
+
if (receipt.status === "mined" && options?.onCheckpoint)
|
|
200
|
+
try {
|
|
201
|
+
options.onCheckpoint(receipt);
|
|
202
|
+
}
|
|
203
|
+
catch { }
|
|
204
|
+
;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
;
|
|
210
|
+
if (status !== receipt.status) {
|
|
211
|
+
receipt.timestamp = Math.floor(Date.now() / 1000);
|
|
212
|
+
if (!["confirmed", "finalized"].includes(receipt.status) && options?.onStatusChange)
|
|
213
|
+
try {
|
|
214
|
+
options.onStatusChange(receipt);
|
|
215
|
+
}
|
|
216
|
+
catch { }
|
|
217
|
+
;
|
|
218
|
+
}
|
|
219
|
+
rpc_1.JsonRpcProvider.receipts[hash] = receipt;
|
|
220
|
+
return ["relayed", "mined"].includes(receipt.status);
|
|
221
|
+
},
|
|
222
|
+
interval, timeout,
|
|
223
|
+
}).then(async () => {
|
|
224
|
+
if (receipt.status === "removed" && receipt.type !== "Unstake") {
|
|
225
|
+
// TRANSACTION REMOVED FROM MEMPOOL //
|
|
226
|
+
// 1. Try to recover input utxos belonging to ledger's addresses:
|
|
227
|
+
try {
|
|
228
|
+
const inputs = receipt.tx[receipt.type].body.inputs;
|
|
229
|
+
const signatures = receipt.tx[receipt.type].signatures;
|
|
230
|
+
const utxos = [];
|
|
231
|
+
if (inputs.length === signatures.length) {
|
|
232
|
+
inputs.forEach((metadata, index) => ({
|
|
233
|
+
...metadata,
|
|
234
|
+
signer: types_1.PublicKey.fromProtobuf(signatures[index].public_key).hash().toBech32(this.network),
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
this.ledger.addUtxos(...utxos);
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
console.error(`${this.constructor.name}: warning: cannot recover input UTXOS from tx ${hash}: ${err}`);
|
|
241
|
+
}
|
|
242
|
+
// 2. Throw MempoolError
|
|
243
|
+
throw new types_1.MempoolError(receipt, `${this.constructor.name}: transaction removed from mempool: ${hash}`);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
// TRANSACTION EITHER CONFIRMED OR FINALIZED //
|
|
247
|
+
// 1. Try to load value transfer outputs into the ledger's local cache:
|
|
248
|
+
try {
|
|
249
|
+
const utxos = [];
|
|
250
|
+
if (["Stake", "Unstake"].includes(receipt.type)) {
|
|
251
|
+
let vto = (receipt.type === "Stake"
|
|
252
|
+
? receipt.tx[receipt.type].body?.output
|
|
253
|
+
: receipt.tx[receipt.type].body?.withdrawal);
|
|
254
|
+
if (vto) {
|
|
255
|
+
utxos.push({
|
|
256
|
+
output_pointer: `${receipt.hash}:0`,
|
|
257
|
+
timelock: vto.time_lock,
|
|
258
|
+
utxo_mature: true,
|
|
259
|
+
value: vto.value,
|
|
260
|
+
signer: vto.pkh,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
const outputs = receipt.tx[receipt.type].body?.outputs || [];
|
|
266
|
+
outputs.forEach((vto, index) => utxos.push({
|
|
267
|
+
output_pointer: `${receipt.hash}:${index}`,
|
|
268
|
+
timelock: vto.time_lock,
|
|
269
|
+
utxo_mature: true,
|
|
270
|
+
value: vto.value,
|
|
271
|
+
signer: vto.pkh,
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
// console.log("output utxos before =>", utxos)
|
|
275
|
+
// console.log("output utxos after =>", this.ledger.addUtxos(...utxos))
|
|
276
|
+
this.ledger.addUtxos(...utxos);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
console.error(`${this.constructor.name}: warning: cannot recover output UTXOs from ${hash}: ${err}`);
|
|
280
|
+
}
|
|
281
|
+
// 2. Add blockMiner address to the transaction receipt:
|
|
282
|
+
if (receipt?.blockHash && (0, utils_1.isHexString)(receipt.blockHash)) {
|
|
283
|
+
const block = await this.provider.getBlock(receipt.blockHash || "");
|
|
284
|
+
rpc_1.JsonRpcProvider.receipts[hash].blockMiner = types_1.PublicKey
|
|
285
|
+
.fromProtobuf(block.block_sig.public_key)
|
|
286
|
+
.hash()
|
|
287
|
+
.toBech32(this.network);
|
|
288
|
+
}
|
|
289
|
+
if (options?.onStatusChange)
|
|
290
|
+
try {
|
|
291
|
+
options.onStatusChange(receipt);
|
|
292
|
+
}
|
|
293
|
+
catch { }
|
|
294
|
+
;
|
|
295
|
+
// 3. Return transaction receipt:
|
|
296
|
+
return rpc_1.JsonRpcProvider.receipts[hash];
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
]);
|
|
300
|
+
}
|
|
301
|
+
_cleanSignatures(newTarget) {
|
|
302
|
+
this._payload.resetTarget(newTarget);
|
|
303
|
+
this._signatures = [];
|
|
304
|
+
}
|
|
305
|
+
_getInflightBytecode() {
|
|
306
|
+
const obj = this._toProtobuf();
|
|
307
|
+
const err = this._protoBuf.verify(obj);
|
|
308
|
+
if (!err) {
|
|
309
|
+
const message = this._protoBuf.fromObject(obj);
|
|
310
|
+
return this._protoBuf.encode(message).finish();
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
return undefined;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
_getInflightReceipt() {
|
|
317
|
+
const hash = this._payload.hash;
|
|
318
|
+
if (hash) {
|
|
319
|
+
return rpc_1.JsonRpcProvider.receipts[hash];
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
return undefined;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
_getInflightTransmission() {
|
|
326
|
+
return {
|
|
327
|
+
bytecode: this._getInflightBytecode(),
|
|
328
|
+
hash: this._payload.hash,
|
|
329
|
+
message: this._toJSON(true),
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
_recoverInputUtxos() { }
|
|
333
|
+
_recoverOutputUtxos() { }
|
|
334
|
+
_upsertTransactionReceipt(hash, target, status) {
|
|
335
|
+
rpc_1.JsonRpcProvider.receipts[hash] = {
|
|
336
|
+
...this._payload.intoReceipt(target, this.network),
|
|
337
|
+
hash,
|
|
338
|
+
change: this._payload.change,
|
|
339
|
+
fees: this._payload.fees,
|
|
340
|
+
from: this._from,
|
|
341
|
+
status,
|
|
342
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
343
|
+
tx: this._toJSON(true),
|
|
344
|
+
type: this.type,
|
|
345
|
+
value: this._payload.value,
|
|
346
|
+
weight: this._payload.weight,
|
|
347
|
+
};
|
|
348
|
+
return rpc_1.JsonRpcProvider.receipts[hash];
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
exports.Transmitter = Transmitter;
|
|
352
|
+
class TransmitterMultiSig extends Transmitter {
|
|
353
|
+
constructor(protoTypeName, payload, ledger, changePkh) {
|
|
354
|
+
super(protoTypeName, payload, ledger, changePkh);
|
|
355
|
+
this._payload = payload;
|
|
356
|
+
}
|
|
357
|
+
/// Recover formerly consumed UTXOs by a failing transaction back to their respective signer's UTXO pool
|
|
358
|
+
_recoverInputUtxos() {
|
|
359
|
+
if (this._payload.inputs) {
|
|
360
|
+
this.ledger.addUtxos(...this._payload.inputs);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/// Recover self-targeted outputs as expendable utxos on their respective signer's memoized cache
|
|
364
|
+
_recoverOutputUtxos() {
|
|
365
|
+
if (this._payload.hash && this._payload.outputs) {
|
|
366
|
+
const utxos = [];
|
|
367
|
+
this._payload.outputs.forEach((vto, index) => {
|
|
368
|
+
if (this.ledger.getSigner(vto.pkh))
|
|
369
|
+
utxos.push({
|
|
370
|
+
signer: vto.pkh,
|
|
371
|
+
output_pointer: `${this._payload.hash}:${index}`,
|
|
372
|
+
timelock: vto.time_lock,
|
|
373
|
+
value: vto.value,
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
this.ledger.addUtxos(...utxos);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
_signTransactionPayload() {
|
|
380
|
+
const hash = this._payload.hash;
|
|
381
|
+
if (!hash) {
|
|
382
|
+
throw Error(`${this.constructor.name}: internal error: unable to hashify payload: ${this._payload.toJSON(true, this.network)}}.`);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
this._payload.inputs.forEach(utxo => {
|
|
386
|
+
const signer = this.ledger.getSigner(utxo.signer);
|
|
387
|
+
if (!signer)
|
|
388
|
+
throw Error(`${this.constructor.name}: internal error: cannot find Signer ${utxo.signer} in ${this.ledger.constructor.name} ${this.ledger.pkh}.`);
|
|
389
|
+
else {
|
|
390
|
+
// console.log(`...signer ${signer.pkh} signing hash ${hash}...`)
|
|
391
|
+
this._signatures.push(signer.signHash(hash));
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
return hash;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
_toJSON(humanize) {
|
|
398
|
+
return {
|
|
399
|
+
[this.type]: {
|
|
400
|
+
body: this._payload.toJSON(humanize, this.network),
|
|
401
|
+
signatures: this._signatures,
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
_toProtobuf() {
|
|
406
|
+
const body = this._payload.toProtobuf();
|
|
407
|
+
if (body && this._signatures) {
|
|
408
|
+
return {
|
|
409
|
+
body,
|
|
410
|
+
signatures: this._signatures,
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
exports.TransmitterMultiSig = TransmitterMultiSig;
|
|
416
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNtaXR0ZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9jcnlwdG8vdHJhbnNtaXR0ZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUV4RCwyQ0FBaUU7QUFDakUsTUFBTSxTQUFTLEdBQUcsaUJBQVMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLG1DQUFtQyxDQUFDLENBQUMsQ0FBQTtBQUdsRixnQ0FBd0M7QUFFeEMsb0NBQXVDO0FBVXZDLG1DQVlnQjtBQUVoQixNQUFzQixXQUFXO0lBVTdCLFlBQWEsYUFBcUIsRUFBRSxPQUFnQixFQUFFLE1BQWUsRUFBRSxTQUErQjtRQUg1RixnQkFBVyxHQUEwQixFQUFFLENBQUE7UUFDdkMsa0JBQWEsR0FBZ0IsRUFBRSxDQUFBO1FBR3JDLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQTtRQUNwRCxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQTtRQUNwQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMzQixNQUFNLFNBQVMsQ0FBQyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSx5Q0FBeUMsQ0FBQyxDQUFBO1FBQ3RGLENBQUM7UUFDRCxJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFBO1FBQzlDLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLCtDQUErQyxJQUFJLENBQUMsU0FBUyxH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dkksQ0FBQztxQkFBTSxDQUFDO29CQUNMLGlFQUFpRTtvQkFDakUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO2dCQUNoRCxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUE7WUFDRixPQUFPLElBQUksQ0FBQTtRQUNmLENBQUM7SUFDTCxDQUFDO0lBRVMsT0FBTyxDQUFDLFFBQWlCO1FBQy9CLE9BQU87WUFDSCxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDVCxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUM7Z0JBQ2xELFVBQVUsRUFBRSxJQUFJLENBQUMsV0FBVzthQUMvQjtTQUNKLENBQUE7SUFDTCxDQUFDO0lBRVMsV0FBVztRQUNqQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBQ3ZDLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQixPQUFPO2dCQUNILElBQUk7Z0JBQ0osVUFBVSxFQUFFLElBQUksQ0FBQyxXQUFXO2FBQy9CLENBQUE7UUFDTCxDQUFDO0lBQ0wsQ0FBQztDQUNKO0FBckVELGtEQXFFQyIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHByb21pc2VQb2xsZXIgPSByZXF1aXJlKCdwcm9taXNlLXBvbGxlcicpLmRlZmF1bHQ7XHJcblxyXG5pbXBvcnQgeyBSb290IGFzIFByb3RvUm9vdCwgVHlwZSBhcyBQcm90b1R5cGUgfSBmcm9tIFwicHJvdG9idWZqc1wiXHJcbmNvbnN0IHByb3RvUm9vdCA9IFByb3RvUm9vdC5mcm9tSlNPTihyZXF1aXJlKFwiLi4vLi4vLi4vd2l0bmV0L3dpdG5ldC5wcm90by5qc29uXCIpKSBcclxuXHJcbmltcG9ydCB7IFRyYW5zYWN0aW9uUmVwb3J0LCBVdHhvTWV0YWRhdGEsIFZhbHVlVHJhbnNmZXJPdXRwdXQgfSBmcm9tIFwiLi4vcnBjL3R5cGVzXCJcclxuaW1wb3J0IHsgSnNvblJwY1Byb3ZpZGVyIH0gZnJvbSBcIi4uL3JwY1wiXHJcbmltcG9ydCB7IEhhc2gsIE5ldHdvcmsgfSBmcm9tIFwiLi4vdHlwZXNcIlxyXG5pbXBvcnQgeyBpc0hleFN0cmluZyB9IGZyb20gXCIuLi91dGlsc1wiO1xyXG5cclxuaW1wb3J0IHsgXHJcbiAgICBJTGVkZ2VyLFxyXG4gICAgSUpzb25ScGNQcm92aWRlciwgXHJcbiAgICBJVHJhbnNtaXR0ZXIsIFxyXG4gICAgSVRyYW5zYWN0aW9uUGF5bG9hZCwgXHJcbiAgICBJVHJhbnNhY3Rpb25QYXlsb2FkTXVsdGlTaWcsIFxyXG59IGZyb20gXCIuL2ludGVyZmFjZXNcIlxyXG5cclxuaW1wb3J0IHsgXHJcbiAgICBLZXllZFNpZ25hdHVyZSwgXHJcbiAgICBQdWJsaWNLZXksIFxyXG4gICAgUHVibGljS2V5SGFzaFN0cmluZywgXHJcbiAgICBNZW1wb29sRXJyb3IsXHJcbiAgICBUcmFuc2FjdGlvbkNhbGxiYWNrLCBcclxuICAgIFRyYW5zYWN0aW9uUmVjZWlwdCwgXHJcbiAgICBUcmFuc2FjdGlvblN0YXR1cywgXHJcbiAgICBUaW1lb3V0RXJyb3IsXHJcbiAgICBUcmFuc21pc3Npb24sXHJcbiAgICBUcmFuc21pc3Npb25FcnJvcixcclxuICAgIFV0eG8sXHJcbn0gZnJvbSBcIi4vdHlwZXNcIlxyXG5cclxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFRyYW5zbWl0dGVyPFNwZWNzLCBQYXlsb2FkIGV4dGVuZHMgSVRyYW5zYWN0aW9uUGF5bG9hZDxTcGVjcz4+IGltcGxlbWVudHMgSVRyYW5zbWl0dGVyIHtcclxuICAgIFxyXG4gICAgcHVibGljIHJlYWRvbmx5IGxlZGdlcjogSUxlZGdlcjtcclxuICAgIHB1YmxpYyByZWFkb25seSBjaGFuZ2VQa2g6IFB1YmxpY0tleUhhc2hTdHJpbmc7XHJcbiAgICBcclxuICAgIHByb3RlY3RlZCBfcGF5bG9hZDogUGF5bG9hZDtcclxuICAgIHByb3RlY3RlZCBfcHJvdG9CdWY6IFByb3RvVHlwZTtcclxuICAgIHByb3RlY3RlZCBfc2lnbmF0dXJlczogQXJyYXk8S2V5ZWRTaWduYXR1cmU+ID0gW11cclxuICAgIHByb3RlY3RlZCBfdHJhbnNhY3Rpb25zOiBBcnJheTxIYXNoPiA9IFtdXHJcblxyXG4gICAgY29uc3RydWN0b3IgKHByb3RvVHlwZU5hbWU6IHN0cmluZywgcGF5bG9hZDogUGF5bG9hZCwgbGVkZ2VyOiBJTGVkZ2VyLCBjaGFuZ2VQa2g/OiBQdWJsaWNLZXlIYXNoU3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5fcHJvdG9CdWYgPSBwcm90b1Jvb3QubG9va3VwVHlwZShwcm90b1R5cGVOYW1lKVxyXG4gICAgICAgIHRoaXMuX3BheWxvYWQgPSBwYXlsb2FkO1xyXG4gICAgICAgIHRoaXMubGVkZ2VyID0gbGVkZ2VyXHJcbiAgICAgICAgaWYgKCFsZWRnZXIucHJvdmlkZXIubmV0d29yaykge1xyXG4gICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogbGVkZ2VyJ3MgcHJvdmlkZXIgaXMgbm90IGluaXRpYWxpemVkLmApXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY2hhbmdlUGtoID0gY2hhbmdlUGtoIHx8IGxlZGdlci5jaGFuZ2VQa2hcclxuICAgICAgICBpZiAoIWxlZGdlci5nZXRTaWduZXIodGhpcy5jaGFuZ2VQa2gpKSB7XHJcbiAgICAgICAgICAgIHRocm93IFR5cGVFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9OiBsZWRnZXIgaG9sZHMgbm8gU2lnbmVyIGZvciBjaGFuZ2UgYWRkcmVzcyAke3RoaXMuY2hhbmdlUGtofS5gKVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IHBheWxvYWQoKTogUGF5bG9hZCB8IHVuZGVmaW5lZCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BheWxvYWQucHJlcGFyZWQgPyB0aGlzLl9wYXlsb2FkIDogdW5kZWZpbmVkXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBwcm92aWRlcigpOiBJSnNvblJwY1Byb3ZpZGVyIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sZWRnZXIucHJvdmlkZXJcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IG5ldHdvcmsoKTogTmV0d29yayB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvdmlkZXIubmV0d29yayB8fCBcIm1haW5uZXRcIlxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXQgdHJhbnNhY3Rpb25zKCk6IEFycmF5PEhhc2g+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdHJhbnNhY3Rpb25zXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCB0eXBlKCk6IHN0cmluZyB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BheWxvYWQuY29uc3RydWN0b3IubmFtZS5zcGxpdCgvKFthLXpdKD89W0EtWl0pKS9nKS5zbGljZSgwLCAtMSkuam9pbihcIlwiKVxyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBnZXQgX2Zyb20oKTogQXJyYXk8UHVibGljS2V5SGFzaFN0cmluZz4gfCB1bmRlZmluZWQge1xyXG4gICAgICAgIGlmICh0aGlzLl9zaWduYXR1cmVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NpZ25hdHVyZXNcclxuICAgICAgICAgICAgICAgIC5tYXAoa3MgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBraCA9IFB1YmxpY0tleS5mcm9tUHJvdG9idWYoa3MucHVibGljX2tleSkuaGFzaCgpLnRvQmVjaDMyKHRoaXMubmV0d29yaylcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5sZWRnZXIuZ2V0U2lnbmVyKHBraCk/LnBraCB8fCB0aGlzLmxlZGdlci5wa2hcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAvLyBhdm9pZCByZXBldGl0aW9uc1xyXG4gICAgICAgICAgICAgICAgLmZpbHRlcigocGtoLCBpbmRleCwgYXJyYXkpID0+IGluZGV4ID09PSBhcnJheS5pbmRleE9mKHBraCkpXHJcbiAgICAgICAgXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZFxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgZ2V0IF9wcmVwYXJlZCgpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICB0aGlzLl9wYXlsb2FkLnByZXBhcmVkXHJcbiAgICAgICAgICAgICAgICAmJiAhIXRoaXMuX3NpZ25hdHVyZXNcclxuICAgICAgICAgICAgICAgICYmIHRoaXMuX3NpZ25hdHVyZXMubGVuZ3RoID4gMFxyXG4gICAgICAgIClcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgYXN5bmMgc2VuZFRyYW5zYWN0aW9uKHRhcmdldD86IGFueSk6IFByb21pc2U8VHJhbnNhY3Rpb25SZWNlaXB0PiB7XHJcbiAgICAgICAgbGV0IHJlY2VpcHQgPSB0aGlzLl9nZXRJbmZsaWdodFJlY2VpcHQoKVxyXG4gICAgICAgIGlmICghcmVjZWlwdCB8fCB0YXJnZXQpIHtcclxuICAgICAgICAgICAgLy8gaWYgaW5mbGlnaHQgbm90IHlldCBwcmVwYXJlZCwgb3IgcHJlcGFyZWQgYnV0IG5vdCB5ZXQgdHJhbnNtaXR0ZWQsXHJcbiAgICAgICAgICAgIC8vIHByZXBhcmUgYSBuZXcgaW5mbGlnaHQgZWl0aGVyIHdpdGggc3BlY2lmaWVkIHBhcmFtcyAoaWYgYW55KSxcclxuICAgICAgICAgICAgLy8gb3IgcHJldmlvdXNseSBwcmVwYXJlZCBpbmZsaWdodCAoaWYga25vd24pLlxyXG4gICAgICAgICAgICByZWNlaXB0ID0gYXdhaXQgdGhpcy5zaWduVHJhbnNhY3Rpb24odGFyZ2V0IHx8IHJlY2VpcHQpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChyZWNlaXB0Py5zdGF0dXMgJiYgcmVjZWlwdC5zdGF0dXMgIT09IFwic2lnbmVkXCIgJiYgIXJlY2VpcHQ/LmVycm9yKSB7XHJcbiAgICAgICAgICAgIC8vIGlmIGN1cnJlbnQgaW5mbGlnaHQgd2FzIGFscmVhZHkgdHJhbnNtaXR0ZWQgYW5kIGl0J3Mgbm90IHlldCBrbm93biB0byBmYWlsIC4uLlxyXG4gICAgICAgICAgICByZXR1cm4gcmVjZWlwdFxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBpZiB3ZSByZWFjaCB0aGlzIHBvaW50IGlzIGJlY2F1c2UgYW4gaW5mbGlnaHQgdHJhbnNhY3Rpb24gaXMgXHJcbiAgICAgICAgLy8gcmVhZHkgdG8gYmUgdHJhbnNtaXR0ZWRcclxuICAgICAgICBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbcmVjZWlwdC5oYXNoXS5zdGF0dXMgPSBcInBlbmRpbmdcIlxyXG4gICAgICAgIGRlbGV0ZSBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbcmVjZWlwdC5oYXNoXS5lcnJvclxyXG4gICAgICAgIHJldHVybiB0aGlzLnByb3ZpZGVyXHJcbiAgICAgICAgICAgIC5zZW5kUmF3VHJhbnNhY3Rpb24odGhpcy5fdG9KU09OKGZhbHNlKSlcclxuICAgICAgICAgICAgLmNhdGNoKGVyciA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBUcmFuc21pc3Npb25FcnJvcih0aGlzLl9nZXRJbmZsaWdodFRyYW5zbWlzc2lvbigpLCBlcnIpXHJcbiAgICAgICAgICAgICAgICBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbcmVjZWlwdC5oYXNoXS5lcnJvciA9IGVycm9yXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAudGhlbihhY2NlcHRlZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWNjZXB0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbcmVjZWlwdC5oYXNoXS5zdGF0dXMgPSBcInJlbGF5ZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbcmVjZWlwdC5oYXNoXVxyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBUcmFuc21pc3Npb25FcnJvcih0aGlzLl9nZXRJbmZsaWdodFRyYW5zbWlzc2lvbigpLCBFcnJvcihgUmVqZWN0ZWQgZm9yIHVua25vd24gcmVhc29uc2ApKVxyXG4gICAgICAgICAgICAgICAgICAgIEpzb25ScGNQcm92aWRlci5yZWNlaXB0c1tyZWNlaXB0Lmhhc2hdLmVycm9yID0gZXJyb3JcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBlcnJvclxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBhc3luYyBzaWduVHJhbnNhY3Rpb24odGFyZ2V0PzogU3BlY3MsIHJlbG9hZFV0eG9zID0gZmFsc2UpOiBQcm9taXNlPFRyYW5zYWN0aW9uUmVjZWlwdD4ge1xyXG4gICAgICAgIHRhcmdldCA9IGF3YWl0IHRoaXMuX3BheWxvYWQudmFsaWRhdGVUYXJnZXQodGFyZ2V0KVxyXG4gICAgICAgIGlmICghdGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIC8vIGUuZy4gaWYgY2FsbGVkIGZyb20gdGhpcy5zZW5kKCkgd2l0aCBubyBwYXJhbXNcclxuICAgICAgICAgICAgdGhyb3cgVHlwZUVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IGNhbm5vdCBzaWduIGEgdHJhbnNhY3Rpb24gaWYgbm8gcGFyYW1zIHdlcmUgcHJldmlvdXNseSBzcGVjaWZpZWQuYClcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgaW5mbGlnaHQgPSB0aGlzLl9nZXRJbmZsaWdodFJlY2VpcHQoKVxyXG4gICAgICAgIGlmIChpbmZsaWdodCkge1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcInNpZ24ucGVuZGluZ1JlY2VpcHQgPT5cIiwgaW5mbGlnaHQpXHJcbiAgICAgICAgICAgIGlmICghaW5mbGlnaHQ/LnN0YXR1cyB8fCBpbmZsaWdodC5zdGF0dXMgPT09IFwic2lnbmVkXCIpIHtcclxuICAgICAgICAgICAgICAgIC8vIHJlY292ZXIgaW5wdXQgdXR4b3MgaWYgcHJldmlvdXNseSBzaWduZWQgcGFyYW1zIHdlcmUgbm90IGV2ZW4gYXR0ZW1wdGVkIHRvIGJlIHNlbnRcclxuICAgICAgICAgICAgICAgIGlmICghcmVsb2FkVXR4b3MpIHRoaXMuX3JlY292ZXJJbnB1dFV0eG9zKClcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5mbGlnaHQuc3RhdHVzID09PSBcInBlbmRpbmdcIiAmJiAhaW5mbGlnaHQuZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIC8vIHRocm93IGV4Y2VwdGlvbiBpZiBhIGZvcm1lcmx5IHNpZ25lZCB0cmFuc2FjdGlvbiBpcyBzdGlsbCB3YWl0aW5nIHRvIGJlIHJlbGF5ZWQgYnkgYSBwcm92aWRlclxyXG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogaW4tZmxpZ2h0IHR4IGJlaW5nIHJlbGF5ZWQ6ICR7aW5mbGlnaHQuaGFzaH1gKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBcclxuICAgICAgICBcclxuICAgICAgICAvLyBjbGVhbiBjdXJyZW50IHNpZ25hdHVyZXMsIHNvIG5ldyBVVFhPcyBjYW4gYmUgY29uc3VtZWQgYW5kIHRoZXJlZm9yZSBhIG5ldyB0cmFuc2FjdGlvbiBoYXNoIGJlIGluY2VwdGVkXHJcbiAgICAgICAgdGhpcy5fY2xlYW5TaWduYXR1cmVzKHRhcmdldClcclxuICAgICAgICBcclxuICAgICAgICAvLyBpZiBub3QgeWV0IHByZXBhcmVkLCB0cnkgdG8gY292ZXIgdHJhbnNhY3Rpb24gZXhwZW5zZXMgd2l0aCBleGlzdGluZyB1dHhvcyBvbiBzaWduZXJzOlxyXG4gICAgICAgIGlmICghdGhpcy5fcGF5bG9hZC5wcmVwYXJlZCkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9wYXlsb2FkLmNvbnN1bWVVdHhvcyh0aGlzLmxlZGdlciwgcmVsb2FkVXR4b3MpXHJcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyOiBhbnkpID0+IHtcclxuICAgICAgICAgICAgICAgIHRocm93IEVycm9yKFxyXG4gICAgICAgICAgICAgICAgICAgIGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IGNhbm5vdCBjb25zdW1lIFVUWE9zIGZyb20gJHt0aGlzLmxlZGdlci5jb25zdHJ1Y3Rvci5uYW1lfSAke3RoaXMubGVkZ2VyLnBraH06ICR7ZXJyfS5gXHJcbiAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIH0pICBcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYgKCF0aGlzLl9wYXlsb2FkLnByZXBhcmVkKSB7XHJcbiAgICAgICAgICAgIC8vIHRocm93cyBleGVjZXB0aW9uIGlmIG5vdCBlbm91Z2ggdXR4b3Mgd2VyZSBmb3VuZCB0byBjb3ZlciB0cmFuc2FjdGlvbiBleHBlbnNlczpcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXHJcbiAgICAgICAgICAgICAgICBgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9OiBpbnN1ZmZpY2llbnQgZnVuZHMgb24gJHt0aGlzLmxlZGdlci5jb25zdHJ1Y3Rvci5uYW1lfSAke3RoaXMubGVkZ2VyLnBraH0uYFxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgfSBcclxuXHJcbiAgICAgICAgLy8gZG91YmxlLWNoZWNrIHdlaWdodCBkb2VzIG5vdCBleGNlZWRzIGJsb2NrIGxpbWl0Li4uXHJcbiAgICAgICAgaWYgKHRoaXMuX3BheWxvYWQud2VpZ2h0ID4gdGhpcy5fcGF5bG9hZC5tYXhXZWlnaHQpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoXHJcbiAgICAgICAgICAgICAgICBgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9OiB0cmFuc2FjdGlvbiB3ZWlnaHQgZXhjZWVkZWQgYmxvY2sgbGltaXQ6ICR7dGhpcy5fcGF5bG9hZC53ZWlnaHR9ID4gJHt0aGlzLl9wYXlsb2FkLm1heFdlaWdodH0uYFxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBzaWduaW5nIHRoZSB0cmFuc2FjdGlvbiBwYXlsb2FkIGdlbmVyYXRlcyB0aGUgdHJhbnNhY3Rpb24gaGFzaCwgYW5kIHRoZSByZWNlaXB0XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Vwc2VydFRyYW5zYWN0aW9uUmVjZWlwdCh0aGlzLl9zaWduVHJhbnNhY3Rpb25QYXlsb2FkKCksIHRhcmdldCwgXCJzaWduZWRcIikgICAgXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIGNvbmZpcm1UcmFuc2FjdGlvbihcclxuICAgICAgICBoYXNoOiBIYXNoLCBcclxuICAgICAgICBvcHRpb25zPzoge1xyXG4gICAgICAgICAgICBjb25maXJtYXRpb25zPzogbnVtYmVyLFxyXG4gICAgICAgICAgICB0aW1lb3V0U2Vjcz86IG51bWJlcixcclxuICAgICAgICAgICAgb25DaGVja3BvaW50PzogVHJhbnNhY3Rpb25DYWxsYmFjayxcclxuICAgICAgICAgICAgb25TdGF0dXNDaGFuZ2U/OiBUcmFuc2FjdGlvbkNhbGxiYWNrLFxyXG4gICAgICAgIH1cclxuICAgICk6IFByb21pc2U8VHJhbnNhY3Rpb25SZWNlaXB0PiB7XHJcblxyXG4gICAgICAgIGxldCByZWNlaXB0ID0gSnNvblJwY1Byb3ZpZGVyLnJlY2VpcHRzW2hhc2hdXHJcbiAgICAgICAgaWYgKCFyZWNlaXB0IHx8IHJlY2VpcHQuaGFzaCAhPT0gaGFzaCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogdHJhbnNhY3Rpb24gbm90IGZvdW5kOiAke2hhc2h9YClcclxuICAgICAgICBcclxuICAgICAgICB9IGVsc2UgaWYgKFtcInNpZ25lZFwiLCBcInBlbmRpbmdcIl0uaW5jbHVkZXMocmVjZWlwdC5zdGF0dXMpKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9OiB0cmFuc2FjdGlvbiBzdGF0dXMgXCIke3JlY2VpcHQuc3RhdHVzfVwiOiAke2hhc2h9YClcclxuICAgICAgICBcclxuICAgICAgICB9IGVsc2UgaWYgKHJlY2VpcHQuc3RhdHVzID09PSBcInJlbW92ZWRcIikge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgTWVtcG9vbEVycm9yKHJlY2VpcHQsIGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IHRyYW5zYWN0aW9uIHJlbW92ZWQgZnJvbSBtZW1wb29sOiAke2hhc2h9YClcclxuICAgICAgICBcclxuICAgICAgICB9IGVsc2UgaWYgKHJlY2VpcHQuc3RhdHVzID09PSBcInJlbGF5ZWRcIiAmJiBvcHRpb25zPy5vblN0YXR1c0NoYW5nZSkgdHJ5IHtcclxuICAgICAgICAgICAgb3B0aW9ucy5vblN0YXR1c0NoYW5nZShyZWNlaXB0KVxyXG4gICAgICAgIH0gY2F0Y2gge307XHJcblxyXG4gICAgICAgIGNvbnN0IGdsb2JhbFRpbWVyID0gKHN0YXJ0OiBudW1iZXIsIG1zOiBudW1iZXIpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+IHtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoXHJcbiAgICAgICAgICAgICAgICAgICAgKCkgPT4gcmVqZWN0KGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IHBvbGxpbmcgdGltZW91dCBhZnRlciAke01hdGguZmxvb3IoKERhdGUubm93KCkgLSBzdGFydCkgLyAxMDAwKX0gc2VjcykuYCksIFxyXG4gICAgICAgICAgICAgICAgICAgIG1zXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IFtjb25maXJtYXRpb25zLCBpbnRlcnZhbCwgdGltZW91dCwgZ2xvYmFsVGltZW91dF0gPSBbXHJcbiAgICAgICAgICAgIG9wdGlvbnM/LmNvbmZpcm1hdGlvbnMgfHwgMCxcclxuICAgICAgICAgICAgMTAwMDAsXHJcbiAgICAgICAgICAgIDUwMDAsXHJcbiAgICAgICAgICAgIChvcHRpb25zPy50aW1lb3V0U2VjcyB8fCA2MDApICogMTAwMCxcclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yYWNlKFtcclxuICAgICAgICAgICAgZ2xvYmFsVGltZXIoRGF0ZS5ub3coKSwgZ2xvYmFsVGltZW91dClcclxuICAgICAgICAgICAgICAgIC5jYXRjaCgocmVhc29uOiBhbnkpID0+IHsgdGhyb3cgbmV3IFRpbWVvdXRFcnJvcihnbG9iYWxUaW1lb3V0LCByZWNlaXB0LCByZWFzb24pIH0pLFxyXG4gICAgICAgICAgICBcclxuICAgICAgICAgICAgcHJvbWlzZVBvbGxlcih7XHJcbiAgICAgICAgICAgICAgICB0YXNrRm46ICgpID0+IHRoaXMucHJvdmlkZXIuZ2V0VHJhbnNhY3Rpb24oaGFzaCksXHJcbiAgICAgICAgICAgICAgICBzaG91bGRDb250aW51ZTogKGVycm9yOiBhbnksIHJlcG9ydDogVHJhbnNhY3Rpb25SZXBvcnQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdGF0dXMgPSByZWNlaXB0LnN0YXR1c1xyXG4gICAgICAgICAgICAgICAgICAgIHJlY2VpcHQuZXJyb3IgPSBlcnJvclxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yICYmIGVycm9yLm1lc3NhZ2UuaW5kZXhPZihcIm5vdCBmb3VuZFwiKSA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpcHQuc3RhdHVzID0gXCJyZW1vdmVkXCJcclxuICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugc3dpdGNoIChyZWNlaXB0LnN0YXR1cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFwicmVsYXllZFwiOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcG9ydD8uYmxvY2tIYXNoICYmIGlzSGV4U3RyaW5nKHJlcG9ydC5ibG9ja0hhc2gpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdC5jb25maXJtYXRpb25zID0gcmVwb3J0LmNvbmZpcm1hdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXB0LmJsb2NrSGFzaCA9IHJlcG9ydC5ibG9ja0hhc2gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdC5ibG9ja0Vwb2NoID0gcmVwb3J0LmJsb2NrRXBvY2gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdC5ibG9ja1RpbWVzdGFtcCA9IHJlcG9ydC5ibG9ja1RpbWVzdGFtcFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpcHQuc3RhdHVzID0gKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBvcnQuY29uZmlybWVkIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBcImZpbmFsaXplZFwiIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAocmVwb3J0Py5jb25maXJtYXRpb25zID49IGNvbmZpcm1hdGlvbnMgPyBcImNvbmZpcm1lZFwiIDogXCJtaW5lZFwiKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgXCJtaW5lZFwiOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXBvcnQ/LmJsb2NrSGFzaCB8fCByZXBvcnQuYmxvY2tIYXNoICE9PSByZWNlaXB0LmJsb2NrSGFzaCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZWNlaXB0LmJsb2NrSGFzaFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByZWNlaXB0LmJsb2NrRXBvY2hcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgcmVjZWlwdC5ibG9ja01pbmVyXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHJlY2VpcHQuYmxvY2tUaW1lc3RhbXBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXB0LnN0YXR1cyA9IFwicmVsYXllZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdC5zdGF0dXMgPSAoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcG9ydC5jb25maXJtZWQgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IFwiZmluYWxpemVkXCIgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChyZXBvcnQ/LmNvbmZpcm1hdGlvbnMgPj0gY29uZmlybWF0aW9ucyA/IFwiY29uZmlybWVkXCIgOiBcIm1pbmVkXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVwb3J0LmNvbmZpcm1hdGlvbnMgIT09IHJlY2VpcHQuY29uZmlybWF0aW9ucykgeyAgICBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdC5jb25maXJtYXRpb25zID0gcmVwb3J0LmNvbmZpcm1hdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlY2VpcHQuc3RhdHVzID09PSBcIm1pbmVkXCIgJiYgb3B0aW9ucz8ub25DaGVja3BvaW50KSB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5vbkNoZWNrcG9pbnQocmVjZWlwdClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCB7fTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzICE9PSByZWNlaXB0LnN0YXR1cykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZWNlaXB0LnRpbWVzdGFtcCA9IE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIVtcImNvbmZpcm1lZFwiLCBcImZpbmFsaXplZFwiXS5pbmNsdWRlcyhyZWNlaXB0LnN0YXR1cykgJiYgb3B0aW9ucz8ub25TdGF0dXNDaGFuZ2UpIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm9uU3RhdHVzQ2hhbmdlKHJlY2VpcHQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2gge307XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIEpzb25ScGNQcm92aWRlci5yZWNlaXB0c1toYXNoXSA9IHJlY2VpcHRcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gW1wicmVsYXllZFwiLCBcIm1pbmVkXCJdLmluY2x1ZGVzKHJlY2VpcHQuc3RhdHVzKVxyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGludGVydmFsLCB0aW1lb3V0LCBcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIH0pLnRoZW4oYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlY2VpcHQuc3RhdHVzID09PSBcInJlbW92ZWRcIiAmJiByZWNlaXB0LnR5cGUgIT09IFwiVW5zdGFrZVwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVFJBTlNBQ1RJT04gUkVNT1ZFRCBGUk9NIE1FTVBPT0wgLy9cclxuICAgICAgICAgICAgICAgICAgICAvLyAxLiBUcnkgdG8gcmVjb3ZlciBpbnB1dCB1dHhvcyBiZWxvbmdpbmcgdG8gbGVkZ2VyJ3MgYWRkcmVzc2VzOlxyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGlucHV0czogQXJyYXk8VXR4b01ldGFkYXRhPiA9IHJlY2VpcHQudHhbcmVjZWlwdC50eXBlXS5ib2R5LmlucHV0c1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzaWduYXR1cmVzOiBBcnJheTxLZXllZFNpZ25hdHVyZT4gPSByZWNlaXB0LnR4W3JlY2VpcHQudHlwZV0uc2lnbmF0dXJlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1dHhvczogQXJyYXk8VXR4bz4gPSBbXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXRzLmxlbmd0aCA9PT0gc2lnbmF0dXJlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0cy5mb3JFYWNoKChtZXRhZGF0YSwgaW5kZXgpID0+ICh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ubWV0YWRhdGEsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2lnbmVyOiBQdWJsaWNLZXkuZnJvbVByb3RvYnVmKHNpZ25hdHVyZXNbaW5kZXhdLnB1YmxpY19rZXkpLmhhc2goKS50b0JlY2gzMih0aGlzLm5ldHdvcmspLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sZWRnZXIuYWRkVXR4b3MoLi4udXR4b3MpXHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfTogd2FybmluZzogY2Fubm90IHJlY292ZXIgaW5wdXQgVVRYT1MgZnJvbSB0eCAke2hhc2h9OiAke2Vycn1gKVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyAyLiBUaHJvdyBNZW1wb29sRXJyb3JcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgTWVtcG9vbEVycm9yKHJlY2VpcHQsIGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IHRyYW5zYWN0aW9uIHJlbW92ZWQgZnJvbSBtZW1wb29sOiAke2hhc2h9YCk7XHJcbiAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVFJBTlNBQ1RJT04gRUlUSEVSIENPTkZJUk1FRCBPUiBGSU5BTElaRUQgLy9cclxuICAgICAgICAgICAgICAgICAgICAvLyAxLiBUcnkgdG8gbG9hZCB2YWx1ZSB0cmFuc2ZlciBvdXRwdXRzIGludG8gdGhlIGxlZGdlcidzIGxvY2FsIGNhY2hlOiBcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1dHhvczogQXJyYXk8VXR4bz4gPSBbXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoW1wiU3Rha2VcIiwgXCJVbnN0YWtlXCJdLmluY2x1ZGVzKHJlY2VpcHQudHlwZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCB2dG86IFZhbHVlVHJhbnNmZXJPdXRwdXQgPSAoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjZWlwdC50eXBlID09PSBcIlN0YWtlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyByZWNlaXB0LnR4W3JlY2VpcHQudHlwZV0uYm9keT8ub3V0cHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogcmVjZWlwdC50eFtyZWNlaXB0LnR5cGVdLmJvZHk/LndpdGhkcmF3YWxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodnRvKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXR4b3MucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dF9wb2ludGVyOiBgJHtyZWNlaXB0Lmhhc2h9OjBgLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lbG9jazogdnRvLnRpbWVfbG9jayxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXR4b19tYXR1cmU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2dG8udmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ25lcjogdnRvLnBraCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3V0cHV0czogQXJyYXk8VmFsdWVUcmFuc2Zlck91dHB1dD4gPSByZWNlaXB0LnR4W3JlY2VpcHQudHlwZV0uYm9keT8ub3V0cHV0cyB8fCBbXVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0cHV0cy5mb3JFYWNoKCh2dG8sIGluZGV4KSA9PiB1dHhvcy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXRfcG9pbnRlcjogYCR7cmVjZWlwdC5oYXNofToke2luZGV4fWAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGltZWxvY2s6IHZ0by50aW1lX2xvY2ssXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXR4b19tYXR1cmU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZ0by52YWx1ZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduZXI6IHZ0by5wa2gsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIm91dHB1dCB1dHhvcyBiZWZvcmUgPT5cIiwgdXR4b3MpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwib3V0cHV0IHV0eG9zIGFmdGVyICA9PlwiLCB0aGlzLmxlZGdlci5hZGRVdHhvcyguLi51dHhvcykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGVkZ2VyLmFkZFV0eG9zKC4uLnV0eG9zKVxyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IHdhcm5pbmc6IGNhbm5vdCByZWNvdmVyIG91dHB1dCBVVFhPcyBmcm9tICR7aGFzaH06ICR7ZXJyfWApXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIDIuIEFkZCBibG9ja01pbmVyIGFkZHJlc3MgdG8gdGhlIHRyYW5zYWN0aW9uIHJlY2VpcHQ6IFxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWNlaXB0Py5ibG9ja0hhc2ggJiYgaXNIZXhTdHJpbmcocmVjZWlwdC5ibG9ja0hhc2gpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGJsb2NrID0gYXdhaXQgdGhpcy5wcm92aWRlci5nZXRCbG9jayhyZWNlaXB0LmJsb2NrSGFzaCB8fCBcIlwiKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbaGFzaF0uYmxvY2tNaW5lciA9IFB1YmxpY0tleVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmZyb21Qcm90b2J1ZihibG9jay5ibG9ja19zaWcucHVibGljX2tleSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5oYXNoKClcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b0JlY2gzMih0aGlzLm5ldHdvcmspO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucz8ub25TdGF0dXNDaGFuZ2UpIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMub25TdGF0dXNDaGFuZ2UocmVjZWlwdClcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIHt9O1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIDMuIFJldHVybiB0cmFuc2FjdGlvbiByZWNlaXB0OlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbaGFzaF1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSlcclxuICAgICAgICBdKVxyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBfY2xlYW5TaWduYXR1cmVzKG5ld1RhcmdldDogU3BlY3MpOiBhbnkge1xyXG4gICAgICAgIHRoaXMuX3BheWxvYWQucmVzZXRUYXJnZXQobmV3VGFyZ2V0KVxyXG4gICAgICAgIHRoaXMuX3NpZ25hdHVyZXMgPSBbXVxyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBfZ2V0SW5mbGlnaHRCeXRlY29kZSgpOiBVaW50OEFycmF5IHwgdW5kZWZpbmVkIHtcclxuICAgICAgICBjb25zdCBvYmogPSB0aGlzLl90b1Byb3RvYnVmKClcclxuICAgICAgICBjb25zdCBlcnIgPSB0aGlzLl9wcm90b0J1Zi52ZXJpZnkob2JqKVxyXG4gICAgICAgIGlmICghZXJyKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB0aGlzLl9wcm90b0J1Zi5mcm9tT2JqZWN0KG9iailcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb3RvQnVmLmVuY29kZShtZXNzYWdlKS5maW5pc2goKVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIF9nZXRJbmZsaWdodFJlY2VpcHQoKTogVHJhbnNhY3Rpb25SZWNlaXB0IHwgdW5kZWZpbmVkIHtcclxuICAgICAgICBjb25zdCBoYXNoID0gdGhpcy5fcGF5bG9hZC5oYXNoXHJcbiAgICAgICAgaWYgKGhhc2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuIEpzb25ScGNQcm92aWRlci5yZWNlaXB0c1toYXNoXVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWRcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJvdGVjdGVkIF9nZXRJbmZsaWdodFRyYW5zbWlzc2lvbigpOiBUcmFuc21pc3Npb24ge1xyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIGJ5dGVjb2RlOiB0aGlzLl9nZXRJbmZsaWdodEJ5dGVjb2RlKCksXHJcbiAgICAgICAgICAgIGhhc2g6IHRoaXMuX3BheWxvYWQuaGFzaCxcclxuICAgICAgICAgICAgbWVzc2FnZTogdGhpcy5fdG9KU09OKHRydWUpLFxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgX3JlY292ZXJJbnB1dFV0eG9zKCk6IGFueSB7fVxyXG4gICAgcHJvdGVjdGVkIF9yZWNvdmVyT3V0cHV0VXR4b3MoKTogYW55IHt9XHJcblxyXG4gICAgcHJvdGVjdGVkIF91cHNlcnRUcmFuc2FjdGlvblJlY2VpcHQoaGFzaDogSGFzaCwgdGFyZ2V0OiBTcGVjcywgc3RhdHVzOiBUcmFuc2FjdGlvblN0YXR1cyk6IFRyYW5zYWN0aW9uUmVjZWlwdCB7XHJcbiAgICAgICAgSnNvblJwY1Byb3ZpZGVyLnJlY2VpcHRzW2hhc2hdID0ge1xyXG4gICAgICAgICAgICAuLi50aGlzLl9wYXlsb2FkLmludG9SZWNlaXB0KHRhcmdldCwgdGhpcy5uZXR3b3JrKSxcclxuICAgICAgICAgICAgaGFzaCxcclxuICAgICAgICAgICAgY2hhbmdlOiB0aGlzLl9wYXlsb2FkLmNoYW5nZSxcclxuICAgICAgICAgICAgZmVlczogdGhpcy5fcGF5bG9hZC5mZWVzLFxyXG4gICAgICAgICAgICBmcm9tOiB0aGlzLl9mcm9tLFxyXG4gICAgICAgICAgICBzdGF0dXMsXHJcbiAgICAgICAgICAgIHRpbWVzdGFtcDogTWF0aC5mbG9vcihEYXRlLm5vdygpIC8gMTAwMCksXHJcbiAgICAgICAgICAgIHR4OiB0aGlzLl90b0pTT04odHJ1ZSksXHJcbiAgICAgICAgICAgIHR5cGU6IHRoaXMudHlwZSxcclxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuX3BheWxvYWQudmFsdWUsXHJcbiAgICAgICAgICAgIHdlaWdodDogdGhpcy5fcGF5bG9hZC53ZWlnaHQsXHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBKc29uUnBjUHJvdmlkZXIucmVjZWlwdHNbaGFzaF1cclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgYWJzdHJhY3QgX3NpZ25UcmFuc2FjdGlvblBheWxvYWQoKTogSGFzaDtcclxuICAgIHByb3RlY3RlZCBhYnN0cmFjdCBfdG9KU09OKF9odW1hbml6ZTogYm9vbGVhbik6IGFueTtcclxuICAgIHByb3RlY3RlZCBhYnN0cmFjdCBfdG9Qcm90b2J1ZigpOiBhbnk7XHJcbn1cclxuXHJcblxyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVHJhbnNtaXR0ZXJNdWx0aVNpZzxTcGVjcywgUGF5bG9hZCBleHRlbmRzIElUcmFuc2FjdGlvblBheWxvYWRNdWx0aVNpZzxTcGVjcz4+IFxyXG4gICAgZXh0ZW5kcyBUcmFuc21pdHRlcjxTcGVjcywgUGF5bG9hZD4gXHJcbntcclxuICAgIGNvbnN0cnVjdG9yIChwcm90b1R5cGVOYW1lOiBzdHJpbmcsIHBheWxvYWQ6IFBheWxvYWQsIGxlZGdlcjogSUxlZGdlciwgY2hhbmdlUGtoPzogUHVibGljS2V5SGFzaFN0cmluZykge1xyXG4gICAgICAgIHN1cGVyKHByb3RvVHlwZU5hbWUsIHBheWxvYWQsIGxlZGdlciwgY2hhbmdlUGtoKVxyXG4gICAgICAgIHRoaXMuX3BheWxvYWQgPSBwYXlsb2FkO1xyXG4gICAgfVxyXG5cclxuICAgIC8vLyBSZWNvdmVyIGZvcm1lcmx5IGNvbnN1bWVkIFVUWE9zIGJ5IGEgZmFpbGluZyB0cmFuc2FjdGlvbiBiYWNrIHRvIHRoZWlyIHJlc3BlY3RpdmUgc2lnbmVyJ3MgVVRYTyBwb29sXHJcbiAgICBwcm90ZWN0ZWQgX3JlY292ZXJJbnB1dFV0eG9zKCk6IGFueSB7XHJcbiAgICAgICAgaWYgKHRoaXMuX3BheWxvYWQuaW5wdXRzKSB7ICAgIFxyXG4gICAgICAgICAgICB0aGlzLmxlZGdlci5hZGRVdHhvcyguLi50aGlzLl9wYXlsb2FkLmlucHV0cylcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8vIFJlY292ZXIgc2VsZi10YXJnZXRlZCBvdXRwdXRzIGFzIGV4cGVuZGFibGUgdXR4b3Mgb24gdGhlaXIgcmVzcGVjdGl2ZSBzaWduZXIncyBtZW1vaXplZCBjYWNoZVxyXG4gICAgcHJvdGVjdGVkIF9yZWNvdmVyT3V0cHV0VXR4b3MoKTogYW55IHtcclxuICAgICAgICBpZiAodGhpcy5fcGF5bG9hZC5oYXNoICYmIHRoaXMuX3BheWxvYWQub3V0cHV0cykge1xyXG4gICAgICAgICAgICBjb25zdCB1dHhvczogQXJyYXk8VXR4bz4gPSBbXVxyXG4gICAgICAgICAgICB0aGlzLl9wYXlsb2FkLm91dHB1dHMuZm9yRWFjaCgodnRvLCBpbmRleCkgPT4geyAgICBcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxlZGdlci5nZXRTaWduZXIodnRvLnBraCkpIHV0eG9zLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIHNpZ25lcjogdnRvLnBraCxcclxuICAgICAgICAgICAgICAgICAgICBvdXRwdXRfcG9pbnRlcjogYCR7dGhpcy5fcGF5bG9hZC5oYXNofToke2luZGV4fWAsXHJcbiAgICAgICAgICAgICAgICAgICAgdGltZWxvY2s6IHZ0by50aW1lX2xvY2ssXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHZ0by52YWx1ZSxcclxuICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIHRoaXMubGVkZ2VyLmFkZFV0eG9zKC4uLnV0eG9zKVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgX3NpZ25UcmFuc2FjdGlvblBheWxvYWQoKTogSGFzaCB7XHJcbiAgICAgICAgY29uc3QgaGFzaCA9IHRoaXMuX3BheWxvYWQuaGFzaFxyXG4gICAgICAgIGlmICghaGFzaCkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcihcclxuICAgICAgICAgICAgICAgIGAke3RoaXMuY29uc3RydWN0b3IubmFtZX06IGludGVybmFsIGVycm9yOiB1bmFibGUgdG8gaGFzaGlmeSBwYXlsb2FkOiAke3RoaXMuX3BheWxvYWQudG9KU09OKHRydWUsIHRoaXMubmV0d29yayl9fS5gXHJcbiAgICAgICAgICAgIClcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9wYXlsb2FkLmlucHV0cy5mb3JFYWNoKHV0eG8gPT4geyBcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNpZ25lciA9IHRoaXMubGVkZ2VyLmdldFNpZ25lcih1dHhvLnNpZ25lcilcclxuICAgICAgICAgICAgICAgIGlmICghc2lnbmVyKSB0aHJvdyBFcnJvcihcclxuICAgICAgICAgICAgICAgICAgICBgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9OiBpbnRlcm5hbCBlcnJvcjogY2Fubm90IGZpbmQgU2lnbmVyICR7dXR4by5zaWduZXJ9IGluICR7dGhpcy5sZWRnZXIuY29uc3RydWN0b3IubmFtZX0gJHt0aGlzLmxlZGdlci5wa2h9LmAgICAgXHJcbiAgICAgICAgICAgICAgICApOyBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgLi4uc2lnbmVyICR7c2lnbmVyLnBraH0gc2lnbmluZyBoYXNoICR7aGFzaH0uLi5gKVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3NpZ25hdHVyZXMucHVzaChzaWduZXIuc2lnbkhhc2goaGFzaCkpIFxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICByZXR1cm4gaGFzaFxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgX3RvSlNPTihodW1hbml6ZTogYm9vbGVhbik6IGFueSB7XHJcbiAgICAgICAgcmV0dXJuIHsgXHJcbiAgICAgICAgICAgIFt0aGlzLnR5cGVdOiB7IFxyXG4gICAgICAgICAgICAgICAgYm9keTogdGhpcy5fcGF5bG9hZC50b0pTT04oaHVtYW5pemUsIHRoaXMubmV0d29yayksXHJcbiAgICAgICAgICAgICAgICBzaWduYXR1cmVzOiB0aGlzLl9zaWduYXR1cmVzLFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcm90ZWN0ZWQgX3RvUHJvdG9idWYoKTogYW55IHtcclxuICAgICAgICBjb25zdCBib2R5ID0gdGhpcy5fcGF5bG9hZC50b1Byb3RvYnVmKClcclxuICAgICAgICBpZiAoYm9keSAmJiB0aGlzLl9zaWduYXR1cmVzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICBib2R5LFxyXG4gICAgICAgICAgICAgICAgc2lnbmF0dXJlczogdGhpcy5fc2lnbmF0dXJlcyxcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxufVxyXG4iXX0=
|