drama-pm-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,153 @@
1
+ import type { BN, Program } from "@coral-xyz/anchor";
2
+ import anchor from "@coral-xyz/anchor";
3
+ import { Connection, PublicKey, Transaction, TransactionInstruction } from "@solana/web3.js";
4
+ import { IDL } from "./idl.js";
5
+ import { DramaPm } from "./types.js";
6
+ export * from "./utils.js";
7
+ export { DramaPm, IDL };
8
+ export type Outcome = "Yes" | "No";
9
+ export interface CreateMarketParams {
10
+ admin: PublicKey;
11
+ marketId: number | BN;
12
+ yesPrice: number | BN;
13
+ noPrice: number | BN;
14
+ endTime: number | BN;
15
+ bettingToken: PublicKey;
16
+ }
17
+ export interface PlaceBetParams {
18
+ user: PublicKey;
19
+ admin: PublicKey;
20
+ marketId: number | BN;
21
+ amount: number | BN;
22
+ outcome: Outcome;
23
+ bettingToken: PublicKey;
24
+ createAta?: boolean;
25
+ }
26
+ export interface ClaimRewardsParams {
27
+ user: PublicKey;
28
+ admin: PublicKey;
29
+ marketId: number | BN;
30
+ bettingToken: PublicKey;
31
+ winningOutcome: Outcome;
32
+ }
33
+ export interface RefundParams {
34
+ user: PublicKey;
35
+ admin: PublicKey;
36
+ marketId: number | BN;
37
+ bettingToken: PublicKey;
38
+ outcome: Outcome;
39
+ }
40
+ export declare class DramaPmClient {
41
+ program: Program<DramaPm>;
42
+ provider: anchor.AnchorProvider;
43
+ connection: Connection;
44
+ constructor(connection: Connection, wallet?: anchor.Wallet);
45
+ /**
46
+ * Check if an associated token account exists
47
+ */
48
+ ataExists(ata: PublicKey): Promise<boolean>;
49
+ /**
50
+ * Create an instruction to initialize an associated token account
51
+ */
52
+ createAtaInstruction(payer: PublicKey, owner: PublicKey, mint: PublicKey): TransactionInstruction;
53
+ /**
54
+ * Create a new prediction market instruction
55
+ */
56
+ createMarket(params: CreateMarketParams): Promise<TransactionInstruction>;
57
+ /**
58
+ * Build a complete transaction to create a market
59
+ */
60
+ buildCreateMarketTx(params: CreateMarketParams): Promise<Transaction>;
61
+ /**
62
+ * Place a bet instruction (without ATA creation)
63
+ */
64
+ placeBet(params: PlaceBetParams): Promise<TransactionInstruction>;
65
+ /**
66
+ * Build a complete transaction to place a bet (with optional ATA creation)
67
+ */
68
+ buildPlaceBetTx(params: PlaceBetParams): Promise<Transaction>;
69
+ /**
70
+ * Claim rewards after market resolution
71
+ */
72
+ claimRewards(params: ClaimRewardsParams): Promise<TransactionInstruction>;
73
+ /**
74
+ * Build a complete transaction to claim rewards
75
+ */
76
+ buildClaimRewardsTx(params: ClaimRewardsParams): Promise<Transaction>;
77
+ /**
78
+ * Refund bets if market is refunded
79
+ */
80
+ refund(params: RefundParams): Promise<TransactionInstruction>;
81
+ /**
82
+ * Build a complete transaction to refund
83
+ */
84
+ buildRefundTx(params: RefundParams): Promise<Transaction>;
85
+ /**
86
+ * Resolve a market (Admin only)
87
+ */
88
+ resolveMarket(admin: PublicKey, marketId: number | BN, winningOutcome: "Yes" | "No" | null): Promise<TransactionInstruction>;
89
+ /**
90
+ * Build a complete transaction to resolve a market
91
+ */
92
+ buildResolveMarketTx(admin: PublicKey, marketId: number | BN, winningOutcome: "Yes" | "No" | null): Promise<Transaction>;
93
+ /**
94
+ * Close a market (Admin only)
95
+ */
96
+ closeMarket(admin: PublicKey, marketId: number | BN): Promise<TransactionInstruction>;
97
+ /**
98
+ * Build a complete transaction to close a market
99
+ */
100
+ buildCloseMarketTx(admin: PublicKey, marketId: number | BN): Promise<Transaction>;
101
+ /**
102
+ * Fetch market account data
103
+ */
104
+ getMarketAccount(admin: PublicKey, marketId: number | BN): Promise<{
105
+ admin: anchor.web3.PublicKey;
106
+ marketId: BN;
107
+ yesMint: anchor.web3.PublicKey;
108
+ noMint: anchor.web3.PublicKey;
109
+ bettingToken: anchor.web3.PublicKey;
110
+ vault: anchor.web3.PublicKey;
111
+ yesPrice: BN;
112
+ noPrice: BN;
113
+ createTime: BN;
114
+ endTime: BN;
115
+ status: ({
116
+ closed?: undefined;
117
+ resolved?: undefined;
118
+ refunded?: undefined;
119
+ } & {
120
+ active: Record<string, never>;
121
+ }) | ({
122
+ active?: undefined;
123
+ resolved?: undefined;
124
+ refunded?: undefined;
125
+ } & {
126
+ closed: Record<string, never>;
127
+ }) | ({
128
+ active?: undefined;
129
+ closed?: undefined;
130
+ refunded?: undefined;
131
+ } & {
132
+ resolved: Record<string, never>;
133
+ }) | ({
134
+ active?: undefined;
135
+ closed?: undefined;
136
+ resolved?: undefined;
137
+ } & {
138
+ refunded: Record<string, never>;
139
+ });
140
+ winningOutcome: (({
141
+ yes?: undefined;
142
+ } & {
143
+ no: Record<string, never>;
144
+ }) | ({
145
+ no?: undefined;
146
+ } & {
147
+ yes: Record<string, never>;
148
+ })) | null;
149
+ totalYesSupply: BN;
150
+ totalNoSupply: BN;
151
+ bump: number;
152
+ }>;
153
+ }
package/dist/index.js ADDED
@@ -0,0 +1,232 @@
1
+ import anchor from "@coral-xyz/anchor";
2
+ import { createAssociatedTokenAccountInstruction, getAccount, getAssociatedTokenAddressSync, TOKEN_PROGRAM_ID, } from "@solana/spl-token";
3
+ import { Keypair, Transaction } from "@solana/web3.js";
4
+ import { IDL } from "./idl.js";
5
+ import { getMarketPda, getMarketPdas } from "./utils.js";
6
+ const { BN: AnchorBN, Program: AnchorProgram } = anchor;
7
+ export * from "./utils.js";
8
+ export { IDL };
9
+ export class DramaPmClient {
10
+ constructor(connection, wallet) {
11
+ this.connection = connection;
12
+ this.provider = new anchor.AnchorProvider(connection, wallet || new anchor.Wallet(Keypair.generate()), { commitment: "confirmed" });
13
+ this.program = new AnchorProgram(IDL, this.provider);
14
+ }
15
+ /**
16
+ * Check if an associated token account exists
17
+ */
18
+ async ataExists(ata) {
19
+ try {
20
+ await getAccount(this.connection, ata);
21
+ return true;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ /**
28
+ * Create an instruction to initialize an associated token account
29
+ */
30
+ createAtaInstruction(payer, owner, mint) {
31
+ const ata = getAssociatedTokenAddressSync(mint, owner);
32
+ return createAssociatedTokenAccountInstruction(payer, ata, owner, mint, TOKEN_PROGRAM_ID);
33
+ }
34
+ /**
35
+ * Create a new prediction market instruction
36
+ */
37
+ async createMarket(params) {
38
+ const { admin, marketId, yesPrice, noPrice, endTime, bettingToken } = params;
39
+ const marketIdBn = new AnchorBN(marketId);
40
+ const yesPriceBn = new AnchorBN(yesPrice);
41
+ const noPriceBn = new AnchorBN(noPrice);
42
+ const endTimeBn = new AnchorBN(endTime);
43
+ const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
44
+ return await this.program.methods
45
+ .createMarket({
46
+ marketId: marketIdBn,
47
+ yesPrice: yesPriceBn,
48
+ noPrice: noPriceBn,
49
+ endTime: endTimeBn,
50
+ })
51
+ .accountsPartial({
52
+ market: pdas.market,
53
+ yesMint: pdas.yesMint,
54
+ noMint: pdas.noMint,
55
+ bettingToken: bettingToken,
56
+ vault: pdas.vault,
57
+ admin: admin,
58
+ systemProgram: anchor.web3.SystemProgram.programId,
59
+ })
60
+ .instruction();
61
+ }
62
+ /**
63
+ * Build a complete transaction to create a market
64
+ */
65
+ async buildCreateMarketTx(params) {
66
+ const ix = await this.createMarket(params);
67
+ return new Transaction().add(ix);
68
+ }
69
+ /**
70
+ * Place a bet instruction (without ATA creation)
71
+ */
72
+ async placeBet(params) {
73
+ const { user, admin, marketId, amount, outcome, bettingToken } = params;
74
+ const marketIdBn = new AnchorBN(marketId);
75
+ const amountBn = new AnchorBN(amount);
76
+ const outcomeEnum = outcome === "Yes" ? { yes: {} } : { no: {} };
77
+ const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
78
+ const userBettingToken = getAssociatedTokenAddressSync(bettingToken, user);
79
+ // Determine which outcome token the user will receive
80
+ const targetMint = outcome === "Yes" ? pdas.yesMint : pdas.noMint;
81
+ const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
82
+ return await this.program.methods
83
+ .placeBet({
84
+ buyOutcome: outcomeEnum,
85
+ amount: amountBn,
86
+ })
87
+ .accountsPartial({
88
+ market: pdas.market,
89
+ yesMint: pdas.yesMint,
90
+ noMint: pdas.noMint,
91
+ vault: pdas.vault,
92
+ userOutcomeToken,
93
+ userBettingToken,
94
+ user,
95
+ })
96
+ .instruction();
97
+ }
98
+ /**
99
+ * Build a complete transaction to place a bet (with optional ATA creation)
100
+ */
101
+ async buildPlaceBetTx(params) {
102
+ const { user, admin, marketId, outcome, createAta = true } = params;
103
+ const tx = new Transaction();
104
+ const marketIdBn = new AnchorBN(marketId);
105
+ const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
106
+ const targetMint = outcome === "Yes" ? pdas.yesMint : pdas.noMint;
107
+ const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
108
+ // Check if ATA exists and create if needed
109
+ if (createAta) {
110
+ const exists = await this.ataExists(userOutcomeToken);
111
+ if (!exists) {
112
+ const createAtaIx = this.createAtaInstruction(user, user, targetMint);
113
+ tx.add(createAtaIx);
114
+ }
115
+ }
116
+ const placeBetIx = await this.placeBet(params);
117
+ tx.add(placeBetIx);
118
+ return tx;
119
+ }
120
+ /**
121
+ * Claim rewards after market resolution
122
+ */
123
+ async claimRewards(params) {
124
+ const { user, admin, marketId, bettingToken, winningOutcome } = params;
125
+ const marketIdBn = new AnchorBN(marketId);
126
+ const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
127
+ const userBettingToken = getAssociatedTokenAddressSync(bettingToken, user);
128
+ const targetMint = winningOutcome === "Yes" ? pdas.yesMint : pdas.noMint;
129
+ const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
130
+ return await this.program.methods
131
+ .claimRewards()
132
+ .accountsPartial({
133
+ market: pdas.market,
134
+ userOutcomeToken,
135
+ userBettingToken,
136
+ user,
137
+ })
138
+ .instruction();
139
+ }
140
+ /**
141
+ * Build a complete transaction to claim rewards
142
+ */
143
+ async buildClaimRewardsTx(params) {
144
+ const ix = await this.claimRewards(params);
145
+ return new Transaction().add(ix);
146
+ }
147
+ /**
148
+ * Refund bets if market is refunded
149
+ */
150
+ async refund(params) {
151
+ const { user, admin, marketId, bettingToken, outcome } = params;
152
+ const marketIdBn = new AnchorBN(marketId);
153
+ const outcomeEnum = outcome === "Yes" ? { yes: {} } : { no: {} };
154
+ const pdas = getMarketPdas(this.program.programId, admin, marketIdBn);
155
+ const userBettingToken = getAssociatedTokenAddressSync(bettingToken, user);
156
+ const targetMint = outcome === "Yes" ? pdas.yesMint : pdas.noMint;
157
+ const userOutcomeToken = getAssociatedTokenAddressSync(targetMint, user);
158
+ return await this.program.methods
159
+ .refund(outcomeEnum)
160
+ .accountsPartial({
161
+ market: pdas.market,
162
+ userOutcomeToken,
163
+ userBettingToken,
164
+ user,
165
+ })
166
+ .instruction();
167
+ }
168
+ /**
169
+ * Build a complete transaction to refund
170
+ */
171
+ async buildRefundTx(params) {
172
+ const ix = await this.refund(params);
173
+ return new Transaction().add(ix);
174
+ }
175
+ /**
176
+ * Resolve a market (Admin only)
177
+ */
178
+ async resolveMarket(admin, marketId, winningOutcome) {
179
+ const marketIdBn = new AnchorBN(marketId);
180
+ const marketPda = getMarketPda(this.program.programId, admin, marketIdBn);
181
+ let outcomeEnum = null;
182
+ if (winningOutcome === "Yes") {
183
+ outcomeEnum = { yes: {} };
184
+ }
185
+ else if (winningOutcome === "No") {
186
+ outcomeEnum = { no: {} };
187
+ }
188
+ return await this.program.methods
189
+ .resolveMarket(outcomeEnum)
190
+ .accountsPartial({
191
+ market: marketPda,
192
+ admin,
193
+ })
194
+ .instruction();
195
+ }
196
+ /**
197
+ * Build a complete transaction to resolve a market
198
+ */
199
+ async buildResolveMarketTx(admin, marketId, winningOutcome) {
200
+ const ix = await this.resolveMarket(admin, marketId, winningOutcome);
201
+ return new Transaction().add(ix);
202
+ }
203
+ /**
204
+ * Close a market (Admin only)
205
+ */
206
+ async closeMarket(admin, marketId) {
207
+ const marketIdBn = new AnchorBN(marketId);
208
+ const marketPda = getMarketPda(this.program.programId, admin, marketIdBn);
209
+ return await this.program.methods
210
+ .closeMarket()
211
+ .accountsPartial({
212
+ market: marketPda,
213
+ })
214
+ .instruction();
215
+ }
216
+ /**
217
+ * Build a complete transaction to close a market
218
+ */
219
+ async buildCloseMarketTx(admin, marketId) {
220
+ const ix = await this.closeMarket(admin, marketId);
221
+ return new Transaction().add(ix);
222
+ }
223
+ /**
224
+ * Fetch market account data
225
+ */
226
+ async getMarketAccount(admin, marketId) {
227
+ const marketIdBn = new AnchorBN(marketId);
228
+ const marketPda = getMarketPda(this.program.programId, admin, marketIdBn);
229
+ return await this.program.account.market.fetch(marketPda);
230
+ }
231
+ }
232
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxNQUFNLE1BQU0sbUJBQW1CLENBQUM7QUFDdkMsT0FBTyxFQUNILHVDQUF1QyxFQUN2QyxVQUFVLEVBQ1YsNkJBQTZCLEVBQzdCLGdCQUFnQixHQUNuQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFFSCxPQUFPLEVBRVAsV0FBVyxFQUVkLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUUvQixPQUFPLEVBQ0gsWUFBWSxFQUNaLGFBQWEsRUFDaEIsTUFBTSxZQUFZLENBQUM7QUFDcEIsTUFBTSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxHQUFHLE1BQU0sQ0FBQztBQUV4RCxjQUFjLFlBQVksQ0FBQztBQUMzQixPQUFPLEVBQVcsR0FBRyxFQUFFLENBQUM7QUF1Q3hCLE1BQU0sT0FBTyxhQUFhO0lBS3hCLFlBQVksVUFBc0IsRUFBRSxNQUFzQjtRQUN4RCxJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM3QixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksTUFBTSxDQUFDLGNBQWMsQ0FDdkMsVUFBVSxFQUNWLE1BQU0sSUFBSSxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQy9DLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxDQUM1QixDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLGFBQWEsQ0FBQyxHQUFVLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBZ0MsQ0FBQztJQUM3RixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQWM7UUFDNUIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxVQUFVLENBQUMsSUFB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QyxFQUFFLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsS0FBZ0IsRUFBRSxRQUFxQjtRQUM1RCxNQUFNLFVBQVUsR0FBRyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzFFLE9BQU8sTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQk4sIElkbCwgUHJvZ3JhbSB9IGZyb20gXCJAY29yYWwteHl6L2FuY2hvclwiO1xuaW1wb3J0IGFuY2hvciBmcm9tIFwiQGNvcmFsLXh5ei9hbmNob3JcIjtcbmltcG9ydCB7XG4gICAgY3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudEluc3RydWN0aW9uLFxuICAgIGdldEFjY291bnQsXG4gICAgZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmMsXG4gICAgVE9LRU5fUFJPR1JBTV9JRCxcbn0gZnJvbSBcIkBzb2xhbmEvc3BsLXRva2VuXCI7XG5pbXBvcnQge1xuICAgIENvbm5lY3Rpb24sXG4gICAgS2V5cGFpcixcbiAgICBQdWJsaWNLZXksXG4gICAgVHJhbnNhY3Rpb24sXG4gICAgVHJhbnNhY3Rpb25JbnN0cnVjdGlvblxufSBmcm9tIFwiQHNvbGFuYS93ZWIzLmpzXCI7XG5pbXBvcnQgeyBJREwgfSBmcm9tIFwiLi9pZGwuanNcIjtcbmltcG9ydCB7IERyYW1hUG0gfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuaW1wb3J0IHtcbiAgICBnZXRNYXJrZXRQZGEsXG4gICAgZ2V0TWFya2V0UGRhc1xufSBmcm9tIFwiLi91dGlscy5qc1wiO1xuY29uc3QgeyBCTjogQW5jaG9yQk4sIFByb2dyYW06IEFuY2hvclByb2dyYW0gfSA9IGFuY2hvcjtcblxuZXhwb3J0ICogZnJvbSBcIi4vdXRpbHMuanNcIjtcbmV4cG9ydCB7IERyYW1hUG0sIElETCB9O1xuXG5leHBvcnQgdHlwZSBPdXRjb21lID0gXCJZZXNcIiB8IFwiTm9cIjtcblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVNYXJrZXRQYXJhbXMge1xuICBhZG1pbjogUHVibGljS2V5O1xuICBtYXJrZXRJZDogbnVtYmVyIHwgQk47XG4gIHllc1ByaWNlOiBudW1iZXIgfCBCTjtcbiAgbm9QcmljZTogbnVtYmVyIHwgQk47XG4gIGVuZFRpbWU6IG51bWJlciB8IEJOO1xuICBiZXR0aW5nVG9rZW46IFB1YmxpY0tleTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbGFjZUJldFBhcmFtcyB7XG4gIHVzZXI6IFB1YmxpY0tleTtcbiAgYWRtaW46IFB1YmxpY0tleTtcbiAgbWFya2V0SWQ6IG51bWJlciB8IEJOO1xuICBhbW91bnQ6IG51bWJlciB8IEJOO1xuICBvdXRjb21lOiBPdXRjb21lO1xuICBiZXR0aW5nVG9rZW46IFB1YmxpY0tleTtcbiAgY3JlYXRlQXRhPzogYm9vbGVhbjsgLy8gV2hldGhlciB0byBjcmVhdGUgQVRBIGluc3RydWN0aW9uIGF1dG9tYXRpY2FsbHlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDbGFpbVJld2FyZHNQYXJhbXMge1xuICB1c2VyOiBQdWJsaWNLZXk7XG4gIGFkbWluOiBQdWJsaWNLZXk7XG4gIG1hcmtldElkOiBudW1iZXIgfCBCTjtcbiAgYmV0dGluZ1Rva2VuOiBQdWJsaWNLZXk7XG4gIHdpbm5pbmdPdXRjb21lOiBPdXRjb21lO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlZnVuZFBhcmFtcyB7XG4gIHVzZXI6IFB1YmxpY0tleTtcbiAgYWRtaW46IFB1YmxpY0tleTtcbiAgbWFya2V0SWQ6IG51bWJlciB8IEJOO1xuICBiZXR0aW5nVG9rZW46IFB1YmxpY0tleTtcbiAgb3V0Y29tZTogT3V0Y29tZTtcbn1cblxuZXhwb3J0IGNsYXNzIERyYW1hUG1DbGllbnQge1xuICBwcm9ncmFtOiBQcm9ncmFtPERyYW1hUG0+O1xuICBwcm92aWRlcjogYW5jaG9yLkFuY2hvclByb3ZpZGVyO1xuICBjb25uZWN0aW9uOiBDb25uZWN0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKGNvbm5lY3Rpb246IENvbm5lY3Rpb24sIHdhbGxldD86IGFuY2hvci5XYWxsZXQpIHtcbiAgICB0aGlzLmNvbm5lY3Rpb24gPSBjb25uZWN0aW9uO1xuICAgIHRoaXMucHJvdmlkZXIgPSBuZXcgYW5jaG9yLkFuY2hvclByb3ZpZGVyKFxuICAgICAgY29ubmVjdGlvbixcbiAgICAgIHdhbGxldCB8fCBuZXcgYW5jaG9yLldhbGxldChLZXlwYWlyLmdlbmVyYXRlKCkpLFxuICAgICAgeyBjb21taXRtZW50OiBcImNvbmZpcm1lZFwiIH1cbiAgICApO1xuICAgIHRoaXMucHJvZ3JhbSA9IG5ldyBBbmNob3JQcm9ncmFtKElETCBhcyBJZGwsIHRoaXMucHJvdmlkZXIpIGFzIHVua25vd24gYXMgUHJvZ3JhbTxEcmFtYVBtPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayBpZiBhbiBhc3NvY2lhdGVkIHRva2VuIGFjY291bnQgZXhpc3RzXG4gICAqL1xuICBhc3luYyBhdGFFeGlzdHMoYXRhOiBQdWJsaWNLZXkpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgZ2V0QWNjb3VudCh0aGlzLmNvbm5lY3Rpb24sIGF0YSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGluc3RydWN0aW9uIHRvIGluaXRpYWxpemUgYW4gYXNzb2NpYXRlZCB0b2tlbiBhY2NvdW50XG4gICAqL1xuICBjcmVhdGVBdGFJbnN0cnVjdGlvbihcbiAgICBwYXllcjogUHVibGljS2V5LFxuICAgIG93bmVyOiBQdWJsaWNLZXksXG4gICAgbWludDogUHVibGljS2V5XG4gICk6IFRyYW5zYWN0aW9uSW5zdHJ1Y3Rpb24ge1xuICAgIGNvbnN0IGF0YSA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKG1pbnQsIG93bmVyKTtcbiAgICByZXR1cm4gY3JlYXRlQXNzb2NpYXRlZFRva2VuQWNjb3VudEluc3RydWN0aW9uKFxuICAgICAgcGF5ZXIsXG4gICAgICBhdGEsXG4gICAgICBvd25lcixcbiAgICAgIG1pbnQsXG4gICAgICBUT0tFTl9QUk9HUkFNX0lEXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBuZXcgcHJlZGljdGlvbiBtYXJrZXQgaW5zdHJ1Y3Rpb25cbiAgICovXG4gIGFzeW5jIGNyZWF0ZU1hcmtldChwYXJhbXM6IENyZWF0ZU1hcmtldFBhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IHsgYWRtaW4sIG1hcmtldElkLCB5ZXNQcmljZSwgbm9QcmljZSwgZW5kVGltZSwgYmV0dGluZ1Rva2VuIH0gPSBwYXJhbXM7XG4gICAgXG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgeWVzUHJpY2VCbiA9IG5ldyBBbmNob3JCTih5ZXNQcmljZSk7XG4gICAgY29uc3Qgbm9QcmljZUJuID0gbmV3IEFuY2hvckJOKG5vUHJpY2UpO1xuICAgIGNvbnN0IGVuZFRpbWVCbiA9IG5ldyBBbmNob3JCTihlbmRUaW1lKTtcblxuICAgIGNvbnN0IHBkYXMgPSBnZXRNYXJrZXRQZGFzKHRoaXMucHJvZ3JhbS5wcm9ncmFtSWQsIGFkbWluLCBtYXJrZXRJZEJuKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLmNyZWF0ZU1hcmtldCh7XG4gICAgICAgICAgbWFya2V0SWQ6IG1hcmtldElkQm4sXG4gICAgICAgICAgeWVzUHJpY2U6IHllc1ByaWNlQm4sXG4gICAgICAgICAgbm9QcmljZTogbm9QcmljZUJuLFxuICAgICAgICAgIGVuZFRpbWU6IGVuZFRpbWVCbixcbiAgICAgICAgfSlcbiAgICAgICAgLmFjY291bnRzUGFydGlhbCh7XG4gICAgICAgICAgbWFya2V0OiBwZGFzLm1hcmtldCxcbiAgICAgICAgICB5ZXNNaW50OiBwZGFzLnllc01pbnQsXG4gICAgICAgICAgbm9NaW50OiBwZGFzLm5vTWludCxcbiAgICAgICAgICBiZXR0aW5nVG9rZW46IGJldHRpbmdUb2tlbixcbiAgICAgICAgICB2YXVsdDogcGRhcy52YXVsdCxcbiAgICAgICAgICBhZG1pbjogYWRtaW4sXG4gICAgICAgICAgc3lzdGVtUHJvZ3JhbTogYW5jaG9yLndlYjMuU3lzdGVtUHJvZ3JhbS5wcm9ncmFtSWQsXG4gICAgICAgIH0pXG4gICAgICAgIC5pbnN0cnVjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgY29tcGxldGUgdHJhbnNhY3Rpb24gdG8gY3JlYXRlIGEgbWFya2V0XG4gICAqL1xuICBhc3luYyBidWlsZENyZWF0ZU1hcmtldFR4KHBhcmFtczogQ3JlYXRlTWFya2V0UGFyYW1zKTogUHJvbWlzZTxUcmFuc2FjdGlvbj4ge1xuICAgIGNvbnN0IGl4ID0gYXdhaXQgdGhpcy5jcmVhdGVNYXJrZXQocGFyYW1zKTtcbiAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uKCkuYWRkKGl4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQbGFjZSBhIGJldCBpbnN0cnVjdGlvbiAod2l0aG91dCBBVEEgY3JlYXRpb24pXG4gICAqL1xuICBhc3luYyBwbGFjZUJldChwYXJhbXM6IFBsYWNlQmV0UGFyYW1zKTogUHJvbWlzZTxUcmFuc2FjdGlvbkluc3RydWN0aW9uPiB7XG4gICAgY29uc3QgeyB1c2VyLCBhZG1pbiwgbWFya2V0SWQsIGFtb3VudCwgb3V0Y29tZSwgYmV0dGluZ1Rva2VuIH0gPSBwYXJhbXM7XG4gICAgXG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgYW1vdW50Qm4gPSBuZXcgQW5jaG9yQk4oYW1vdW50KTtcbiAgICBjb25zdCBvdXRjb21lRW51bSA9IG91dGNvbWUgPT09IFwiWWVzXCIgPyB7IHllczoge30gfSA6IHsgbm86IHt9IH07XG5cblxuICAgIGNvbnN0IHBkYXMgPSBnZXRNYXJrZXRQZGFzKHRoaXMucHJvZ3JhbS5wcm9ncmFtSWQsIGFkbWluLCBtYXJrZXRJZEJuKTtcbiAgICBjb25zdCB1c2VyQmV0dGluZ1Rva2VuID0gZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmMoYmV0dGluZ1Rva2VuLCB1c2VyKTtcbiAgICBcbiAgICAvLyBEZXRlcm1pbmUgd2hpY2ggb3V0Y29tZSB0b2tlbiB0aGUgdXNlciB3aWxsIHJlY2VpdmVcbiAgICBjb25zdCB0YXJnZXRNaW50ID0gb3V0Y29tZSA9PT0gXCJZZXNcIiA/IHBkYXMueWVzTWludCA6IHBkYXMubm9NaW50O1xuICAgIGNvbnN0IHVzZXJPdXRjb21lVG9rZW4gPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh0YXJnZXRNaW50LCB1c2VyKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLnBsYWNlQmV0KHtcbiAgICAgICAgYnV5T3V0Y29tZTogb3V0Y29tZUVudW0sXG4gICAgICAgIGFtb3VudDogYW1vdW50Qm4sXG4gICAgICB9KVxuICAgICAgLmFjY291bnRzUGFydGlhbCh7XG4gICAgICAgIG1hcmtldDogcGRhcy5tYXJrZXQsXG4gICAgICAgIHllc01pbnQ6IHBkYXMueWVzTWludCxcbiAgICAgICAgbm9NaW50OiBwZGFzLm5vTWludCxcbiAgICAgICAgdmF1bHQ6IHBkYXMudmF1bHQsXG4gICAgICAgIHVzZXJPdXRjb21lVG9rZW4sXG4gICAgICAgIHVzZXJCZXR0aW5nVG9rZW4sXG4gICAgICAgIHVzZXIsXG4gICAgICB9KVxuICAgICAgLmluc3RydWN0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb21wbGV0ZSB0cmFuc2FjdGlvbiB0byBwbGFjZSBhIGJldCAod2l0aCBvcHRpb25hbCBBVEEgY3JlYXRpb24pXG4gICAqL1xuICBhc3luYyBidWlsZFBsYWNlQmV0VHgocGFyYW1zOiBQbGFjZUJldFBhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCB7IHVzZXIsIGFkbWluLCBtYXJrZXRJZCwgb3V0Y29tZSwgY3JlYXRlQXRhID0gdHJ1ZSB9ID0gcGFyYW1zO1xuICAgIFxuICAgIGNvbnN0IHR4ID0gbmV3IFRyYW5zYWN0aW9uKCk7XG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgcGRhcyA9IGdldE1hcmtldFBkYXModGhpcy5wcm9ncmFtLnByb2dyYW1JZCwgYWRtaW4sIG1hcmtldElkQm4pO1xuICAgIFxuICAgIGNvbnN0IHRhcmdldE1pbnQgPSBvdXRjb21lID09PSBcIlllc1wiID8gcGRhcy55ZXNNaW50IDogcGRhcy5ub01pbnQ7XG4gICAgY29uc3QgdXNlck91dGNvbWVUb2tlbiA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKHRhcmdldE1pbnQsIHVzZXIpO1xuXG4gICAgLy8gQ2hlY2sgaWYgQVRBIGV4aXN0cyBhbmQgY3JlYXRlIGlmIG5lZWRlZFxuICAgIGlmIChjcmVhdGVBdGEpIHtcbiAgICAgIGNvbnN0IGV4aXN0cyA9IGF3YWl0IHRoaXMuYXRhRXhpc3RzKHVzZXJPdXRjb21lVG9rZW4pO1xuICAgICAgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgY29uc3QgY3JlYXRlQXRhSXggPSB0aGlzLmNyZWF0ZUF0YUluc3RydWN0aW9uKHVzZXIsIHVzZXIsIHRhcmdldE1pbnQpO1xuICAgICAgICB0eC5hZGQoY3JlYXRlQXRhSXgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHBsYWNlQmV0SXggPSBhd2FpdCB0aGlzLnBsYWNlQmV0KHBhcmFtcyk7XG4gICAgdHguYWRkKHBsYWNlQmV0SXgpO1xuXG4gICAgcmV0dXJuIHR4O1xuICB9XG5cbiAgLyoqXG4gICAqIENsYWltIHJld2FyZHMgYWZ0ZXIgbWFya2V0IHJlc29sdXRpb25cbiAgICovXG4gIGFzeW5jIGNsYWltUmV3YXJkcyhwYXJhbXM6IENsYWltUmV3YXJkc1BhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IHsgdXNlciwgYWRtaW4sIG1hcmtldElkLCBiZXR0aW5nVG9rZW4sIHdpbm5pbmdPdXRjb21lIH0gPSBwYXJhbXM7XG4gICAgXG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgcGRhcyA9IGdldE1hcmtldFBkYXModGhpcy5wcm9ncmFtLnByb2dyYW1JZCwgYWRtaW4sIG1hcmtldElkQm4pO1xuICAgIGNvbnN0IHVzZXJCZXR0aW5nVG9rZW4gPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyhiZXR0aW5nVG9rZW4sIHVzZXIpO1xuICAgIFxuICAgIGNvbnN0IHRhcmdldE1pbnQgPSB3aW5uaW5nT3V0Y29tZSA9PT0gXCJZZXNcIiA/IHBkYXMueWVzTWludCA6IHBkYXMubm9NaW50O1xuICAgIGNvbnN0IHVzZXJPdXRjb21lVG9rZW4gPSBnZXRBc3NvY2lhdGVkVG9rZW5BZGRyZXNzU3luYyh0YXJnZXRNaW50LCB1c2VyKTtcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLmNsYWltUmV3YXJkcygpXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBwZGFzLm1hcmtldCxcbiAgICAgICAgdXNlck91dGNvbWVUb2tlbixcbiAgICAgICAgdXNlckJldHRpbmdUb2tlbixcbiAgICAgICAgdXNlcixcbiAgICAgIH0pXG4gICAgICAuaW5zdHJ1Y3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGNvbXBsZXRlIHRyYW5zYWN0aW9uIHRvIGNsYWltIHJld2FyZHNcbiAgICovXG4gIGFzeW5jIGJ1aWxkQ2xhaW1SZXdhcmRzVHgocGFyYW1zOiBDbGFpbVJld2FyZHNQYXJhbXMpOiBQcm9taXNlPFRyYW5zYWN0aW9uPiB7XG4gICAgY29uc3QgaXggPSBhd2FpdCB0aGlzLmNsYWltUmV3YXJkcyhwYXJhbXMpO1xuICAgIHJldHVybiBuZXcgVHJhbnNhY3Rpb24oKS5hZGQoaXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZnVuZCBiZXRzIGlmIG1hcmtldCBpcyByZWZ1bmRlZFxuICAgKi9cbiAgYXN5bmMgcmVmdW5kKHBhcmFtczogUmVmdW5kUGFyYW1zKTogUHJvbWlzZTxUcmFuc2FjdGlvbkluc3RydWN0aW9uPiB7XG4gICAgY29uc3QgeyB1c2VyLCBhZG1pbiwgbWFya2V0SWQsIGJldHRpbmdUb2tlbiwgb3V0Y29tZSB9ID0gcGFyYW1zO1xuICAgIFxuICAgIGNvbnN0IG1hcmtldElkQm4gPSBuZXcgQW5jaG9yQk4obWFya2V0SWQpO1xuICAgIGNvbnN0IG91dGNvbWVFbnVtID0gb3V0Y29tZSA9PT0gXCJZZXNcIiA/IHsgeWVzOiB7fSB9IDogeyBubzoge30gfTtcbiAgICBjb25zdCBwZGFzID0gZ2V0TWFya2V0UGRhcyh0aGlzLnByb2dyYW0ucHJvZ3JhbUlkLCBhZG1pbiwgbWFya2V0SWRCbik7XG4gICAgY29uc3QgdXNlckJldHRpbmdUb2tlbiA9IGdldEFzc29jaWF0ZWRUb2tlbkFkZHJlc3NTeW5jKGJldHRpbmdUb2tlbiwgdXNlcik7XG4gICAgXG4gICAgY29uc3QgdGFyZ2V0TWludCA9IG91dGNvbWUgPT09IFwiWWVzXCIgPyBwZGFzLnllc01pbnQgOiBwZGFzLm5vTWludDtcbiAgICBjb25zdCB1c2VyT3V0Y29tZVRva2VuID0gZ2V0QXNzb2NpYXRlZFRva2VuQWRkcmVzc1N5bmModGFyZ2V0TWludCwgdXNlcik7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9ncmFtLm1ldGhvZHNcbiAgICAgIC5yZWZ1bmQob3V0Y29tZUVudW0pXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBwZGFzLm1hcmtldCxcbiAgICAgICAgdXNlck91dGNvbWVUb2tlbixcbiAgICAgICAgdXNlckJldHRpbmdUb2tlbixcbiAgICAgICAgdXNlcixcbiAgICAgIH0pXG4gICAgICAuaW5zdHJ1Y3Rpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGNvbXBsZXRlIHRyYW5zYWN0aW9uIHRvIHJlZnVuZFxuICAgKi9cbiAgYXN5bmMgYnVpbGRSZWZ1bmRUeChwYXJhbXM6IFJlZnVuZFBhcmFtcyk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpeCA9IGF3YWl0IHRoaXMucmVmdW5kKHBhcmFtcyk7XG4gICAgcmV0dXJuIG5ldyBUcmFuc2FjdGlvbigpLmFkZChpeCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBhIG1hcmtldCAoQWRtaW4gb25seSlcbiAgICovXG4gIGFzeW5jIHJlc29sdmVNYXJrZXQoXG4gICAgYWRtaW46IFB1YmxpY0tleSxcbiAgICBtYXJrZXRJZDogbnVtYmVyIHwgQk4sXG4gICAgd2lubmluZ091dGNvbWU6IFwiWWVzXCIgfCBcIk5vXCIgfCBudWxsXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IG1hcmtldElkQm4gPSBuZXcgQW5jaG9yQk4obWFya2V0SWQpO1xuICAgIGNvbnN0IG1hcmtldFBkYSA9IGdldE1hcmtldFBkYSh0aGlzLnByb2dyYW0ucHJvZ3JhbUlkLCBhZG1pbiwgbWFya2V0SWRCbik7XG5cbiAgICBsZXQgb3V0Y29tZUVudW06IGFueSA9IG51bGw7XG4gICAgaWYgKHdpbm5pbmdPdXRjb21lID09PSBcIlllc1wiKSB7XG4gICAgICBvdXRjb21lRW51bSA9IHsgeWVzOiB7fSB9O1xuICAgIH0gZWxzZSBpZiAod2lubmluZ091dGNvbWUgPT09IFwiTm9cIikge1xuICAgICAgb3V0Y29tZUVudW0gPSB7IG5vOiB7fSB9O1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnByb2dyYW0ubWV0aG9kc1xuICAgICAgLnJlc29sdmVNYXJrZXQob3V0Y29tZUVudW0pXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBtYXJrZXRQZGEsXG4gICAgICAgIGFkbWluLFxuICAgICAgfSlcbiAgICAgIC5pbnN0cnVjdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgY29tcGxldGUgdHJhbnNhY3Rpb24gdG8gcmVzb2x2ZSBhIG1hcmtldFxuICAgKi9cbiAgYXN5bmMgYnVpbGRSZXNvbHZlTWFya2V0VHgoXG4gICAgYWRtaW46IFB1YmxpY0tleSxcbiAgICBtYXJrZXRJZDogbnVtYmVyIHwgQk4sXG4gICAgd2lubmluZ091dGNvbWU6IFwiWWVzXCIgfCBcIk5vXCIgfCBudWxsXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpeCA9IGF3YWl0IHRoaXMucmVzb2x2ZU1hcmtldChhZG1pbiwgbWFya2V0SWQsIHdpbm5pbmdPdXRjb21lKTtcbiAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uKCkuYWRkKGl4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZSBhIG1hcmtldCAoQWRtaW4gb25seSlcbiAgICovXG4gIGFzeW5jIGNsb3NlTWFya2V0KFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgbWFya2V0SWQ6IG51bWJlciB8IEJOXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb25JbnN0cnVjdGlvbj4ge1xuICAgIGNvbnN0IG1hcmtldElkQm4gPSBuZXcgQW5jaG9yQk4obWFya2V0SWQpO1xuICAgIGNvbnN0IG1hcmtldFBkYSA9IGdldE1hcmtldFBkYSh0aGlzLnByb2dyYW0ucHJvZ3JhbUlkLCBhZG1pbiwgbWFya2V0SWRCbik7XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9ncmFtLm1ldGhvZHNcbiAgICAgIC5jbG9zZU1hcmtldCgpXG4gICAgICAuYWNjb3VudHNQYXJ0aWFsKHtcbiAgICAgICAgbWFya2V0OiBtYXJrZXRQZGEsXG4gICAgICB9KVxuICAgICAgLmluc3RydWN0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBjb21wbGV0ZSB0cmFuc2FjdGlvbiB0byBjbG9zZSBhIG1hcmtldFxuICAgKi9cbiAgYXN5bmMgYnVpbGRDbG9zZU1hcmtldFR4KFxuICAgIGFkbWluOiBQdWJsaWNLZXksXG4gICAgbWFya2V0SWQ6IG51bWJlciB8IEJOXG4gICk6IFByb21pc2U8VHJhbnNhY3Rpb24+IHtcbiAgICBjb25zdCBpeCA9IGF3YWl0IHRoaXMuY2xvc2VNYXJrZXQoYWRtaW4sIG1hcmtldElkKTtcbiAgICByZXR1cm4gbmV3IFRyYW5zYWN0aW9uKCkuYWRkKGl4KTtcbiAgfVxuICBcbiAgLyoqXG4gICAqIEZldGNoIG1hcmtldCBhY2NvdW50IGRhdGFcbiAgICovXG4gIGFzeW5jIGdldE1hcmtldEFjY291bnQoYWRtaW46IFB1YmxpY0tleSwgbWFya2V0SWQ6IG51bWJlciB8IEJOKSB7XG4gICAgY29uc3QgbWFya2V0SWRCbiA9IG5ldyBBbmNob3JCTihtYXJrZXRJZCk7XG4gICAgY29uc3QgbWFya2V0UGRhID0gZ2V0TWFya2V0UGRhKHRoaXMucHJvZ3JhbS5wcm9ncmFtSWQsIGFkbWluLCBtYXJrZXRJZEJuKTtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5wcm9ncmFtLmFjY291bnQubWFya2V0LmZldGNoKG1hcmtldFBkYSk7XG4gIH1cbn1cbiJdfQ==