@discordeno/gateway 19.0.0-next.85ea2d9 → 19.0.0-next.87f62d2
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/README.md +16 -13
- package/dist/cjs/Shard.cjs +488 -0
- package/dist/cjs/index.cjs +22 -0
- package/dist/cjs/manager.cjs +463 -0
- package/dist/cjs/types.cjs +41 -0
- package/dist/esm/Shard.js +465 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/manager.js +448 -0
- package/dist/esm/types.js +23 -0
- package/dist/{Shard.d.ts → types/Shard.d.ts} +12 -89
- package/dist/types/Shard.d.ts.map +1 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{manager.d.ts → types/manager.d.ts} +74 -12
- package/dist/types/manager.d.ts.map +1 -0
- package/dist/{types.d.ts → types/types.d.ts} +2 -3
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +31 -27
- package/dist/Shard.d.ts.map +0 -1
- package/dist/Shard.js +0 -599
- package/dist/Shard.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -5
- package/dist/index.js.map +0 -1
- package/dist/manager.d.ts.map +0 -1
- package/dist/manager.js +0 -243
- package/dist/manager.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -23
- package/dist/types.js.map +0 -1
- /package/dist/{index.d.ts → types/index.d.ts} +0 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export * from './manager.js';
|
|
2
|
+
export * from './Shard.js';
|
|
3
|
+
export * from './types.js';
|
|
4
|
+
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL21hbmFnZXIuanMnXG5leHBvcnQgKiBmcm9tICcuL1NoYXJkLmpzJ1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcy5qcydcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLGVBQWM7QUFDNUIsY0FBYyxhQUFZO0FBQzFCLGNBQWMsYUFBWSJ9
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import { GatewayIntents, GatewayOpcodes } from '@discordeno/types';
|
|
2
|
+
import { Collection, delay, logger } from '@discordeno/utils';
|
|
3
|
+
import Shard from './Shard.js';
|
|
4
|
+
import { ShardSocketCloseCodes } from './types.js';
|
|
5
|
+
export function createGatewayManager(options) {
|
|
6
|
+
const connectionOptions = options.connection ?? {
|
|
7
|
+
url: 'wss://gateway.discord.gg',
|
|
8
|
+
shards: 1,
|
|
9
|
+
sessionStartLimit: {
|
|
10
|
+
maxConcurrency: 1,
|
|
11
|
+
remaining: 1000,
|
|
12
|
+
total: 1000,
|
|
13
|
+
resetAfter: 1000 * 60 * 60 * 24
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const gateway = {
|
|
17
|
+
events: options.events ?? {},
|
|
18
|
+
compress: options.compress ?? false,
|
|
19
|
+
intents: options.intents ?? 0,
|
|
20
|
+
properties: {
|
|
21
|
+
os: options.properties?.os ?? process.platform,
|
|
22
|
+
browser: options.properties?.browser ?? 'Discordeno',
|
|
23
|
+
device: options.properties?.device ?? 'Discordeno'
|
|
24
|
+
},
|
|
25
|
+
token: options.token,
|
|
26
|
+
url: options.url ?? connectionOptions.url ?? 'wss://gateway.discord.gg',
|
|
27
|
+
version: options.version ?? 10,
|
|
28
|
+
connection: connectionOptions,
|
|
29
|
+
totalShards: options.totalShards ?? connectionOptions.shards ?? 1,
|
|
30
|
+
lastShardId: options.lastShardId ?? (options.totalShards ? options.totalShards - 1 : connectionOptions ? connectionOptions.shards - 1 : 0),
|
|
31
|
+
firstShardId: options.firstShardId ?? 0,
|
|
32
|
+
totalWorkers: options.totalWorkers ?? 4,
|
|
33
|
+
shardsPerWorker: options.shardsPerWorker ?? 25,
|
|
34
|
+
spawnShardDelay: options.spawnShardDelay ?? 5300,
|
|
35
|
+
preferSnakeCase: options.preferSnakeCase ?? false,
|
|
36
|
+
shards: new Map(),
|
|
37
|
+
buckets: new Map(),
|
|
38
|
+
cache: {
|
|
39
|
+
requestMembers: {
|
|
40
|
+
enabled: options.cache?.requestMembers?.enabled ?? false,
|
|
41
|
+
pending: new Collection()
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
logger: options.logger ?? logger,
|
|
45
|
+
resharding: {
|
|
46
|
+
enabled: true,
|
|
47
|
+
shardsFullPercentage: 80,
|
|
48
|
+
checkInterval: 28800000,
|
|
49
|
+
shards: new Collection(),
|
|
50
|
+
pendingShards: new Collection(),
|
|
51
|
+
async getSessionInfo () {
|
|
52
|
+
throw new Error('[Resharding] was enabled but no getSessionInfo handler was provided. Please set a handler like: gateway.resharding.getSessionInfo = async () => { // insert code here to fetch getSessionInfo from rest process. }');
|
|
53
|
+
},
|
|
54
|
+
async checkIfReshardingIsNeeded () {
|
|
55
|
+
logger.warn(`[Resharding] Checking if resharding is needed.`);
|
|
56
|
+
// Resharding is disabled.
|
|
57
|
+
if (!gateway.resharding.enabled) return {
|
|
58
|
+
needed: false
|
|
59
|
+
};
|
|
60
|
+
logger.warn(`[Resharding] Resharding is enabled.`);
|
|
61
|
+
const sessionInfo = await gateway.resharding.getSessionInfo();
|
|
62
|
+
logger.warn(`[Resharding] Session info retrieved.`);
|
|
63
|
+
// Don't have enough identify limits to try resharding
|
|
64
|
+
if (sessionInfo.sessionStartLimit.remaining < sessionInfo.shards) return {
|
|
65
|
+
needed: false,
|
|
66
|
+
info: sessionInfo
|
|
67
|
+
};
|
|
68
|
+
logger.warn(`[Resharding] Able to reshard, checking whether necessary now.`);
|
|
69
|
+
// 2500 is the max amount of guilds a single shard can handle
|
|
70
|
+
// 1000 is the amount of guilds discord uses to determine how many shards to recommend.
|
|
71
|
+
// This algo helps check if your bot has grown enough to reshard.
|
|
72
|
+
const percentage = 2500 * sessionInfo.shards / (gateway.totalShards * 1000) * 100;
|
|
73
|
+
// Less than necessary% being used so do nothing
|
|
74
|
+
if (percentage < gateway.resharding.shardsFullPercentage) return {
|
|
75
|
+
needed: false,
|
|
76
|
+
info: sessionInfo
|
|
77
|
+
};
|
|
78
|
+
logger.warn(`[Resharding] Resharding is needed.`);
|
|
79
|
+
return {
|
|
80
|
+
needed: true,
|
|
81
|
+
info: sessionInfo
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
async reshard (info) {
|
|
85
|
+
logger.warn(`[Resharding] Starting the reshard process. Previous total shards. ${gateway.totalShards}`);
|
|
86
|
+
// Set values on gateway
|
|
87
|
+
gateway.totalShards = info.shards;
|
|
88
|
+
// Handles preparing mid sized bots for LBS
|
|
89
|
+
gateway.totalShards = gateway.calculateTotalShards();
|
|
90
|
+
// Set first shard id if provided in info
|
|
91
|
+
if (typeof info.firstShardId === 'number') gateway.firstShardId = info.firstShardId;
|
|
92
|
+
// Set last shard id if provided in info
|
|
93
|
+
if (typeof info.lastShardId === 'number') gateway.lastShardId = info.lastShardId;
|
|
94
|
+
logger.warn(`[Resharding] Starting the reshard process. New Total Shards. ${gateway.totalShards}`);
|
|
95
|
+
// Resetting buckets
|
|
96
|
+
gateway.buckets.clear();
|
|
97
|
+
// Refilling buckets with new values
|
|
98
|
+
gateway.prepareBuckets();
|
|
99
|
+
// SPREAD THIS OUT TO DIFFERENT WORKERS TO BEGIN STARTING UP
|
|
100
|
+
gateway.buckets.forEach(async (bucket, bucketId)=>{
|
|
101
|
+
for (const worker of bucket.workers){
|
|
102
|
+
for (const shardId of worker.queue){
|
|
103
|
+
await gateway.resharding.tellWorkerToPrepare(worker.id, shardId, bucketId);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
async tellWorkerToPrepare (workerId, shardId, bucketId) {
|
|
109
|
+
logger.warn(`[Resharding] Telling worker to prepare. Worker: ${workerId} | Shard: ${shardId} | Bucket: ${bucketId}`);
|
|
110
|
+
const shard = new Shard({
|
|
111
|
+
id: shardId,
|
|
112
|
+
connection: {
|
|
113
|
+
compress: gateway.compress,
|
|
114
|
+
intents: gateway.intents,
|
|
115
|
+
properties: gateway.properties,
|
|
116
|
+
token: gateway.token,
|
|
117
|
+
totalShards: gateway.totalShards,
|
|
118
|
+
url: gateway.url,
|
|
119
|
+
version: gateway.version
|
|
120
|
+
},
|
|
121
|
+
// Ignore events until we are ready
|
|
122
|
+
events: {
|
|
123
|
+
async message (_shard, payload) {
|
|
124
|
+
if (payload.t === 'READY') {
|
|
125
|
+
await gateway.resharding.updateGuildsShardId(payload.d.guilds.map((g)=>g.id), shardId);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
requestIdentify: async ()=>{
|
|
130
|
+
await gateway.identify(shardId);
|
|
131
|
+
},
|
|
132
|
+
shardIsReady: async ()=>{
|
|
133
|
+
logger.debug(`[Shard] Shard #${shardId} is ready`);
|
|
134
|
+
await delay(gateway.spawnShardDelay);
|
|
135
|
+
logger.debug(`[Shard] Resolving shard identify request`);
|
|
136
|
+
gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency).identifyRequests.shift()?.();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
if (gateway.preferSnakeCase) {
|
|
140
|
+
shard.forwardToBot = async (payload)=>{
|
|
141
|
+
shard.events?.message?.(shard, payload);
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
gateway.resharding.shards.set(shardId, shard);
|
|
145
|
+
const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency);
|
|
146
|
+
if (!bucket) return;
|
|
147
|
+
return await new Promise((resolve)=>{
|
|
148
|
+
// Mark that we are making an identify request so another is not made.
|
|
149
|
+
bucket.identifyRequests.push(resolve);
|
|
150
|
+
logger.debug(`[Gateway] identifying shard #(${shardId}).`);
|
|
151
|
+
// This will trigger identify and when READY is received it will resolve the above request.
|
|
152
|
+
shard?.identify().then(async ()=>{
|
|
153
|
+
// Tell the manager that this shard is online
|
|
154
|
+
return await gateway.resharding.shardIsPending(shard);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
},
|
|
158
|
+
async updateGuildsShardId (guildIds, shardId) {
|
|
159
|
+
logger.debug(`[Resharding] Updating the following guild ids shard to #${shardId}: ${guildIds.join(', ')}. Override this function to update your cache if you need to.`);
|
|
160
|
+
},
|
|
161
|
+
async shardIsPending (shard) {
|
|
162
|
+
// Save this in pending at the moment, until all shards are online
|
|
163
|
+
gateway.resharding.pendingShards.set(shard.id, shard);
|
|
164
|
+
logger.warn(`[Resharding] Shard #${shard.id} is now pending`);
|
|
165
|
+
// Check if all shards are now online.
|
|
166
|
+
if (gateway.lastShardId - gateway.firstShardId + 1 > gateway.resharding.pendingShards.size) return;
|
|
167
|
+
logger.warn(`[Resharding] All shards are now online.`);
|
|
168
|
+
// New shards start processing events
|
|
169
|
+
for (const shard of gateway.resharding.pendingShards.values()){
|
|
170
|
+
for(const event in options.events){
|
|
171
|
+
// @ts-expect-error fixing this seems complex and doesnt seem worth it, feel free to fix if you wish
|
|
172
|
+
shard.events[event] = options.events[event];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Old shards stop processing events
|
|
176
|
+
for (const shard of gateway.shards.values()){
|
|
177
|
+
const oldHandler = shard.events.message;
|
|
178
|
+
// Change with spread operator to not affect new shards, as changing anything on shard.events will directly change options.events, which changes new shards' events
|
|
179
|
+
shard.events = {
|
|
180
|
+
...shard.events,
|
|
181
|
+
message: async function(_, message) {
|
|
182
|
+
// Member checks need to continue but others can stop
|
|
183
|
+
if (message.t !== 'GUILD_MEMBERS_CHUNK') return;
|
|
184
|
+
// Process only the chunking events
|
|
185
|
+
oldHandler?.(shard, message);
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
logger.warn(`[Resharding] Shutting down old shards.`);
|
|
190
|
+
// Close old shards
|
|
191
|
+
await gateway.shutdown(ShardSocketCloseCodes.Resharded, 'Resharded!', false);
|
|
192
|
+
logger.warn(`[Resharding] Completed.`);
|
|
193
|
+
// Replace old shards
|
|
194
|
+
gateway.shards = gateway.resharding.shards;
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
calculateTotalShards () {
|
|
198
|
+
// Bots under 100k servers do not have access to LBS.
|
|
199
|
+
if (gateway.totalShards < 100) {
|
|
200
|
+
gateway.logger.debug(`[Gateway] Calculating total shards: ${gateway.totalShards}`);
|
|
201
|
+
return gateway.totalShards;
|
|
202
|
+
}
|
|
203
|
+
gateway.logger.debug(`[Gateway] Calculating total shards`, gateway.totalShards, gateway.connection.sessionStartLimit.maxConcurrency);
|
|
204
|
+
// Calculate a multiple of `maxConcurrency` which can be used to connect to the gateway.
|
|
205
|
+
return Math.ceil(gateway.totalShards / // If `maxConcurrency` is 1, we can safely use 16 to get `totalShards` to be in a multiple of 16 so that we can prepare bots with 100k servers for LBS.
|
|
206
|
+
(gateway.connection.sessionStartLimit.maxConcurrency === 1 ? 16 : gateway.connection.sessionStartLimit.maxConcurrency)) * (gateway.connection.sessionStartLimit.maxConcurrency === 1 ? 16 : gateway.connection.sessionStartLimit.maxConcurrency);
|
|
207
|
+
},
|
|
208
|
+
calculateWorkerId (shardId) {
|
|
209
|
+
const workerId = Math.min(shardId % gateway.shardsPerWorker, gateway.totalWorkers - 1);
|
|
210
|
+
gateway.logger.debug(`[Gateway] Calculating workerId: Shard: ${shardId} -> Worker: ${workerId} -> Per Worker: ${gateway.shardsPerWorker} -> Total: ${gateway.totalWorkers}`);
|
|
211
|
+
return workerId;
|
|
212
|
+
},
|
|
213
|
+
prepareBuckets () {
|
|
214
|
+
for(let i = 0; i < gateway.connection.sessionStartLimit.maxConcurrency; ++i){
|
|
215
|
+
gateway.logger.debug(`[Gateway] Preparing buckets for concurrency: ${i}`);
|
|
216
|
+
gateway.buckets.set(i, {
|
|
217
|
+
workers: [],
|
|
218
|
+
identifyRequests: []
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
// ORGANIZE ALL SHARDS INTO THEIR OWN BUCKETS
|
|
222
|
+
for(let shardId = gateway.firstShardId; shardId <= gateway.lastShardId; ++shardId){
|
|
223
|
+
gateway.logger.debug(`[Gateway] Preparing buckets for shard: ${shardId}`);
|
|
224
|
+
if (shardId >= gateway.totalShards) {
|
|
225
|
+
throw new Error(`Shard (id: ${shardId}) is bigger or equal to the used amount of used shards which is ${gateway.totalShards}`);
|
|
226
|
+
}
|
|
227
|
+
const bucketId = shardId % gateway.connection.sessionStartLimit.maxConcurrency;
|
|
228
|
+
const bucket = gateway.buckets.get(bucketId);
|
|
229
|
+
if (!bucket) {
|
|
230
|
+
throw new Error(`Shard (id: ${shardId}) got assigned to an illegal bucket id: ${bucketId}, expected a bucket id between 0 and ${gateway.connection.sessionStartLimit.maxConcurrency - 1}`);
|
|
231
|
+
}
|
|
232
|
+
// FIND A QUEUE IN THIS BUCKET THAT HAS SPACE
|
|
233
|
+
// const worker = bucket.workers.find((w) => w.queue.length < gateway.shardsPerWorker);
|
|
234
|
+
const workerId = gateway.calculateWorkerId(shardId);
|
|
235
|
+
const worker = bucket.workers.find((w)=>w.id === workerId);
|
|
236
|
+
if (worker) {
|
|
237
|
+
// IF THE QUEUE HAS SPACE JUST ADD IT TO THIS QUEUE
|
|
238
|
+
worker.queue.push(shardId);
|
|
239
|
+
} else {
|
|
240
|
+
bucket.workers.push({
|
|
241
|
+
id: workerId,
|
|
242
|
+
queue: [
|
|
243
|
+
shardId
|
|
244
|
+
]
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
for (const bucket of gateway.buckets.values()){
|
|
249
|
+
for (const worker of bucket.workers.values()){
|
|
250
|
+
worker.queue = worker.queue.sort((a, b)=>a - b);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
async spawnShards () {
|
|
255
|
+
// PREPARES ALL SHARDS IN SPECIFIC BUCKETS
|
|
256
|
+
gateway.prepareBuckets();
|
|
257
|
+
// Prefer concurrency of forEach instead of forof
|
|
258
|
+
await Promise.all([
|
|
259
|
+
...gateway.buckets.entries()
|
|
260
|
+
].map(async ([bucketId, bucket])=>{
|
|
261
|
+
for (const worker of bucket.workers){
|
|
262
|
+
for (const shardId of worker.queue){
|
|
263
|
+
await gateway.tellWorkerToIdentify(worker.id, shardId, bucketId);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}));
|
|
267
|
+
// Check and reshard automatically if auto resharding is enabled.
|
|
268
|
+
if (gateway.resharding.enabled && gateway.resharding.checkInterval !== -1) {
|
|
269
|
+
gateway.resharding.checkIntervalId = setInterval(async ()=>{
|
|
270
|
+
const reshardingInfo = await gateway.resharding.checkIfReshardingIsNeeded();
|
|
271
|
+
if (reshardingInfo.needed && reshardingInfo.info) await gateway.resharding.reshard(reshardingInfo.info);
|
|
272
|
+
}, gateway.resharding.checkInterval);
|
|
273
|
+
}
|
|
274
|
+
},
|
|
275
|
+
async shutdown (code, reason, clearReshardingInterval = true) {
|
|
276
|
+
gateway.shards.forEach((shard)=>shard.close(code, reason));
|
|
277
|
+
if (clearReshardingInterval && gateway.resharding.checkIntervalId) clearInterval(gateway.resharding.checkIntervalId);
|
|
278
|
+
await delay(5000);
|
|
279
|
+
},
|
|
280
|
+
async sendPayload (shardId, payload) {
|
|
281
|
+
const shard = gateway.shards.get(shardId);
|
|
282
|
+
if (!shard) {
|
|
283
|
+
throw new Error(`Shard (id: ${shardId} not found`);
|
|
284
|
+
}
|
|
285
|
+
await shard.send(payload);
|
|
286
|
+
},
|
|
287
|
+
async tellWorkerToIdentify (workerId, shardId, bucketId) {
|
|
288
|
+
gateway.logger.debug(`[Gateway] tell worker to identify (${workerId}, ${shardId}, ${bucketId})`);
|
|
289
|
+
await gateway.identify(shardId);
|
|
290
|
+
},
|
|
291
|
+
async identify (shardId) {
|
|
292
|
+
let shard = this.shards.get(shardId);
|
|
293
|
+
gateway.logger.debug(`[Gateway] identifying ${shard ? 'existing' : 'new'} shard (${shardId})`);
|
|
294
|
+
if (!shard) {
|
|
295
|
+
shard = new Shard({
|
|
296
|
+
id: shardId,
|
|
297
|
+
connection: {
|
|
298
|
+
compress: this.compress,
|
|
299
|
+
intents: this.intents,
|
|
300
|
+
properties: this.properties,
|
|
301
|
+
token: this.token,
|
|
302
|
+
totalShards: this.totalShards,
|
|
303
|
+
url: this.url,
|
|
304
|
+
version: this.version
|
|
305
|
+
},
|
|
306
|
+
events: options.events ?? {},
|
|
307
|
+
logger: this.logger,
|
|
308
|
+
requestIdentify: async ()=>{
|
|
309
|
+
await gateway.identify(shardId);
|
|
310
|
+
},
|
|
311
|
+
shardIsReady: async ()=>{
|
|
312
|
+
gateway.logger.debug(`[Shard] Shard #${shardId} is ready`);
|
|
313
|
+
await delay(gateway.spawnShardDelay);
|
|
314
|
+
gateway.logger.debug(`[Shard] Resolving shard identify request`);
|
|
315
|
+
gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency).identifyRequests.shift()?.();
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
if (this.preferSnakeCase) {
|
|
319
|
+
shard.forwardToBot = async (payload)=>{
|
|
320
|
+
shard.events.message?.(shard, payload);
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
this.shards.set(shardId, shard);
|
|
324
|
+
}
|
|
325
|
+
const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency);
|
|
326
|
+
if (!bucket) return;
|
|
327
|
+
return await new Promise((resolve)=>{
|
|
328
|
+
// Mark that we are making an identify request so another is not made.
|
|
329
|
+
bucket.identifyRequests.push(resolve);
|
|
330
|
+
gateway.logger.debug(`[Gateway] identifying shard #(${shardId}).`);
|
|
331
|
+
// This will trigger identify and when READY is received it will resolve the above request.
|
|
332
|
+
shard?.identify();
|
|
333
|
+
});
|
|
334
|
+
},
|
|
335
|
+
async kill (shardId) {
|
|
336
|
+
const shard = this.shards.get(shardId);
|
|
337
|
+
if (!shard) {
|
|
338
|
+
return gateway.logger.debug(`[Gateway] kill shard but not found (${shardId})`);
|
|
339
|
+
}
|
|
340
|
+
gateway.logger.debug(`[Gateway] kill shard (${shardId})`);
|
|
341
|
+
this.shards.delete(shardId);
|
|
342
|
+
await shard.shutdown();
|
|
343
|
+
},
|
|
344
|
+
async requestIdentify (_shardId) {
|
|
345
|
+
gateway.logger.debug(`[Gateway] requesting identify`);
|
|
346
|
+
// const bucket = gateway.buckets.get(shardId % gateway.connection.sessionStartLimit.maxConcurrency)
|
|
347
|
+
// if (!bucket) return
|
|
348
|
+
// return await new Promise((resolve) => {
|
|
349
|
+
// bucket.identifyRequests.push(resolve)
|
|
350
|
+
// })
|
|
351
|
+
},
|
|
352
|
+
// Helpers methods below this
|
|
353
|
+
calculateShardId (guildId, totalShards) {
|
|
354
|
+
// If none is provided, use the total shards number from gateway object.
|
|
355
|
+
if (!totalShards) totalShards = gateway.totalShards;
|
|
356
|
+
// If it is only 1 shard, it will always be shard id 0
|
|
357
|
+
if (totalShards === 1) {
|
|
358
|
+
gateway.logger.debug(`[Gateway] calculateShardId (1 shard)`);
|
|
359
|
+
return 0;
|
|
360
|
+
}
|
|
361
|
+
gateway.logger.debug(`[Gateway] calculateShardId (guildId: ${guildId}, totalShards: ${totalShards})`);
|
|
362
|
+
return Number((BigInt(guildId) >> 22n) % BigInt(totalShards));
|
|
363
|
+
},
|
|
364
|
+
async joinVoiceChannel (guildId, channelId, options) {
|
|
365
|
+
const shardId = gateway.calculateShardId(guildId);
|
|
366
|
+
gateway.logger.debug(`[Gateway] joinVoiceChannel guildId: ${guildId} channelId: ${channelId}`);
|
|
367
|
+
await gateway.sendPayload(shardId, {
|
|
368
|
+
op: GatewayOpcodes.VoiceStateUpdate,
|
|
369
|
+
d: {
|
|
370
|
+
guild_id: guildId.toString(),
|
|
371
|
+
channel_id: channelId.toString(),
|
|
372
|
+
self_mute: options?.selfMute ?? false,
|
|
373
|
+
self_deaf: options?.selfDeaf ?? true
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
},
|
|
377
|
+
async editBotStatus (data) {
|
|
378
|
+
gateway.logger.debug(`[Gateway] editBotStatus data: ${JSON.stringify(data)}`);
|
|
379
|
+
await Promise.all([
|
|
380
|
+
...gateway.shards.values()
|
|
381
|
+
].map(async (shard)=>{
|
|
382
|
+
gateway.editShardStatus(shard.id, data);
|
|
383
|
+
}));
|
|
384
|
+
},
|
|
385
|
+
async editShardStatus (shardId, data) {
|
|
386
|
+
gateway.logger.debug(`[Gateway] editShardStatus shardId: ${shardId} -> data: ${JSON.stringify(data)}`);
|
|
387
|
+
await gateway.sendPayload(shardId, {
|
|
388
|
+
op: GatewayOpcodes.PresenceUpdate,
|
|
389
|
+
d: {
|
|
390
|
+
since: null,
|
|
391
|
+
afk: false,
|
|
392
|
+
activities: data.activities,
|
|
393
|
+
status: data.status
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
},
|
|
397
|
+
async requestMembers (guildId, options) {
|
|
398
|
+
const shardId = gateway.calculateShardId(guildId);
|
|
399
|
+
if (gateway.intents && (!options?.limit || options.limit > 1) && !(gateway.intents & GatewayIntents.GuildMembers)) throw new Error('Cannot fetch more then 1 member without the GUILD_MEMBERS intent');
|
|
400
|
+
gateway.logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> data: ${JSON.stringify(options)}`);
|
|
401
|
+
if (options?.userIds?.length) {
|
|
402
|
+
gateway.logger.debug(`[Gateway] requestMembers guildId: ${guildId} -> setting user limit based on userIds length: ${options.userIds.length}`);
|
|
403
|
+
options.limit = options.userIds.length;
|
|
404
|
+
}
|
|
405
|
+
const members = !gateway.cache.requestMembers.enabled || !options?.nonce ? [] : new Promise((resolve, reject)=>{
|
|
406
|
+
// Should never happen.
|
|
407
|
+
if (!gateway.cache.requestMembers.enabled || !options?.nonce) {
|
|
408
|
+
reject(new Error("Can't request the members without the nonce or with the feature disabled."));
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
gateway.cache.requestMembers.pending.set(options.nonce, {
|
|
412
|
+
nonce: options.nonce,
|
|
413
|
+
resolve,
|
|
414
|
+
members: []
|
|
415
|
+
});
|
|
416
|
+
});
|
|
417
|
+
await gateway.sendPayload(shardId, {
|
|
418
|
+
op: GatewayOpcodes.RequestGuildMembers,
|
|
419
|
+
d: {
|
|
420
|
+
guild_id: guildId.toString(),
|
|
421
|
+
// If a query is provided use it, OR if a limit is NOT provided use ""
|
|
422
|
+
query: options?.query ?? (options?.limit ? undefined : ''),
|
|
423
|
+
limit: options?.limit ?? 0,
|
|
424
|
+
presences: options?.presences ?? false,
|
|
425
|
+
user_ids: options?.userIds?.map((id)=>id.toString()),
|
|
426
|
+
nonce: options?.nonce
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
return await members;
|
|
430
|
+
},
|
|
431
|
+
async leaveVoiceChannel (guildId) {
|
|
432
|
+
const shardId = gateway.calculateShardId(guildId);
|
|
433
|
+
gateway.logger.debug(`[Gateway] leaveVoiceChannel guildId: ${guildId} Shard ${shardId}`);
|
|
434
|
+
await gateway.sendPayload(shardId, {
|
|
435
|
+
op: GatewayOpcodes.VoiceStateUpdate,
|
|
436
|
+
d: {
|
|
437
|
+
guild_id: guildId.toString(),
|
|
438
|
+
channel_id: null,
|
|
439
|
+
self_mute: false,
|
|
440
|
+
self_deaf: false
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
return gateway;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tYW5hZ2VyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIHR5cGUgQXRMZWFzdE9uZSxcbiAgdHlwZSBCaWdTdHJpbmcsXG4gIHR5cGUgQ2FtZWxpemUsXG4gIHR5cGUgRGlzY29yZEdldEdhdGV3YXlCb3QsXG4gIHR5cGUgRGlzY29yZE1lbWJlcldpdGhVc2VyLFxuICB0eXBlIERpc2NvcmRSZWFkeSxcbiAgR2F0ZXdheUludGVudHMsXG4gIEdhdGV3YXlPcGNvZGVzLFxuICB0eXBlIFJlcXVlc3RHdWlsZE1lbWJlcnMsXG59IGZyb20gJ0BkaXNjb3JkZW5vL3R5cGVzJ1xuaW1wb3J0IHsgQ29sbGVjdGlvbiwgZGVsYXksIGxvZ2dlciB9IGZyb20gJ0BkaXNjb3JkZW5vL3V0aWxzJ1xuaW1wb3J0IFNoYXJkIGZyb20gJy4vU2hhcmQuanMnXG5pbXBvcnQgeyB0eXBlIFNoYXJkRXZlbnRzLCBTaGFyZFNvY2tldENsb3NlQ29kZXMsIHR5cGUgU2hhcmRTb2NrZXRSZXF1ZXN0LCB0eXBlIFN0YXR1c1VwZGF0ZSwgdHlwZSBVcGRhdGVWb2ljZVN0YXRlIH0gZnJvbSAnLi90eXBlcy5qcydcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUdhdGV3YXlNYW5hZ2VyKG9wdGlvbnM6IENyZWF0ZUdhdGV3YXlNYW5hZ2VyT3B0aW9ucyk6IEdhdGV3YXlNYW5hZ2VyIHtcbiAgY29uc3QgY29ubmVjdGlvbk9wdGlvbnMgPSBvcHRpb25zLmNvbm5lY3Rpb24gPz8ge1xuICAgIHVybDogJ3dzczovL2dhdGV3YXkuZGlzY29yZC5nZycsXG4gICAgc2hhcmRzOiAxLFxuICAgIHNlc3Npb25TdGFydExpbWl0OiB7XG4gICAgICBtYXhDb25jdXJyZW5jeTogMSxcbiAgICAgIHJlbWFpbmluZzogMTAwMCxcbiAgICAgIHRvdGFsOiAxMDAwLFxuICAgICAgcmVzZXRBZnRlcjogMTAwMCAqIDYwICogNjAgKiAyNCxcbiAgICB9LFxuICB9XG5cbiAgY29uc3QgZ2F0ZXdheTogR2F0ZXdheU1hbmFnZXIgPSB7XG4gICAgZXZlbnRzOiBvcHRpb25zLmV2ZW50cyA/PyB7fSxcbiAgICBjb21wcmVzczogb3B0aW9ucy5jb21wcmVzcyA/PyBmYWxzZSxcbiAgICBpbnRlbnRzOiBvcHRpb25zLmludGVudHMgPz8gMCxcbiAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICBvczogb3B0aW9ucy5wcm9wZXJ0aWVzPy5vcyA/PyBwcm9jZXNzLnBsYXRmb3JtLFxuICAgICAgYnJvd3Nlcjogb3B0aW9ucy5wcm9wZXJ0aWVzPy5icm93c2VyID8/ICdEaXNjb3JkZW5vJyxcbiAgICAgIGRldmljZTogb3B0aW9ucy5wcm9wZXJ0aWVzPy5kZXZpY2UgPz8gJ0Rpc2NvcmRlbm8nLFxuICAgIH0sXG4gICAgdG9rZW46IG9wdGlvbnMudG9rZW4sXG4gICAgdXJsOiBvcHRpb25zLnVybCA/PyBjb25uZWN0aW9uT3B0aW9ucy51cmwgPz8gJ3dzczovL2dhdGV3YXkuZGlzY29yZC5nZycsXG4gICAgdmVyc2lvbjogb3B0aW9ucy52ZXJzaW9uID8/IDEwLFxuICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb25PcHRpb25zLFxuICAgIHRvdGFsU2hhcmRzOiBvcHRpb25zLnRvdGFsU2hhcmRzID8/IGNvbm5lY3Rpb25PcHRpb25zLnNoYXJkcyA/PyAxLFxuICAgIGxhc3RTaGFyZElkOiBvcHRpb25zLmxhc3RTaGFyZElkID8/IChvcHRpb25zLnRvdGFsU2hhcmRzID8gb3B0aW9ucy50b3RhbFNoYXJkcyAtIDEgOiBjb25uZWN0aW9uT3B0aW9ucyA/IGNvbm5lY3Rpb25PcHRpb25zLnNoYXJkcyAtIDEgOiAwKSxcbiAgICBmaXJzdFNoYXJkSWQ6IG9wdGlvbnMuZmlyc3RTaGFyZElkID8/IDAsXG4gICAgdG90YWxXb3JrZXJzOiBvcHRpb25zLnRvdGFsV29ya2VycyA/PyA0LFxuICAgIHNoYXJkc1Blcldvcmtlcjogb3B0aW9ucy5zaGFyZHNQZXJXb3JrZXIgPz8gMjUsXG4gICAgc3Bhd25TaGFyZERlbGF5OiBvcHRpb25zLnNwYXduU2hhcmREZWxheSA/PyA1MzAwLFxuICAgIHByZWZlclNuYWtlQ2FzZTogb3B0aW9ucy5wcmVmZXJTbmFrZUNhc2UgPz8gZmFsc2UsXG4gICAgc2hhcmRzOiBuZXcgTWFwKCksXG4gICAgYnVja2V0czogbmV3IE1hcCgpLFxuICAgIGNhY2hlOiB7XG4gICAgICByZXF1ZXN0TWVtYmVyczoge1xuICAgICAgICBlbmFibGVkOiBvcHRpb25zLmNhY2hlPy5yZXF1ZXN0TWVtYmVycz8uZW5hYmxlZCA/PyBmYWxzZSxcbiAgICAgICAgcGVuZGluZzogbmV3IENvbGxlY3Rpb24oKSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICBsb2dnZXI6IG9wdGlvbnMubG9nZ2VyID8/IGxvZ2dlcixcbiAgICByZXNoYXJkaW5nOiB7XG4gICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgc2hhcmRzRnVsbFBlcmNlbnRhZ2U6IDgwLFxuICAgICAgY2hlY2tJbnRlcnZhbDogMjg4MDAwMDAsXG4gICAgICBzaGFyZHM6IG5ldyBDb2xsZWN0aW9uKCksXG4gICAgICBwZW5kaW5nU2hhcmRzOiBuZXcgQ29sbGVjdGlvbigpLFxuICAgICAgYXN5bmMgZ2V0U2Vzc2lvbkluZm8oKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnW1Jlc2hhcmRpbmddIHdhcyBlbmFibGVkIGJ1dCBubyBnZXRTZXNzaW9uSW5mbyBoYW5kbGVyIHdhcyBwcm92aWRlZC4gUGxlYXNlIHNldCBhIGhhbmRsZXIgbGlrZTogZ2F0ZXdheS5yZXNoYXJkaW5nLmdldFNlc3Npb25JbmZvID0gYXN5bmMgKCkgPT4geyAvLyBpbnNlcnQgY29kZSBoZXJlIHRvIGZldGNoIGdldFNlc3Npb25JbmZvIGZyb20gcmVzdCBwcm9jZXNzLiB9JyxcbiAgICAgICAgKVxuICAgICAgfSxcbiAgICAgIGFzeW5jIGNoZWNrSWZSZXNoYXJkaW5nSXNOZWVkZWQoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBbUmVzaGFyZGluZ10gQ2hlY2tpbmcgaWYgcmVzaGFyZGluZyBpcyBuZWVkZWQuYClcbiAgICAgICAgLy8gUmVzaGFyZGluZyBpcyBkaXNhYmxlZC5cbiAgICAgICAgaWYgKCFnYXRld2F5LnJlc2hhcmRpbmcuZW5hYmxlZCkgcmV0dXJuIHsgbmVlZGVkOiBmYWxzZSB9XG4gICAgICAgIGxvZ2dlci53YXJuKGBbUmVzaGFyZGluZ10gUmVzaGFyZGluZyBpcyBlbmFibGVkLmApXG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbkluZm8gPSBhd2FpdCBnYXRld2F5LnJlc2hhcmRpbmcuZ2V0U2Vzc2lvbkluZm8oKVxuICAgICAgICBsb2dnZXIud2FybihgW1Jlc2hhcmRpbmddIFNlc3Npb24gaW5mbyByZXRyaWV2ZWQuYClcbiAgICAgICAgLy8gRG9uJ3QgaGF2ZSBlbm91Z2ggaWRlbnRpZnkgbGltaXRzIHRvIHRyeSByZXNoYXJkaW5nXG4gICAgICAgIGlmIChzZXNzaW9uSW5mby5zZXNzaW9uU3RhcnRMaW1pdC5yZW1haW5pbmcgPCBzZXNzaW9uSW5mby5zaGFyZHMpIHJldHVybiB7IG5lZWRlZDogZmFsc2UsIGluZm86IHNlc3Npb25JbmZvIH1cbiAgICAgICAgbG9nZ2VyLndhcm4oYFtSZXNoYXJkaW5nXSBBYmxlIHRvIHJlc2hhcmQsIGNoZWNraW5nIHdoZXRoZXIgbmVjZXNzYXJ5IG5vdy5gKVxuXG4gICAgICAgIC8vIDI1MDAgaXMgdGhlIG1heCBhbW91bnQgb2YgZ3VpbGRzIGEgc2luZ2xlIHNoYXJkIGNhbiBoYW5kbGVcbiAgICAgICAgLy8gMTAwMCBpcyB0aGUgYW1vdW50IG9mIGd1aWxkcyBkaXNjb3JkIHVzZXMgdG8gZGV0ZXJtaW5lIGhvdyBtYW55IHNoYXJkcyB0byByZWNvbW1lbmQuXG4gICAgICAgIC8vIFRoaXMgYWxnbyBoZWxwcyBjaGVjayBpZiB5b3VyIGJvdCBoYXMgZ3Jvd24gZW5vdWdoIHRvIHJlc2hhcmQuXG4gICAgICAgIGNvbnN0IHBlcmNlbnRhZ2UgPSAoKDI1MDAgKiBzZXNzaW9uSW5mby5zaGFyZHMpIC8gKGdhdGV3YXkudG90YWxTaGFyZHMgKiAxMDAwKSkgKiAxMDBcbiAgICAgICAgLy8gTGVzcyB0aGFuIG5lY2Vzc2FyeSUgYmVpbmcgdXNlZCBzbyBkbyBub3RoaW5nXG4gICAgICAgIGlmIChwZXJjZW50YWdlIDwgZ2F0ZXdheS5yZXNoYXJkaW5nLnNoYXJkc0Z1bGxQZXJjZW50YWdlKSByZXR1cm4geyBuZWVkZWQ6IGZhbHNlLCBpbmZvOiBzZXNzaW9uSW5mbyB9XG4gICAgICAgIGxvZ2dlci53YXJuKGBbUmVzaGFyZGluZ10gUmVzaGFyZGluZyBpcyBuZWVkZWQuYClcblxuICAgICAgICByZXR1cm4geyBuZWVkZWQ6IHRydWUsIGluZm86IHNlc3Npb25JbmZvIH1cbiAgICAgIH0sXG4gICAgICBhc3luYyByZXNoYXJkKGluZm8pIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYFtSZXNoYXJkaW5nXSBTdGFydGluZyB0aGUgcmVzaGFyZCBwcm9jZXNzLiBQcmV2aW91cyB0b3RhbCBzaGFyZHMuICR7Z2F0ZXdheS50b3RhbFNoYXJkc31gKVxuICAgICAgICAvLyBTZXQgdmFsdWVzIG9uIGdhdGV3YXlcbiAgICAgICAgZ2F0ZXdheS50b3RhbFNoYXJkcyA9IGluZm8uc2hhcmRzXG4gICAgICAgIC8vIEhhbmRsZXMgcHJlcGFyaW5nIG1pZCBzaXplZCBib3RzIGZvciBMQlNcbiAgICAgICAgZ2F0ZXdheS50b3RhbFNoYXJkcyA9IGdhdGV3YXkuY2FsY3VsYXRlVG90YWxTaGFyZHMoKVxuICAgICAgICAvLyBTZXQgZmlyc3Qgc2hhcmQgaWQgaWYgcHJvdmlkZWQgaW4gaW5mb1xuICAgICAgICBpZiAodHlwZW9mIGluZm8uZmlyc3RTaGFyZElkID09PSAnbnVtYmVyJykgZ2F0ZXdheS5maXJzdFNoYXJkSWQgPSBpbmZvLmZpcnN0U2hhcmRJZFxuICAgICAgICAvLyBTZXQgbGFzdCBzaGFyZCBpZCBpZiBwcm92aWRlZCBpbiBpbmZvXG4gICAgICAgIGlmICh0eXBlb2YgaW5mby5sYXN0U2hhcmRJZCA9PT0gJ251bWJlcicpIGdhdGV3YXkubGFzdFNoYXJkSWQgPSBpbmZvLmxhc3RTaGFyZElkXG4gICAgICAgIGxvZ2dlci53YXJuKGBbUmVzaGFyZGluZ10gU3RhcnRpbmcgdGhlIHJlc2hhcmQgcHJvY2Vzcy4gTmV3IFRvdGFsIFNoYXJkcy4gJHtnYXRld2F5LnRvdGFsU2hhcmRzfWApXG5cbiAgICAgICAgLy8gUmVzZXR0aW5nIGJ1Y2tldHNcbiAgICAgICAgZ2F0ZXdheS5idWNrZXRzLmNsZWFyKClcbiAgICAgICAgLy8gUmVmaWxsaW5nIGJ1Y2tldHMgd2l0aCBuZXcgdmFsdWVzXG4gICAgICAgIGdhdGV3YXkucHJlcGFyZUJ1Y2tldHMoKVxuXG4gICAgICAgIC8vIFNQUkVBRCBUSElTIE9VVCBUTyBESUZGRVJFTlQgV09SS0VSUyBUTyBCRUdJTiBTVEFSVElORyBVUFxuICAgICAgICBnYXRld2F5LmJ1Y2tldHMuZm9yRWFjaChhc3luYyAoYnVja2V0LCBidWNrZXRJZCkgPT4ge1xuICAgICAgICAgIGZvciAoY29uc3Qgd29ya2VyIG9mIGJ1Y2tldC53b3JrZXJzKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNoYXJkSWQgb2Ygd29ya2VyLnF1ZXVlKSB7XG4gICAgICAgICAgICAgIGF3YWl0IGdhdGV3YXkucmVzaGFyZGluZy50ZWxsV29ya2VyVG9QcmVwYXJlKHdvcmtlci5pZCwgc2hhcmRJZCwgYnVja2V0SWQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfSxcbiAgICAgIGFzeW5jIHRlbGxXb3JrZXJUb1ByZXBhcmUod29ya2VySWQsIHNoYXJkSWQsIGJ1Y2tldElkKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBbUmVzaGFyZGluZ10gVGVsbGluZyB3b3JrZXIgdG8gcHJlcGFyZS4gV29ya2VyOiAke3dvcmtlcklkfSB8IFNoYXJkOiAke3NoYXJkSWR9IHwgQnVja2V0OiAke2J1Y2tldElkfWApXG4gICAgICAgIGNvbnN0IHNoYXJkID0gbmV3IFNoYXJkKHtcbiAgICAgICAgICBpZDogc2hhcmRJZCxcbiAgICAgICAgICBjb25uZWN0aW9uOiB7XG4gICAgICAgICAgICBjb21wcmVzczogZ2F0ZXdheS5jb21wcmVzcyxcbiAgICAgICAgICAgIGludGVudHM6IGdhdGV3YXkuaW50ZW50cyxcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IGdhdGV3YXkucHJvcGVydGllcyxcbiAgICAgICAgICAgIHRva2VuOiBnYXRld2F5LnRva2VuLFxuICAgICAgICAgICAgdG90YWxTaGFyZHM6IGdhdGV3YXkudG90YWxTaGFyZHMsXG4gICAgICAgICAgICB1cmw6IGdhdGV3YXkudXJsLFxuICAgICAgICAgICAgdmVyc2lvbjogZ2F0ZXdheS52ZXJzaW9uLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgLy8gSWdub3JlIGV2ZW50cyB1bnRpbCB3ZSBhcmUgcmVhZHlcbiAgICAgICAgICBldmVudHM6IHtcbiAgICAgICAgICAgIGFzeW5jIG1lc3NhZ2UoX3NoYXJkLCBwYXlsb2FkKSB7XG4gICAgICAgICAgICAgIGlmIChwYXlsb2FkLnQgPT09ICdSRUFEWScpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCBnYXRld2F5LnJlc2hhcmRpbmcudXBkYXRlR3VpbGRzU2hhcmRJZChcbiAgICAgICAgICAgICAgICAgIChwYXlsb2FkLmQgYXMgRGlzY29yZFJlYWR5KS5ndWlsZHMubWFwKChnKSA9PiBnLmlkKSxcbiAgICAgICAgICAgICAgICAgIHNoYXJkSWQsXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVxdWVzdElkZW50aWZ5OiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBhd2FpdCBnYXRld2F5LmlkZW50aWZ5KHNoYXJkSWQpXG4gICAgICAgICAgfSxcbiAgICAgICAgICBzaGFyZElzUmVhZHk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgW1NoYXJkXSBTaGFyZCAjJHtzaGFyZElkfSBpcyByZWFkeWApXG4gICAgICAgICAgICBhd2FpdCBkZWxheShnYXRld2F5LnNwYXduU2hhcmREZWxheSlcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgW1NoYXJkXSBSZXNvbHZpbmcgc2hhcmQgaWRlbnRpZnkgcmVxdWVzdGApXG4gICAgICAgICAgICBnYXRld2F5LmJ1Y2tldHMuZ2V0KHNoYXJkSWQgJSBnYXRld2F5LmNvbm5lY3Rpb24uc2Vzc2lvblN0YXJ0TGltaXQubWF4Q29uY3VycmVuY3kpIS5pZGVudGlmeVJlcXVlc3RzLnNoaWZ0KCk/LigpXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAoZ2F0ZXdheS5wcmVmZXJTbmFrZUNhc2UpIHtcbiAgICAgICAgICBzaGFyZC5mb3J3YXJkVG9Cb3QgPSBhc3luYyAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgc2hhcmQuZXZlbnRzPy5tZXNzYWdlPy4oc2hhcmQsIHBheWxvYWQpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZ2F0ZXdheS5yZXNoYXJkaW5nLnNoYXJkcy5zZXQoc2hhcmRJZCwgc2hhcmQpXG5cbiAgICAgICAgY29uc3QgYnVja2V0ID0gZ2F0ZXdheS5idWNrZXRzLmdldChzaGFyZElkICUgZ2F0ZXdheS5jb25uZWN0aW9uLnNlc3Npb25TdGFydExpbWl0Lm1heENvbmN1cnJlbmN5KVxuICAgICAgICBpZiAoIWJ1Y2tldCkgcmV0dXJuXG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgLy8gTWFyayB0aGF0IHdlIGFyZSBtYWtpbmcgYW4gaWRlbnRpZnkgcmVxdWVzdCBzbyBhbm90aGVyIGlzIG5vdCBtYWRlLlxuICAgICAgICAgIGJ1Y2tldC5pZGVudGlmeVJlcXVlc3RzLnB1c2gocmVzb2x2ZSlcbiAgICAgICAgICBsb2dnZXIuZGVidWcoYFtHYXRld2F5XSBpZGVudGlmeWluZyBzaGFyZCAjKCR7c2hhcmRJZH0pLmApXG4gICAgICAgICAgLy8gVGhpcyB3aWxsIHRyaWdnZXIgaWRlbnRpZnkgYW5kIHdoZW4gUkVBRFkgaXMgcmVjZWl2ZWQgaXQgd2lsbCByZXNvbHZlIHRoZSBhYm92ZSByZXF1ZXN0LlxuICAgICAgICAgIHNoYXJkPy5pZGVudGlmeSgpLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgLy8gVGVsbCB0aGUgbWFuYWdlciB0aGF0IHRoaXMgc2hhcmQgaXMgb25saW5lXG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgZ2F0ZXdheS5yZXNoYXJkaW5nLnNoYXJkSXNQZW5kaW5nKHNoYXJkKVxuICAgICAgICAgIH0pXG4gICAgICAgIH0pXG4gICAgICB9LFxuICAgICAgYXN5bmMgdXBkYXRlR3VpbGRzU2hhcmRJZChndWlsZElkcywgc2hhcmRJZCkge1xuICAgICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgICAgYFtSZXNoYXJkaW5nXSBVcGRhdGluZyB0aGUgZm9sbG93aW5nIGd1aWxkIGlkcyBzaGFyZCB0byAjJHtzaGFyZElkfTogJHtndWlsZElkcy5qb2luKCcsICcpfS4gT3ZlcnJpZGUgdGhpcyBmdW5jdGlvbiB0byB1cGRhdGUgeW91ciBjYWNoZSBpZiB5b3UgbmVlZCB0by5gLFxuICAgICAgICApXG4gICAgICB9LFxuICAgICAgYXN5bmMgc2hhcmRJc1BlbmRpbmcoc2hhcmQpIHtcbiAgICAgICAgLy8gU2F2ZSB0aGlzIGluIHBlbmRpbmcgYXQgdGhlIG1vbWVudCwgdW50aWwgYWxsIHNoYXJkcyBhcmUgb25saW5lXG4gICAgICAgIGdhdGV3YXkucmVzaGFyZGluZy5wZW5kaW5nU2hhcmRzLnNldChzaGFyZC5pZCwgc2hhcmQpXG4gICAgICAgIGxvZ2dlci53YXJuKGBbUmVzaGFyZGluZ10gU2hhcmQgIyR7c2hhcmQuaWR9IGlzIG5vdyBwZW5kaW5nYClcbiAgICAgICAgLy8gQ2hlY2sgaWYgYWxsIHNoYXJkcyBhcmUgbm93IG9ubGluZS5cbiAgICAgICAgaWYgKGdhdGV3YXkubGFzdFNoYXJkSWQgLSBnYXRld2F5LmZpcnN0U2hhcmRJZCArIDEgPiBnYXRld2F5LnJlc2hhcmRpbmcucGVuZGluZ1NoYXJkcy5zaXplKSByZXR1cm5cbiAgICAgICAgbG9nZ2VyLndhcm4oYFtSZXNoYXJkaW5nXSBBbGwgc2hhcmRzIGFyZSBub3cgb25saW5lLmApXG5cbiAgICAgICAgLy8gTmV3IHNoYXJkcyBzdGFydCBwcm9jZXNzaW5nIGV2ZW50c1xuICAgICAgICBmb3IgKGNvbnN0IHNoYXJkIG9mIGdhdGV3YXkucmVzaGFyZGluZy5wZW5kaW5nU2hhcmRzLnZhbHVlcygpKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBldmVudCBpbiBvcHRpb25zLmV2ZW50cykge1xuICAgICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBmaXhpbmcgdGhpcyBzZWVtcyBjb21wbGV4IGFuZCBkb2VzbnQgc2VlbSB3b3J0aCBpdCwgZmVlbCBmcmVlIHRvIGZpeCBpZiB5b3Ugd2lzaFxuICAgICAgICAgICAgc2hhcmQuZXZlbnRzW2V2ZW50XSA9IG9wdGlvbnMuZXZlbnRzW2V2ZW50XVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE9sZCBzaGFyZHMgc3RvcCBwcm9jZXNzaW5nIGV2ZW50c1xuICAgICAgICBmb3IgKGNvbnN0IHNoYXJkIG9mIGdhdGV3YXkuc2hhcmRzLnZhbHVlcygpKSB7XG4gICAgICAgICAgY29uc3Qgb2xkSGFuZGxlciA9IHNoYXJkLmV2ZW50cy5tZXNzYWdlXG5cbiAgICAgICAgICAvLyBDaGFuZ2Ugd2l0aCBzcHJlYWQgb3BlcmF0b3IgdG8gbm90IGFmZmVjdCBuZXcgc2hhcmRzLCBhcyBjaGFuZ2luZyBhbnl0aGluZyBvbiBzaGFyZC5ldmVudHMgd2lsbCBkaXJlY3RseSBjaGFuZ2Ugb3B0aW9ucy5ldmVudHMsIHdoaWNoIGNoYW5nZXMgbmV3IHNoYXJkcycgZXZlbnRzXG4gICAgICAgICAgc2hhcmQuZXZlbnRzID0ge1xuICAgICAgICAgICAgLi4uc2hhcmQuZXZlbnRzLFxuICAgICAgICAgICAgbWVzc2FnZTogYXN5bmMgZnVuY3Rpb24gKF8sIG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgLy8gTWVtYmVyIGNoZWNrcyBuZWVkIHRvIGNvbnRpbnVlIGJ1dCBvdGhlcnMgY2FuIHN0b3BcbiAgICAgICAgICAgICAgaWYgKG1lc3NhZ2UudCAhPT0gJ0dVSUxEX01FTUJFUlNfQ0hVTksnKSByZXR1cm5cbiAgICAgICAgICAgICAgLy8gUHJvY2VzcyBvbmx5IHRoZSBjaHVua2luZyBldmVudHNcbiAgICAgICAgICAgICAgb2xkSGFuZGxlcj8uKHNoYXJkLCBtZXNzYWdlKVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBsb2dnZXIud2FybihgW1Jlc2hhcmRpbmddIFNodXR0aW5nIGRvd24gb2xkIHNoYXJkcy5gKVxuICAgICAgICAvLyBDbG9zZSBvbGQgc2hhcmRzXG4gICAgICAgIGF3YWl0IGdhdGV3YXkuc2h1dGRvd24oU2hhcmRTb2NrZXRDbG9zZUNvZGVzLlJlc2hhcmRlZCwgJ1Jlc2hhcmRlZCEnLCBmYWxzZSlcbiAgICAgICAgbG9nZ2VyLndhcm4oYFtSZXNoYXJkaW5nXSBDb21wbGV0ZWQuYClcblxuICAgICAgICAvLyBSZXBsYWNlIG9sZCBzaGFyZHNcbiAgICAgICAgZ2F0ZXdheS5zaGFyZHMgPSBnYXRld2F5LnJlc2hhcmRpbmcuc2hhcmRzXG4gICAgICB9LFxuICAgIH0sXG5cbiAgICBjYWxjdWxhdGVUb3RhbFNoYXJkcygpIHtcbiAgICAgIC8vIEJvdHMgdW5kZXIgMTAwayBzZXJ2ZXJzIGRvIG5vdCBoYXZlIGFjY2VzcyB0byBMQlMuXG4gICAgICBpZiAoZ2F0ZXdheS50b3RhbFNoYXJkcyA8IDEwMCkge1xuICAgICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIENhbGN1bGF0aW5nIHRvdGFsIHNoYXJkczogJHtnYXRld2F5LnRvdGFsU2hhcmRzfWApXG4gICAgICAgIHJldHVybiBnYXRld2F5LnRvdGFsU2hhcmRzXG4gICAgICB9XG5cbiAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gQ2FsY3VsYXRpbmcgdG90YWwgc2hhcmRzYCwgZ2F0ZXdheS50b3RhbFNoYXJkcywgZ2F0ZXdheS5jb25uZWN0aW9uLnNlc3Npb25TdGFydExpbWl0Lm1heENvbmN1cnJlbmN5KVxuICAgICAgLy8gQ2FsY3VsYXRlIGEgbXVsdGlwbGUgb2YgYG1heENvbmN1cnJlbmN5YCB3aGljaCBjYW4gYmUgdXNlZCB0byBjb25uZWN0IHRvIHRoZSBnYXRld2F5LlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgTWF0aC5jZWlsKFxuICAgICAgICAgIGdhdGV3YXkudG90YWxTaGFyZHMgL1xuICAgICAgICAgICAgLy8gSWYgYG1heENvbmN1cnJlbmN5YCBpcyAxLCB3ZSBjYW4gc2FmZWx5IHVzZSAxNiB0byBnZXQgYHRvdGFsU2hhcmRzYCB0byBiZSBpbiBhIG11bHRpcGxlIG9mIDE2IHNvIHRoYXQgd2UgY2FuIHByZXBhcmUgYm90cyB3aXRoIDEwMGsgc2VydmVycyBmb3IgTEJTLlxuICAgICAgICAgICAgKGdhdGV3YXkuY29ubmVjdGlvbi5zZXNzaW9uU3RhcnRMaW1pdC5tYXhDb25jdXJyZW5jeSA9PT0gMSA/IDE2IDogZ2F0ZXdheS5jb25uZWN0aW9uLnNlc3Npb25TdGFydExpbWl0Lm1heENvbmN1cnJlbmN5KSxcbiAgICAgICAgKSAqIChnYXRld2F5LmNvbm5lY3Rpb24uc2Vzc2lvblN0YXJ0TGltaXQubWF4Q29uY3VycmVuY3kgPT09IDEgPyAxNiA6IGdhdGV3YXkuY29ubmVjdGlvbi5zZXNzaW9uU3RhcnRMaW1pdC5tYXhDb25jdXJyZW5jeSlcbiAgICAgIClcbiAgICB9LFxuICAgIGNhbGN1bGF0ZVdvcmtlcklkKHNoYXJkSWQpIHtcbiAgICAgIGNvbnN0IHdvcmtlcklkID0gTWF0aC5taW4oc2hhcmRJZCAlIGdhdGV3YXkuc2hhcmRzUGVyV29ya2VyLCBnYXRld2F5LnRvdGFsV29ya2VycyAtIDEpXG4gICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhcbiAgICAgICAgYFtHYXRld2F5XSBDYWxjdWxhdGluZyB3b3JrZXJJZDogU2hhcmQ6ICR7c2hhcmRJZH0gLT4gV29ya2VyOiAke3dvcmtlcklkfSAtPiBQZXIgV29ya2VyOiAke2dhdGV3YXkuc2hhcmRzUGVyV29ya2VyfSAtPiBUb3RhbDogJHtnYXRld2F5LnRvdGFsV29ya2Vyc31gLFxuICAgICAgKVxuICAgICAgcmV0dXJuIHdvcmtlcklkXG4gICAgfSxcbiAgICBwcmVwYXJlQnVja2V0cygpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZ2F0ZXdheS5jb25uZWN0aW9uLnNlc3Npb25TdGFydExpbWl0Lm1heENvbmN1cnJlbmN5OyArK2kpIHtcbiAgICAgICAgZ2F0ZXdheS5sb2dnZXIuZGVidWcoYFtHYXRld2F5XSBQcmVwYXJpbmcgYnVja2V0cyBmb3IgY29uY3VycmVuY3k6ICR7aX1gKVxuICAgICAgICBnYXRld2F5LmJ1Y2tldHMuc2V0KGksIHtcbiAgICAgICAgICB3b3JrZXJzOiBbXSxcbiAgICAgICAgICBpZGVudGlmeVJlcXVlc3RzOiBbXSxcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgLy8gT1JHQU5JWkUgQUxMIFNIQVJEUyBJTlRPIFRIRUlSIE9XTiBCVUNLRVRTXG4gICAgICBmb3IgKGxldCBzaGFyZElkID0gZ2F0ZXdheS5maXJzdFNoYXJkSWQ7IHNoYXJkSWQgPD0gZ2F0ZXdheS5sYXN0U2hhcmRJZDsgKytzaGFyZElkKSB7XG4gICAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gUHJlcGFyaW5nIGJ1Y2tldHMgZm9yIHNoYXJkOiAke3NoYXJkSWR9YClcbiAgICAgICAgaWYgKHNoYXJkSWQgPj0gZ2F0ZXdheS50b3RhbFNoYXJkcykge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU2hhcmQgKGlkOiAke3NoYXJkSWR9KSBpcyBiaWdnZXIgb3IgZXF1YWwgdG8gdGhlIHVzZWQgYW1vdW50IG9mIHVzZWQgc2hhcmRzIHdoaWNoIGlzICR7Z2F0ZXdheS50b3RhbFNoYXJkc31gKVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYnVja2V0SWQgPSBzaGFyZElkICUgZ2F0ZXdheS5jb25uZWN0aW9uLnNlc3Npb25TdGFydExpbWl0Lm1heENvbmN1cnJlbmN5XG4gICAgICAgIGNvbnN0IGJ1Y2tldCA9IGdhdGV3YXkuYnVja2V0cy5nZXQoYnVja2V0SWQpXG4gICAgICAgIGlmICghYnVja2V0KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYFNoYXJkIChpZDogJHtzaGFyZElkfSkgZ290IGFzc2lnbmVkIHRvIGFuIGlsbGVnYWwgYnVja2V0IGlkOiAke2J1Y2tldElkfSwgZXhwZWN0ZWQgYSBidWNrZXQgaWQgYmV0d2VlbiAwIGFuZCAke1xuICAgICAgICAgICAgICBnYXRld2F5LmNvbm5lY3Rpb24uc2Vzc2lvblN0YXJ0TGltaXQubWF4Q29uY3VycmVuY3kgLSAxXG4gICAgICAgICAgICB9YCxcbiAgICAgICAgICApXG4gICAgICAgIH1cblxuICAgICAgICAvLyBGSU5EIEEgUVVFVUUgSU4gVEhJUyBCVUNLRVQgVEhBVCBIQVMgU1BBQ0VcbiAgICAgICAgLy8gY29uc3Qgd29ya2VyID0gYnVja2V0LndvcmtlcnMuZmluZCgodykgPT4gdy5xdWV1ZS5sZW5ndGggPCBnYXRld2F5LnNoYXJkc1Blcldvcmtlcik7XG4gICAgICAgIGNvbnN0IHdvcmtlcklkID0gZ2F0ZXdheS5jYWxjdWxhdGVXb3JrZXJJZChzaGFyZElkKVxuICAgICAgICBjb25zdCB3b3JrZXIgPSBidWNrZXQud29ya2Vycy5maW5kKCh3KSA9PiB3LmlkID09PSB3b3JrZXJJZClcbiAgICAgICAgaWYgKHdvcmtlcikge1xuICAgICAgICAgIC8vIElGIFRIRSBRVUVVRSBIQVMgU1BBQ0UgSlVTVCBBREQgSVQgVE8gVEhJUyBRVUVVRVxuICAgICAgICAgIHdvcmtlci5xdWV1ZS5wdXNoKHNoYXJkSWQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYnVja2V0LndvcmtlcnMucHVzaCh7IGlkOiB3b3JrZXJJZCwgcXVldWU6IFtzaGFyZElkXSB9KVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgYnVja2V0IG9mIGdhdGV3YXkuYnVja2V0cy52YWx1ZXMoKSkge1xuICAgICAgICBmb3IgKGNvbnN0IHdvcmtlciBvZiBidWNrZXQud29ya2Vycy52YWx1ZXMoKSkge1xuICAgICAgICAgIHdvcmtlci5xdWV1ZSA9IHdvcmtlci5xdWV1ZS5zb3J0KChhLCBiKSA9PiBhIC0gYilcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgc3Bhd25TaGFyZHMoKSB7XG4gICAgICAvLyBQUkVQQVJFUyBBTEwgU0hBUkRTIElOIFNQRUNJRklDIEJVQ0tFVFNcbiAgICAgIGdhdGV3YXkucHJlcGFyZUJ1Y2tldHMoKVxuXG4gICAgICAvLyBQcmVmZXIgY29uY3VycmVuY3kgb2YgZm9yRWFjaCBpbnN0ZWFkIG9mIGZvcm9mXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgWy4uLmdhdGV3YXkuYnVja2V0cy5lbnRyaWVzKCldLm1hcChhc3luYyAoW2J1Y2tldElkLCBidWNrZXRdKSA9PiB7XG4gICAgICAgICAgZm9yIChjb25zdCB3b3JrZXIgb2YgYnVja2V0LndvcmtlcnMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qgc2hhcmRJZCBvZiB3b3JrZXIucXVldWUpIHtcbiAgICAgICAgICAgICAgYXdhaXQgZ2F0ZXdheS50ZWxsV29ya2VyVG9JZGVudGlmeSh3b3JrZXIuaWQsIHNoYXJkSWQsIGJ1Y2tldElkKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICApXG5cbiAgICAgIC8vIENoZWNrIGFuZCByZXNoYXJkIGF1dG9tYXRpY2FsbHkgaWYgYXV0byByZXNoYXJkaW5nIGlzIGVuYWJsZWQuXG4gICAgICBpZiAoZ2F0ZXdheS5yZXNoYXJkaW5nLmVuYWJsZWQgJiYgZ2F0ZXdheS5yZXNoYXJkaW5nLmNoZWNrSW50ZXJ2YWwgIT09IC0xKSB7XG4gICAgICAgIGdhdGV3YXkucmVzaGFyZGluZy5jaGVja0ludGVydmFsSWQgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgcmVzaGFyZGluZ0luZm8gPSBhd2FpdCBnYXRld2F5LnJlc2hhcmRpbmcuY2hlY2tJZlJlc2hhcmRpbmdJc05lZWRlZCgpXG5cbiAgICAgICAgICBpZiAocmVzaGFyZGluZ0luZm8ubmVlZGVkICYmIHJlc2hhcmRpbmdJbmZvLmluZm8pIGF3YWl0IGdhdGV3YXkucmVzaGFyZGluZy5yZXNoYXJkKHJlc2hhcmRpbmdJbmZvLmluZm8pXG4gICAgICAgIH0sIGdhdGV3YXkucmVzaGFyZGluZy5jaGVja0ludGVydmFsKVxuICAgICAgfVxuICAgIH0sXG4gICAgYXN5bmMgc2h1dGRvd24oY29kZSwgcmVhc29uLCBjbGVhclJlc2hhcmRpbmdJbnRlcnZhbCA9IHRydWUpIHtcbiAgICAgIGdhdGV3YXkuc2hhcmRzLmZvckVhY2goKHNoYXJkKSA9PiBzaGFyZC5jbG9zZShjb2RlLCByZWFzb24pKVxuXG4gICAgICBpZiAoY2xlYXJSZXNoYXJkaW5nSW50ZXJ2YWwgJiYgZ2F0ZXdheS5yZXNoYXJkaW5nLmNoZWNrSW50ZXJ2YWxJZCkgY2xlYXJJbnRlcnZhbChnYXRld2F5LnJlc2hhcmRpbmcuY2hlY2tJbnRlcnZhbElkKVxuXG4gICAgICBhd2FpdCBkZWxheSg1MDAwKVxuICAgIH0sXG4gICAgYXN5bmMgc2VuZFBheWxvYWQoc2hhcmRJZCwgcGF5bG9hZCkge1xuICAgICAgY29uc3Qgc2hhcmQgPSBnYXRld2F5LnNoYXJkcy5nZXQoc2hhcmRJZClcblxuICAgICAgaWYgKCFzaGFyZCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNoYXJkIChpZDogJHtzaGFyZElkfSBub3QgZm91bmRgKVxuICAgICAgfVxuXG4gICAgICBhd2FpdCBzaGFyZC5zZW5kKHBheWxvYWQpXG4gICAgfSxcbiAgICBhc3luYyB0ZWxsV29ya2VyVG9JZGVudGlmeSh3b3JrZXJJZCwgc2hhcmRJZCwgYnVja2V0SWQpIHtcbiAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gdGVsbCB3b3JrZXIgdG8gaWRlbnRpZnkgKCR7d29ya2VySWR9LCAke3NoYXJkSWR9LCAke2J1Y2tldElkfSlgKVxuICAgICAgYXdhaXQgZ2F0ZXdheS5pZGVudGlmeShzaGFyZElkKVxuICAgIH0sXG4gICAgYXN5bmMgaWRlbnRpZnkoc2hhcmRJZDogbnVtYmVyKSB7XG4gICAgICBsZXQgc2hhcmQgPSB0aGlzLnNoYXJkcy5nZXQoc2hhcmRJZClcbiAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gaWRlbnRpZnlpbmcgJHtzaGFyZCA/ICdleGlzdGluZycgOiAnbmV3J30gc2hhcmQgKCR7c2hhcmRJZH0pYClcblxuICAgICAgaWYgKCFzaGFyZCkge1xuICAgICAgICBzaGFyZCA9IG5ldyBTaGFyZCh7XG4gICAgICAgICAgaWQ6IHNoYXJkSWQsXG4gICAgICAgICAgY29ubmVjdGlvbjoge1xuICAgICAgICAgICAgY29tcHJlc3M6IHRoaXMuY29tcHJlc3MsXG4gICAgICAgICAgICBpbnRlbnRzOiB0aGlzLmludGVudHMsXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB0aGlzLnByb3BlcnRpZXMsXG4gICAgICAgICAgICB0b2tlbjogdGhpcy50b2tlbixcbiAgICAgICAgICAgIHRvdGFsU2hhcmRzOiB0aGlzLnRvdGFsU2hhcmRzLFxuICAgICAgICAgICAgdXJsOiB0aGlzLnVybCxcbiAgICAgICAgICAgIHZlcnNpb246IHRoaXMudmVyc2lvbixcbiAgICAgICAgICB9LFxuICAgICAgICAgIGV2ZW50czogb3B0aW9ucy5ldmVudHMgPz8ge30sXG4gICAgICAgICAgbG9nZ2VyOiB0aGlzLmxvZ2dlcixcbiAgICAgICAgICByZXF1ZXN0SWRlbnRpZnk6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGdhdGV3YXkuaWRlbnRpZnkoc2hhcmRJZClcbiAgICAgICAgICB9LFxuICAgICAgICAgIHNoYXJkSXNSZWFkeTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgZ2F0ZXdheS5sb2dnZXIuZGVidWcoYFtTaGFyZF0gU2hhcmQgIyR7c2hhcmRJZH0gaXMgcmVhZHlgKVxuICAgICAgICAgICAgYXdhaXQgZGVsYXkoZ2F0ZXdheS5zcGF3blNoYXJkRGVsYXkpXG4gICAgICAgICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW1NoYXJkXSBSZXNvbHZpbmcgc2hhcmQgaWRlbnRpZnkgcmVxdWVzdGApXG4gICAgICAgICAgICBnYXRld2F5LmJ1Y2tldHMuZ2V0KHNoYXJkSWQgJSBnYXRld2F5LmNvbm5lY3Rpb24uc2Vzc2lvblN0YXJ0TGltaXQubWF4Q29uY3VycmVuY3kpIS5pZGVudGlmeVJlcXVlc3RzLnNoaWZ0KCk/LigpXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAodGhpcy5wcmVmZXJTbmFrZUNhc2UpIHtcbiAgICAgICAgICBzaGFyZC5mb3J3YXJkVG9Cb3QgPSBhc3luYyAocGF5bG9hZCkgPT4ge1xuICAgICAgICAgICAgc2hhcmQhLmV2ZW50cy5tZXNzYWdlPy4oc2hhcmQhLCBwYXlsb2FkKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2hhcmRzLnNldChzaGFyZElkLCBzaGFyZClcbiAgICAgIH1cblxuICAgICAgY29uc3QgYnVja2V0ID0gZ2F0ZXdheS5idWNrZXRzLmdldChzaGFyZElkICUgZ2F0ZXdheS5jb25uZWN0aW9uLnNlc3Npb25TdGFydExpbWl0Lm1heENvbmN1cnJlbmN5KVxuICAgICAgaWYgKCFidWNrZXQpIHJldHVyblxuXG4gICAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgLy8gTWFyayB0aGF0IHdlIGFyZSBtYWtpbmcgYW4gaWRlbnRpZnkgcmVxdWVzdCBzbyBhbm90aGVyIGlzIG5vdCBtYWRlLlxuICAgICAgICBidWNrZXQuaWRlbnRpZnlSZXF1ZXN0cy5wdXNoKHJlc29sdmUpXG4gICAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gaWRlbnRpZnlpbmcgc2hhcmQgIygke3NoYXJkSWR9KS5gKVxuICAgICAgICAvLyBUaGlzIHdpbGwgdHJpZ2dlciBpZGVudGlmeSBhbmQgd2hlbiBSRUFEWSBpcyByZWNlaXZlZCBpdCB3aWxsIHJlc29sdmUgdGhlIGFib3ZlIHJlcXVlc3QuXG4gICAgICAgIHNoYXJkPy5pZGVudGlmeSgpXG4gICAgICB9KVxuICAgIH0sXG4gICAgYXN5bmMga2lsbChzaGFyZElkOiBudW1iZXIpIHtcbiAgICAgIGNvbnN0IHNoYXJkID0gdGhpcy5zaGFyZHMuZ2V0KHNoYXJkSWQpXG4gICAgICBpZiAoIXNoYXJkKSB7XG4gICAgICAgIHJldHVybiBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIGtpbGwgc2hhcmQgYnV0IG5vdCBmb3VuZCAoJHtzaGFyZElkfSlgKVxuICAgICAgfVxuXG4gICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIGtpbGwgc2hhcmQgKCR7c2hhcmRJZH0pYClcbiAgICAgIHRoaXMuc2hhcmRzLmRlbGV0ZShzaGFyZElkKVxuICAgICAgYXdhaXQgc2hhcmQuc2h1dGRvd24oKVxuICAgIH0sXG4gICAgYXN5bmMgcmVxdWVzdElkZW50aWZ5KF9zaGFyZElkOiBudW1iZXIpIHtcbiAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gcmVxdWVzdGluZyBpZGVudGlmeWApXG4gICAgICAvLyBjb25zdCBidWNrZXQgPSBnYXRld2F5LmJ1Y2tldHMuZ2V0KHNoYXJkSWQgJSBnYXRld2F5LmNvbm5lY3Rpb24uc2Vzc2lvblN0YXJ0TGltaXQubWF4Q29uY3VycmVuY3kpXG4gICAgICAvLyBpZiAoIWJ1Y2tldCkgcmV0dXJuXG5cbiAgICAgIC8vIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgLy8gICBidWNrZXQuaWRlbnRpZnlSZXF1ZXN0cy5wdXNoKHJlc29sdmUpXG4gICAgICAvLyB9KVxuICAgIH0sXG5cbiAgICAvLyBIZWxwZXJzIG1ldGhvZHMgYmVsb3cgdGhpc1xuXG4gICAgY2FsY3VsYXRlU2hhcmRJZChndWlsZElkLCB0b3RhbFNoYXJkcykge1xuICAgICAgLy8gSWYgbm9uZSBpcyBwcm92aWRlZCwgdXNlIHRoZSB0b3RhbCBzaGFyZHMgbnVtYmVyIGZyb20gZ2F0ZXdheSBvYmplY3QuXG4gICAgICBpZiAoIXRvdGFsU2hhcmRzKSB0b3RhbFNoYXJkcyA9IGdhdGV3YXkudG90YWxTaGFyZHNcbiAgICAgIC8vIElmIGl0IGlzIG9ubHkgMSBzaGFyZCwgaXQgd2lsbCBhbHdheXMgYmUgc2hhcmQgaWQgMFxuICAgICAgaWYgKHRvdGFsU2hhcmRzID09PSAxKSB7XG4gICAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gY2FsY3VsYXRlU2hhcmRJZCAoMSBzaGFyZClgKVxuICAgICAgICByZXR1cm4gMFxuICAgICAgfVxuXG4gICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIGNhbGN1bGF0ZVNoYXJkSWQgKGd1aWxkSWQ6ICR7Z3VpbGRJZH0sIHRvdGFsU2hhcmRzOiAke3RvdGFsU2hhcmRzfSlgKVxuICAgICAgcmV0dXJuIE51bWJlcigoQmlnSW50KGd1aWxkSWQpID4+IDIybikgJSBCaWdJbnQodG90YWxTaGFyZHMpKVxuICAgIH0sXG5cbiAgICBhc3luYyBqb2luVm9pY2VDaGFubmVsKGd1aWxkSWQsIGNoYW5uZWxJZCwgb3B0aW9ucykge1xuICAgICAgY29uc3Qgc2hhcmRJZCA9IGdhdGV3YXkuY2FsY3VsYXRlU2hhcmRJZChndWlsZElkKVxuXG4gICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIGpvaW5Wb2ljZUNoYW5uZWwgZ3VpbGRJZDogJHtndWlsZElkfSBjaGFubmVsSWQ6ICR7Y2hhbm5lbElkfWApXG5cbiAgICAgIGF3YWl0IGdhdGV3YXkuc2VuZFBheWxvYWQoc2hhcmRJZCwge1xuICAgICAgICBvcDogR2F0ZXdheU9wY29kZXMuVm9pY2VTdGF0ZVVwZGF0ZSxcbiAgICAgICAgZDoge1xuICAgICAgICAgIGd1aWxkX2lkOiBndWlsZElkLnRvU3RyaW5nKCksXG4gICAgICAgICAgY2hhbm5lbF9pZDogY2hhbm5lbElkLnRvU3RyaW5nKCksXG4gICAgICAgICAgc2VsZl9tdXRlOiBvcHRpb25zPy5zZWxmTXV0ZSA/PyBmYWxzZSxcbiAgICAgICAgICBzZWxmX2RlYWY6IG9wdGlvbnM/LnNlbGZEZWFmID8/IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH0sXG5cbiAgICBhc3luYyBlZGl0Qm90U3RhdHVzKGRhdGEpIHtcbiAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gZWRpdEJvdFN0YXR1cyBkYXRhOiAke0pTT04uc3RyaW5naWZ5KGRhdGEpfWApXG5cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBbLi4uZ2F0ZXdheS5zaGFyZHMudmFsdWVzKCldLm1hcChhc3luYyAoc2hhcmQpID0+IHtcbiAgICAgICAgICBnYXRld2F5LmVkaXRTaGFyZFN0YXR1cyhzaGFyZC5pZCwgZGF0YSlcbiAgICAgICAgfSksXG4gICAgICApXG4gICAgfSxcblxuICAgIGFzeW5jIGVkaXRTaGFyZFN0YXR1cyhzaGFyZElkLCBkYXRhKSB7XG4gICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIGVkaXRTaGFyZFN0YXR1cyBzaGFyZElkOiAke3NoYXJkSWR9IC0+IGRhdGE6ICR7SlNPTi5zdHJpbmdpZnkoZGF0YSl9YClcblxuICAgICAgYXdhaXQgZ2F0ZXdheS5zZW5kUGF5bG9hZChzaGFyZElkLCB7XG4gICAgICAgIG9wOiBHYXRld2F5T3Bjb2Rlcy5QcmVzZW5jZVVwZGF0ZSxcbiAgICAgICAgZDoge1xuICAgICAgICAgIHNpbmNlOiBudWxsLFxuICAgICAgICAgIGFmazogZmFsc2UsXG4gICAgICAgICAgYWN0aXZpdGllczogZGF0YS5hY3Rpdml0aWVzLFxuICAgICAgICAgIHN0YXR1czogZGF0YS5zdGF0dXMsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH0sXG5cbiAgICBhc3luYyByZXF1ZXN0TWVtYmVycyhndWlsZElkLCBvcHRpb25zKSB7XG4gICAgICBjb25zdCBzaGFyZElkID0gZ2F0ZXdheS5jYWxjdWxhdGVTaGFyZElkKGd1aWxkSWQpXG5cbiAgICAgIGlmIChnYXRld2F5LmludGVudHMgJiYgKCFvcHRpb25zPy5saW1pdCB8fCBvcHRpb25zLmxpbWl0ID4gMSkgJiYgIShnYXRld2F5LmludGVudHMgJiBHYXRld2F5SW50ZW50cy5HdWlsZE1lbWJlcnMpKVxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBmZXRjaCBtb3JlIHRoZW4gMSBtZW1iZXIgd2l0aG91dCB0aGUgR1VJTERfTUVNQkVSUyBpbnRlbnQnKVxuXG4gICAgICBnYXRld2F5LmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIHJlcXVlc3RNZW1iZXJzIGd1aWxkSWQ6ICR7Z3VpbGRJZH0gLT4gZGF0YTogJHtKU09OLnN0cmluZ2lmeShvcHRpb25zKX1gKVxuXG4gICAgICBpZiAob3B0aW9ucz8udXNlcklkcz8ubGVuZ3RoKSB7XG4gICAgICAgIGdhdGV3YXkubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gcmVxdWVzdE1lbWJlcnMgZ3VpbGRJZDogJHtndWlsZElkfSAtPiBzZXR0aW5nIHVzZXIgbGltaXQgYmFzZWQgb24gdXNlcklkcyBsZW5ndGg6ICR7b3B0aW9ucy51c2VySWRzLmxlbmd0aH1gKVxuXG4gICAgICAgIG9wdGlvbnMubGltaXQgPSBvcHRpb25zLnVzZXJJZHMubGVuZ3RoXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1lbWJlcnMgPVxuICAgICAgICAhZ2F0ZXdheS5jYWNoZS5yZXF1ZXN0TWVtYmVycy5lbmFibGVkIHx8ICFvcHRpb25zPy5ub25jZVxuICAgICAgICAgID8gW11cbiAgICAgICAgICA6IG5ldyBQcm9taXNlPENhbWVsaXplPERpc2NvcmRNZW1iZXJXaXRoVXNlcltdPj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAvLyBTaG91bGQgbmV2ZXIgaGFwcGVuLlxuICAgICAgICAgICAgICBpZiAoIWdhdGV3YXkuY2FjaGUucmVxdWVzdE1lbWJlcnMuZW5hYmxlZCB8fCAhb3B0aW9ucz8ubm9uY2UpIHtcbiAgICAgICAgICAgICAgICByZWplY3QobmV3IEVycm9yKFwiQ2FuJ3QgcmVxdWVzdCB0aGUgbWVtYmVycyB3aXRob3V0IHRoZSBub25jZSBvciB3aXRoIHRoZSBmZWF0dXJlIGRpc2FibGVkLlwiKSlcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGdhdGV3YXkuY2FjaGUucmVxdWVzdE1lbWJlcnMucGVuZGluZy5zZXQob3B0aW9ucy5ub25jZSwge1xuICAgICAgICAgICAgICAgIG5vbmNlOiBvcHRpb25zLm5vbmNlLFxuICAgICAgICAgICAgICAgIHJlc29sdmUsXG4gICAgICAgICAgICAgICAgbWVtYmVyczogW10sXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICB9KVxuXG4gICAgICBhd2FpdCBnYXRld2F5LnNlbmRQYXlsb2FkKHNoYXJkSWQsIHtcbiAgICAgICAgb3A6IEdhdGV3YXlPcGNvZGVzLlJlcXVlc3RHdWlsZE1lbWJlcnMsXG4gICAgICAgIGQ6IHtcbiAgICAgICAgICBndWlsZF9pZDogZ3VpbGRJZC50b1N0cmluZygpLFxuICAgICAgICAgIC8vIElmIGEgcXVlcnkgaXMgcHJvdmlkZWQgdXNlIGl0LCBPUiBpZiBhIGxpbWl0IGlzIE5PVCBwcm92aWRlZCB1c2UgXCJcIlxuICAgICAgICAgIHF1ZXJ5OiBvcHRpb25zPy5xdWVyeSA/PyAob3B0aW9ucz8ubGltaXQgPyB1bmRlZmluZWQgOiAnJyksXG4gICAgICAgICAgbGltaXQ6IG9wdGlvbnM/LmxpbWl0ID8/IDAsXG4gICAgICAgICAgcHJlc2VuY2VzOiBvcHRpb25zPy5wcmVzZW5jZXMgPz8gZmFsc2UsXG4gICAgICAgICAgdXNlcl9pZHM6IG9wdGlvbnM/LnVzZXJJZHM/Lm1hcCgoaWQpID0+IGlkLnRvU3RyaW5nKCkpLFxuICAgICAgICAgIG5vbmNlOiBvcHRpb25zPy5ub25jZSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiBhd2FpdCBtZW1iZXJzXG4gICAgfSxcblxuICAgIGFzeW5jIGxlYXZlVm9pY2VDaGFubmVsKGd1aWxkSWQpIHtcbiAgICAgIGNvbnN0IHNoYXJkSWQgPSBnYXRld2F5LmNhbGN1bGF0ZVNoYXJkSWQoZ3VpbGRJZClcblxuICAgICAgZ2F0ZXdheS5sb2dnZXIuZGVidWcoYFtHYXRld2F5XSBsZWF2ZVZvaWNlQ2hhbm5lbCBndWlsZElkOiAke2d1aWxkSWR9IFNoYXJkICR7c2hhcmRJZH1gKVxuXG4gICAgICBhd2FpdCBnYXRld2F5LnNlbmRQYXlsb2FkKHNoYXJkSWQsIHtcbiAgICAgICAgb3A6IEdhdGV3YXlPcGNvZGVzLlZvaWNlU3RhdGVVcGRhdGUsXG4gICAgICAgIGQ6IHtcbiAgICAgICAgICBndWlsZF9pZDogZ3VpbGRJZC50b1N0cmluZygpLFxuICAgICAgICAgIGNoYW5uZWxfaWQ6IG51bGwsXG4gICAgICAgICAgc2VsZl9tdXRlOiBmYWxzZSxcbiAgICAgICAgICBzZWxmX2RlYWY6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9LFxuICB9XG5cbiAgcmV0dXJuIGdhdGV3YXlcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVHYXRld2F5TWFuYWdlck9wdGlvbnMge1xuICAvKipcbiAgICogSWQgb2YgdGhlIGZpcnN0IFNoYXJkIHdoaWNoIHNob3VsZCBnZXQgY29udHJvbGxlZCBieSB0aGlzIG1hbmFnZXIuXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIGZpcnN0U2hhcmRJZD86IG51bWJlclxuICAvKipcbiAgICogSWQgb2YgdGhlIGxhc3QgU2hhcmQgd2hpY2ggc2hvdWxkIGdldCBjb250cm9sbGVkIGJ5IHRoaXMgbWFuYWdlci5cbiAgICogQGRlZmF1bHQgMFxuICAgKi9cbiAgbGFzdFNoYXJkSWQ/OiBudW1iZXJcbiAgLyoqXG4gICAqIERlbGF5IGluIG1pbGxpc2Vjb25kcyB0byB3YWl0IGJlZm9yZSBzcGF3bmluZyBuZXh0IHNoYXJkLiBPUFRJTUFMIElTIEFCT1ZFIDUxMDAuIFlPVSBET04nVCBXQU5UIFRPIEhJVCBUSEUgUkFURSBMSU1JVCEhIVxuICAgKiBAZGVmYXVsdCA1MzAwXG4gICAqL1xuICBzcGF3blNoYXJkRGVsYXk/OiBudW1iZXJcbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc2VuZCB0aGUgZGlzY29yZCBwYWNrZXRzIGluIHNuYWtlIGNhc2UgZm9ybS5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHByZWZlclNuYWtlQ2FzZT86IGJvb2xlYW5cbiAgLyoqXG4gICAqIFRvdGFsIGFtb3VudCBvZiBzaGFyZHMgeW91ciBib3QgdXNlcy4gVXNlZnVsIGZvciB6ZXJvLWRvd250aW1lIHVwZGF0ZXMgb3IgcmVzaGFyZGluZy5cbiAgICogQGRlZmF1bHQgMVxuICAgKi9cbiAgdG90YWxTaGFyZHM/OiBudW1iZXJcbiAgLyoqXG4gICAqIFRoZSBhbW91bnQgb2Ygc2hhcmRzIHRvIGxvYWQgcGVyIHdvcmtlci5cbiAgICogQGRlZmF1bHQgMjVcbiAgICovXG4gIHNoYXJkc1Blcldvcmtlcj86IG51bWJlclxuICAvKipcbiAgICogVGhlIHRvdGFsIGFtb3VudCBvZiB3b3JrZXJzIHRvIHVzZSBmb3IgeW91ciBib3QuXG4gICAqIEBkZWZhdWx0IDRcbiAgICovXG4gIHRvdGFsV29ya2Vycz86IG51bWJlclxuICAvKiogSW1wb3J0YW50IGRhdGEgd2hpY2ggaXMgdXNlZCBieSB0aGUgbWFuYWdlciB0byBjb25uZWN0IHNoYXJkcyB0byB0aGUgZ2F0ZXdheS4gKi9cbiAgY29ubmVjdGlvbj86IENhbWVsaXplPERpc2NvcmRHZXRHYXRld2F5Qm90PlxuICAvKiogV2hldGhlciBpbmNvbWluZyBwYXlsb2FkcyBhcmUgY29tcHJlc3NlZCB1c2luZyB6bGliLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgY29tcHJlc3M/OiBib29sZWFuXG4gIC8qKiBUaGUgY2FsY3VsYXRlZCBpbnRlbnQgdmFsdWUgb2YgdGhlIGV2ZW50cyB3aGljaCB0aGUgc2hhcmQgc2hvdWxkIHJlY2VpdmUuXG4gICAqXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIGludGVudHM/OiBudW1iZXJcbiAgLyoqIElkZW50aWZ5IHByb3BlcnRpZXMgdG8gdXNlICovXG4gIHByb3BlcnRpZXM/OiB7XG4gICAgLyoqIE9wZXJhdGluZyBzeXN0ZW0gdGhlIHNoYXJkIHJ1bnMgb24uXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCBcImRhcndpblwiIHwgXCJsaW51eFwiIHwgXCJ3aW5kb3dzXCJcbiAgICAgKi9cbiAgICBvczogc3RyaW5nXG4gICAgLyoqIFRoZSBcImJyb3dzZXJcIiB3aGVyZSB0aGlzIHNoYXJkIGlzIHJ1bm5pbmcgb24uXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCBcIkRpc2NvcmRlbm9cIlxuICAgICAqL1xuICAgIGJyb3dzZXI6IHN0cmluZ1xuICAgIC8qKiBUaGUgZGV2aWNlIG9uIHdoaWNoIHRoZSBzaGFyZCBpcyBydW5uaW5nLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgXCJEaXNjb3JkZW5vXCJcbiAgICAgKi9cbiAgICBkZXZpY2U6IHN0cmluZ1xuICB9XG4gIC8qKiBCb3QgdG9rZW4gd2hpY2ggaXMgdXNlZCB0byBjb25uZWN0IHRvIERpc2NvcmQgKi9cbiAgdG9rZW46IHN0cmluZ1xuICAvKiogVGhlIFVSTCBvZiB0aGUgZ2F0ZXdheSB3aGljaCBzaG91bGQgYmUgY29ubmVjdGVkIHRvLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIndzczovL2dhdGV3YXkuZGlzY29yZC5nZ1wiXG4gICAqL1xuICB1cmw/OiBzdHJpbmdcbiAgLyoqIFRoZSBnYXRld2F5IHZlcnNpb24gd2hpY2ggc2hvdWxkIGJlIHVzZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEwXG4gICAqL1xuICB2ZXJzaW9uPzogbnVtYmVyXG4gIC8qKiBUaGUgZXZlbnRzIGhhbmRsZXJzICovXG4gIGV2ZW50cz86IFNoYXJkRXZlbnRzXG4gIC8qKiBUaGlzIG1hbmFnZXJzIGNhY2hlIHJlbGF0ZWQgc2V0dGluZ3MuICovXG4gIGNhY2hlPzoge1xuICAgIHJlcXVlc3RNZW1iZXJzPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBXaGV0aGVyIG9yIG5vdCByZXF1ZXN0IG1lbWJlciByZXF1ZXN0cyBzaG91bGQgYmUgY2FjaGVkLlxuICAgICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgICAqL1xuICAgICAgZW5hYmxlZD86IGJvb2xlYW5cbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIFRoZSBsb2dnZXIgdGhhdCB0aGUgZ2F0ZXdheSBtYW5hZ2VyIHdpbGwgdXNlXG4gICAqIEBkZWZhdWx0IGxvZ2dlciAvLyBUaGUgbG9nZ2VyIGV4cG9ydGVkIGJ5IGBAZGlzY29yZGVuby91dGlsc2BcbiAgICovXG4gIGxvZ2dlcj86IFBpY2s8dHlwZW9mIGxvZ2dlciwgJ2RlYnVnJyB8ICdpbmZvJyB8ICd3YXJuJyB8ICdlcnJvcicgfCAnZmF0YWwnPlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdhdGV3YXlNYW5hZ2VyIGV4dGVuZHMgUmVxdWlyZWQ8Q3JlYXRlR2F0ZXdheU1hbmFnZXJPcHRpb25zPiB7XG4gIC8qKiBUaGUgbWF4IGNvbmN1cnJlbmN5IGJ1Y2tldHMuIFRob3NlIHdpbGwgYmUgY3JlYXRlZCB3aGVuIHRoZSBgc3Bhd25TaGFyZHNgICh3aGljaCBjYWxscyBgcHJlcGFyZUJ1Y2tldHNgIHVuZGVyIHRoZSBob29kKSBmdW5jdGlvbiBnZXRzIGNhbGxlZC4gKi9cbiAgYnVja2V0czogTWFwPFxuICAgIG51bWJlcixcbiAgICB7XG4gICAgICB3b3JrZXJzOiBBcnJheTx7IGlkOiBudW1iZXI7IHF1ZXVlOiBudW1iZXJbXSB9PlxuICAgICAgLyoqIFJlcXVlc3RzIHRvIGlkZW50aWZ5IHNoYXJkcyBhcmUgbWFkZSBiYXNlZCBvbiB3aGV0aGVyIGl0IGlzIGF2YWlsYWJsZSB0byBiZSBtYWRlLiAqL1xuICAgICAgaWRlbnRpZnlSZXF1ZXN0czogQXJyYXk8KHZhbHVlOiB2b2lkIHwgUHJvbWlzZUxpa2U8dm9pZD4pID0+IHZvaWQ+XG4gICAgfVxuICA+XG4gIC8qKiBUaGUgc2hhcmRzIHRoYXQgYXJlIGNyZWF0ZWQuICovXG4gIHNoYXJkczogTWFwPG51bWJlciwgU2hhcmQ+XG4gIC8qKiBUaGUgbG9nZ2VyIGZvciB0aGUgZ2F0ZXdheSBtYW5hZ2VyICovXG4gIGxvZ2dlcjogUGljazx0eXBlb2YgbG9nZ2VyLCAnZGVidWcnIHwgJ2luZm8nIHwgJ3dhcm4nIHwgJ2Vycm9yJyB8ICdmYXRhbCc+XG4gIC8qKiBFdmVyeXRoaW5nIHJlbGF0ZWQgdG8gcmVzaGFyZGluZy4gKi9cbiAgcmVzaGFyZGluZzoge1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgb3Igbm90IGF1dG9tYXRlZCByZXNoYXJkaW5nIHNob3VsZCBiZSBlbmFibGVkLlxuICAgICAqIEBkZWZhdWx0IHRydWVcbiAgICAgKi9cbiAgICBlbmFibGVkOiBib29sZWFuXG4gICAgLyoqXG4gICAgICogVGhlICUgb2YgaG93IGZ1bGwgYSBzaGFyZCBpcyB3aGVuIHJlc2hhcmRpbmcgc2hvdWxkIGJlIHRyaWdnZXJlZC5cbiAgICAgKiBAZGVmYXVsdCA4MCBhcyBpbiA4MCVcbiAgICAgKi9cbiAgICBzaGFyZHNGdWxsUGVyY2VudGFnZTogbnVtYmVyXG4gICAgLyoqXG4gICAgICogVGhlIGludGVydmFsIGluIG1pbGxpc2Vjb25kcywgb2YgaG93IG9mdGVuIHRvIGNoZWNrIHdoZXRoZXIgcmVzaGFyZGluZyBpcyBuZWVkZWQgYW5kIHJlc2hhcmQgYXV0b21hdGljYWxseS4gU2V0IHRvIC0xIHRvIGRpc2FibGUgYXV0byByZXNoYXJkaW5nLlxuICAgICAqIEBkZWZhdWx0IDI4ODAwMDAwICg4IGhvdXJzKVxuICAgICAqL1xuICAgIGNoZWNrSW50ZXJ2YWw6IG51bWJlclxuICAgIC8qKlxuICAgICAqIFRoZSBpbnRlcnZhbCBpZCBvZiB0aGUgY2hlY2sgaW50ZXJ2YWwuIFRoaXMgaXMgdXNlZCB0byBjbGVhciB0aGUgaW50ZXJ2YWwgd2hlbiB0aGUgbWFuYWdlciBpcyBzaHV0ZG93bi5cbiAgICAgKi9cbiAgICBjaGVja0ludGVydmFsSWQ/OiBOb2RlSlMuVGltZW91dCB8IHVuZGVmaW5lZFxuICAgIC8qKiBIb2xkcyB0aGUgc2hhcmRzIHRoYXQgcmVzaGFyZGluZyBoYXMgY3JlYXRlZC4gT25jZSByZXNoYXJkaW5nIGlzIGRvbmUsIHRoaXMgcmVwbGFjZXMgdGhlIGdhdGV3YXkuc2hhcmRzICovXG4gICAgc2hhcmRzOiBDb2xsZWN0aW9uPG51bWJlciwgU2hhcmQ+XG4gICAgLyoqIEhvbGRzIHRoZSBwZW5kaW5nIHNoYXJkcyB0aGF0IGhhdmUgYmVlbiBjcmVhdGVkIGFuZCBhcmUgcGVuZGluZyBhbGwgc2hhcmRzIGZpbmlzaCBsb2FkaW5nLiAqL1xuICAgIHBlbmRpbmdTaGFyZHM6IENvbGxlY3Rpb248bnVtYmVyLCBTaGFyZD5cbiAgICAvKiogSGFuZGxlciB0byBnZXQgc2hhcmQgY291bnQgYW5kIG90aGVyIHNlc3Npb24gaW5mby4gKi9cbiAgICBnZXRTZXNzaW9uSW5mbzogKCkgPT4gUHJvbWlzZTxDYW1lbGl6ZTxEaXNjb3JkR2V0R2F0ZXdheUJvdD4+XG4gICAgLyoqIEhhbmRsZXIgdG8gZWRpdCB0aGUgc2hhcmQgaWQgb24gYW55IGNhY2hlZCBndWlsZHMuICovXG4gICAgdXBkYXRlR3VpbGRzU2hhcmRJZDogKGd1aWxkSWRzOiBzdHJpbmdbXSwgc2hhcmRJZDogbnVtYmVyKSA9PiBQcm9taXNlPHZvaWQ+XG4gICAgLyoqIEhhbmRsZXIgdG8gY2hlY2sgaWYgcmVzaGFyZGluZyBpcyBuZWNlc3NhcnkuICovXG4gICAgY2hlY2tJZlJlc2hhcmRpbmdJc05lZWRlZDogKCkgPT4gUHJvbWlzZTx7IG5lZWRlZDogYm9vbGVhbjsgaW5mbz86IENhbWVsaXplPERpc2NvcmRHZXRHYXRld2F5Qm90PiB9PlxuICAgIC8qKiBIYW5kbGVyIHRvIGJlZ2luIHJlc2hhcmRpbmcuICovXG4gICAgcmVzaGFyZDogKGluZm86IENhbWVsaXplPERpc2NvcmRHZXRHYXRld2F5Qm90PiAmIHsgZmlyc3RTaGFyZElkPzogbnVtYmVyOyBsYXN0U2hhcmRJZD86IG51bWJlciB9KSA9PiBQcm9taXNlPHZvaWQ+XG4gICAgLyoqIEhhbmRsZXIgdG8gY29tbXVuaWNhdGUgdG8gYSB3b3JrZXIgdGhhdCBhIHNoYXJkIG5lZWRzIHRvIGJlIGNyZWF0ZWQuICovXG4gICAgdGVsbFdvcmtlclRvUHJlcGFyZTogKHdvcmtlcklkOiBudW1iZXIsIHNoYXJkSWQ6IG51bWJlciwgYnVja2V0SWQ6IG51bWJlcikgPT4gUHJvbWlzZTx2b2lkPlxuICAgIC8qKiBIYW5kbGVyIHRvIGFsZXJ0IHRoZSBnYXRld2F5IHRoYXQgYSBzaGFyZChyZXNoYXJkZWQpIGlzIG9ubGluZS4gSXQgc2hvdWxkIG5vdyB3YWl0IGZvciBhbGwgc2hhcmRzIHRvIGJlIHBlbmRpbmcgYmVmb3JlIHNodXR0aW5nIG9mZiBvbGQgc2hhcmRzLiAqL1xuICAgIHNoYXJkSXNQZW5kaW5nOiAoc2hhcmQ6IFNoYXJkKSA9PiBQcm9taXNlPHZvaWQ+XG4gIH1cbiAgLyoqIERldGVybWluZSBtYXggbnVtYmVyIG9mIHNoYXJkcyB0byB1c2UgYmFzZWQgdXBvbiB0aGUgbWF4IGNvbmN1cnJlbmN5LiAqL1xuICBjYWxjdWxhdGVUb3RhbFNoYXJkczogKCkgPT4gbnVtYmVyXG4gIC8qKiBEZXRlcm1pbmUgdGhlIGlkIG9mIHRoZSB3b3JrZXIgd2hpY2ggaXMgaGFuZGxpbmcgYSBzaGFyZC4gKi9cbiAgY2FsY3VsYXRlV29ya2VySWQ6IChzaGFyZElkOiBudW1iZXIpID0+IG51bWJlclxuICAvKiogUHJlcGFyZXMgYWxsIHRoZSBidWNrZXRzIHRoYXQgYXJlIGF2YWlsYWJsZSBmb3IgaWRlbnRpZnlpbmcgdGhlIHNoYXJkcy4gKi9cbiAgcHJlcGFyZUJ1Y2tldHM6ICgpID0+IHZvaWRcbiAgLyoqIFN0YXJ0IGlkZW50aWZ5aW5nIGFsbCB0aGUgc2hhcmRzLiAqL1xuICBzcGF3blNoYXJkczogKCkgPT4gUHJvbWlzZTx2b2lkPlxuICAvKiogU2h1dGRvd24gYWxsIHNoYXJkcy4gKi9cbiAgc2h1dGRvd246IChjb2RlOiBudW1iZXIsIHJlYXNvbjogc3RyaW5nLCBjbGVhclJlc2hhcmRpbmdJbnRlcnZhbD86IGJvb2xlYW4pID0+IFByb21pc2U8dm9pZD5cbiAgc2VuZFBheWxvYWQ6IChzaGFyZElkOiBudW1iZXIsIHBheWxvYWQ6IFNoYXJkU29ja2V0UmVxdWVzdCkgPT4gUHJvbWlzZTx2b2lkPlxuICAvKiogQWxsb3dzIHVzZXJzIHRvIGhvb2sgaW4gYW5kIGNoYW5nZSB0byBjb21tdW5pY2F0ZSB0byBkaWZmZXJlbnQgd29ya2VycyBhY3Jvc3MgZGlmZmVyZW50IHNlcnZlcnMgb3IgYW55dGhpbmcgdGhleSBsaWtlLiBGb3IgZXhhbXBsZSB1c2luZyByZWRpcyBwdWJzdWIgdG8gdGFsayB0byBvdGhlciBzZXJ2ZXJzLiAqL1xuICB0ZWxsV29ya2VyVG9JZGVudGlmeTogKHdvcmtlcklkOiBudW1iZXIsIHNoYXJkSWQ6IG51bWJlciwgYnVja2V0SWQ6IG51bWJlcikgPT4gUHJvbWlzZTx2b2lkPlxuICAvKiogVGVsbCB0aGUgbWFuYWdlciB0byBpZGVudGlmeSBhIFNoYXJkLiBJZiB0aGlzIFNoYXJkIGlzIG5vdCBhbHJlYWR5IG1hbmFnZWQgdGhpcyB3aWxsIGFsc28gYWRkIHRoZSBTaGFyZCB0byB0aGUgbWFuYWdlci4gKi9cbiAgaWRlbnRpZnk6IChzaGFyZElkOiBudW1iZXIpID0+IFByb21pc2U8dm9pZD5cbiAgLyoqIEtpbGwgYSBzaGFyZC4gQ2xvc2UgYSBzaGFyZHMgY29ubmVjdGlvbiB0byBEaXNjb3JkJ3MgZ2F0ZXdheSAoaWYgYW55KSBhbmQgcmVtb3ZlIGl0IGZyb20gdGhlIG1hbmFnZXIuICovXG4gIGtpbGw6IChzaGFyZElkOiBudW1iZXIpID0+IFByb21pc2U8dm9pZD5cbiAgLyoqIFRoaXMgZnVuY3Rpb24gbWFrZXMgc3VyZSB0aGF0IHRoZSBidWNrZXQgaXMgYWxsb3dlZCB0byBtYWtlIHRoZSBuZXh0IGlkZW50aWZ5IHJlcXVlc3QuICovXG4gIHJlcXVlc3RJZGVudGlmeTogKHNoYXJkSWQ6IG51bWJlcikgPT4gUHJvbWlzZTx2b2lkPlxuICAvKiogQ2FsY3VsYXRlcyB0aGUgbnVtYmVyIG9mIHNoYXJkcyBiYXNlZCBvbiB0aGUgZ3VpbGQgaWQgYW5kIHRvdGFsIHNoYXJkcy4gKi9cbiAgY2FsY3VsYXRlU2hhcmRJZDogKGd1aWxkSWQ6IEJpZ1N0cmluZywgdG90YWxTaGFyZHM/OiBudW1iZXIpID0+IG51bWJlclxuICAvKipcbiAgICogQ29ubmVjdHMgdGhlIGJvdCB1c2VyIHRvIGEgdm9pY2Ugb3Igc3RhZ2UgY2hhbm5lbC5cbiAgICpcbiAgICogVGhpcyBmdW5jdGlvbiBzZW5kcyB0aGUgX1VwZGF0ZSBWb2ljZSBTdGF0ZV8gZ2F0ZXdheSBjb21tYW5kIG92ZXIgdGhlIGdhdGV3YXkgYmVoaW5kIHRoZSBzY2VuZXMuXG4gICAqXG4gICAqIEBwYXJhbSBndWlsZElkIC0gVGhlIElEIG9mIHRoZSBndWlsZCB0aGUgdm9pY2UgY2hhbm5lbCB0byBsZWF2ZSBpcyBpbi5cbiAgICogQHBhcmFtIGNoYW5uZWxJZCAtIFRoZSBJRCBvZiB0aGUgY2hhbm5lbCB5b3Ugd2FudCB0byBqb2luLlxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBSZXF1aXJlcyB0aGUgYENPTk5FQ1RgIHBlcm1pc3Npb24uXG4gICAqXG4gICAqIEZpcmVzIGEgX1ZvaWNlIFN0YXRlIFVwZGF0ZV8gZ2F0ZXdheSBldmVudC5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9kaXNjb3JkLmNvbS9kZXZlbG9wZXJzL2RvY3MvdG9waWNzL2dhdGV3YXkjdXBkYXRlLXZvaWNlLXN0YXRlfVxuICAgKi9cbiAgam9pblZvaWNlQ2hhbm5lbDogKGd1aWxkSWQ6IEJpZ1N0cmluZywgY2hhbm5lbElkOiBCaWdTdHJpbmcsIG9wdGlvbnM/OiBBdExlYXN0T25lPE9taXQ8VXBkYXRlVm9pY2VTdGF0ZSwgJ2d1aWxkSWQnIHwgJ2NoYW5uZWxJZCc+PikgPT4gUHJvbWlzZTx2b2lkPlxuICAvKipcbiAgICogRWRpdHMgdGhlIGJvdCBzdGF0dXMgaW4gYWxsIHNoYXJkcyB0aGF0IHRoaXMgZ2F0ZXdheSBtYW5hZ2VzLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSBUaGUgc3RhdHVzIGRhdGEgdG8gc2V0IHRoZSBib3RzIHN0YXR1cyB0by5cbiAgICogQHJldHVybnMgbm90aGluZ1xuICAgKi9cbiAgZWRpdEJvdFN0YXR1czogKGRhdGE6IFN0YXR1c1VwZGF0ZSkgPT4gUHJvbWlzZTx2b2lkPlxuICAvKipcbiAgICogRWRpdHMgdGhlIGJvdCdzIHN0YXR1cyBvbiBvbmUgc2hhcmQuXG4gICAqXG4gICAqIEBwYXJhbSBzaGFyZElkIFRoZSBzaGFyZCBpZCB0byBlZGl0IHRoZSBzdGF0dXMgZm9yLlxuICAgKiBAcGFyYW0gZGF0YSBUaGUgc3RhdHVzIGRhdGEgdG8gc2V0IHRoZSBib3RzIHN0YXR1cyB0by5cbiAgICogQHJldHVybnMgbm90aGluZ1xuICAgKi9cbiAgZWRpdFNoYXJkU3RhdHVzOiAoc2hhcmRJZDogbnVtYmVyLCBkYXRhOiBTdGF0dXNVcGRhdGUpID0+IFByb21pc2U8dm9pZD5cbiAgLyoqXG4gICAqIEZldGNoZXMgdGhlIGxpc3Qgb2YgbWVtYmVycyBmb3IgYSBndWlsZCBvdmVyIHRoZSBnYXRld2F5LlxuICAgKlxuICAgKiBAcGFyYW0gZ3VpbGRJZCAtIFRoZSBJRCBvZiB0aGUgZ3VpbGQgdG8gZ2V0IHRoZSBsaXN0IG9mIG1lbWJlcnMgZm9yLlxuICAgKiBAcGFyYW0gb3B0aW9ucyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGUgZmV0Y2hpbmcgb2YgdGhlIG1lbWJlcnMuXG4gICAqXG4gICAqIEByZW1hcmtzXG4gICAqIElmIHJlcXVlc3RpbmcgdGhlIGVudGlyZSBtZW1iZXIgbGlzdDpcbiAgICogLSBSZXF1aXJlcyB0aGUgYEdVSUxEX01FTUJFUlNgIGludGVudC5cbiAgICpcbiAgICogSWYgcmVxdWVzdGluZyBwcmVzZW5jZXMgKHtAbGluayBSZXF1ZXN0R3VpbGRNZW1iZXJzLnByZXNlbmNlcyB8IHByZXNlbmNlc30gc2V0IHRvIGB0cnVlYCk6XG4gICAqIC0gUmVxdWlyZXMgdGhlIGBHVUlMRF9QUkVTRU5DRVNgIGludGVudC5cbiAgICpcbiAgICogSWYgcmVxdWVzdGluZyBhIHByZWZpeCAoe0BsaW5rIFJlcXVlc3RHdWlsZE1lbWJlcnMucXVlcnkgfCBxdWVyeX0gbm9uLWB1bmRlZmluZWRgKTpcbiAgICogLSBSZXR1cm5zIGEgbWF4aW11bSBvZiAxMDAgbWVtYmVycy5cbiAgICpcbiAgICogSWYgcmVxdWVzdGluZyBhIHVzZXJzIGJ5IElEICh7QGxpbmsgUmVxdWVzdEd1aWxkTWVtYmVycy51c2VySWRzIHwgdXNlcklkc30gbm9uLWB1bmRlZmluZWRgKTpcbiAgICogLSBSZXR1cm5zIGEgbWF4aW11bSBvZiAxMDAgbWVtYmVycy5cbiAgICpcbiAgICogRmlyZXMgYSBfR3VpbGQgTWVtYmVycyBDaHVua18gZ2F0ZXdheSBldmVudCBmb3IgZXZlcnkgMTAwMCBtZW1iZXJzIGZldGNoZWQuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGlzY29yZC5jb20vZGV2ZWxvcGVycy9kb2NzL3RvcGljcy9nYXRld2F5I3JlcXVlc3QtZ3VpbGQtbWVtYmVyc31cbiAgICovXG4gIHJlcXVlc3RNZW1iZXJzOiAoZ3VpbGRJZDogQmlnU3RyaW5nLCBvcHRpb25zPzogT21pdDxSZXF1ZXN0R3VpbGRNZW1iZXJzLCAnZ3VpbGRJZCc+KSA9PiBQcm9taXNlPENhbWVsaXplPERpc2NvcmRNZW1iZXJXaXRoVXNlcltdPj5cbiAgLyoqXG4gICAqIExlYXZlcyB0aGUgdm9pY2UgY2hhbm5lbCB0aGUgYm90IHVzZXIgaXMgY3VycmVudGx5IGluLlxuICAgKlxuICAgKiBUaGlzIGZ1bmN0aW9uIHNlbmRzIHRoZSBfVXBkYXRlIFZvaWNlIFN0YXRlXyBnYXRld2F5IGNvbW1hbmQgb3ZlciB0aGUgZ2F0ZXdheSBiZWhpbmQgdGhlIHNjZW5lcy5cbiAgICpcbiAgICogQHBhcmFtIGd1aWxkSWQgLSBUaGUgSUQgb2YgdGhlIGd1aWxkIHRoZSB2b2ljZSBjaGFubmVsIHRvIGxlYXZlIGlzIGluLlxuICAgKlxuICAgKiBAcmVtYXJrc1xuICAgKiBGaXJlcyBhIF9Wb2ljZSBTdGF0ZSBVcGRhdGVfIGdhdGV3YXkgZXZlbnQuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vZGlzY29yZC5jb20vZGV2ZWxvcGVycy9kb2NzL3RvcGljcy9nYXRld2F5I3VwZGF0ZS12b2ljZS1zdGF0ZX1cbiAgICovXG4gIGxlYXZlVm9pY2VDaGFubmVsOiAoZ3VpbGRJZDogQmlnU3RyaW5nKSA9PiBQcm9taXNlPHZvaWQ+XG4gIC8qKiBUaGlzIG1hbmFnZXJzIGNhY2hlIHJlbGF0ZWQgc2V0dGluZ3MuICovXG4gIGNhY2hlOiB7XG4gICAgcmVxdWVzdE1lbWJlcnM6IHtcbiAgICAgIC8qKlxuICAgICAgICogV2hldGhlciBvciBub3QgcmVxdWVzdCBtZW1iZXIgcmVxdWVzdHMgc2hvdWxkIGJlIGNhY2hlZC5cbiAgICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICAgKi9cbiAgICAgIGVuYWJsZWQ6IGJvb2xlYW5cbiAgICAgIC8qKiBUaGUgcGVuZGluZyByZXF1ZXN0cy4gKi9cbiAgICAgIHBlbmRpbmc6IENvbGxlY3Rpb248c3RyaW5nLCBSZXF1ZXN0TWVtYmVyUmVxdWVzdD5cbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXF1ZXN0TWVtYmVyUmVxdWVzdCB7XG4gIC8qKiBUaGUgdW5pcXVlIG5vbmNlIGZvciB0aGlzIHJlcXVlc3QuICovXG4gIG5vbmNlOiBzdHJpbmdcbiAgLyoqIFRoZSByZXNvbHZlciBoYW5kbGVyIHRvIHJ1biB3aGVuIGFsbCBtZW1iZXJzIGFycml2ZS4gKi9cbiAgcmVzb2x2ZTogKHZhbHVlOiBDYW1lbGl6ZTxEaXNjb3JkTWVtYmVyV2l0aFVzZXJbXT4gfCBQcm9taXNlTGlrZTxDYW1lbGl6ZTxEaXNjb3JkTWVtYmVyV2l0aFVzZXJbXT4+KSA9PiB2b2lkXG4gIC8qKiBUaGUgbWVtYmVycyB0aGF0IGhhdmUgYWxyZWFkeSBhcnJpdmVkIGZvciB0aGlzIHJlcXVlc3QuICovXG4gIG1lbWJlcnM6IERpc2NvcmRNZW1iZXJXaXRoVXNlcltdXG59XG4iXSwibmFtZXMiOlsiR2F0ZXdheUludGVudHMiLCJHYXRld2F5T3Bjb2RlcyIsIkNvbGxlY3Rpb24iLCJkZWxheSIsImxvZ2dlciIsIlNoYXJkIiwiU2hhcmRTb2NrZXRDbG9zZUNvZGVzIiwiY3JlYXRlR2F0ZXdheU1hbmFnZXIiLCJvcHRpb25zIiwiY29ubmVjdGlvbk9wdGlvbnMiLCJjb25uZWN0aW9uIiwidXJsIiwic2hhcmRzIiwic2Vzc2lvblN0YXJ0TGltaXQiLCJtYXhDb25jdXJyZW5jeSIsInJlbWFpbmluZyIsInRvdGFsIiwicmVzZXRBZnRlciIsImdhdGV3YXkiLCJldmVudHMiLCJjb21wcmVzcyIsImludGVudHMiLCJwcm9wZXJ0aWVzIiwib3MiLCJwcm9jZXNzIiwicGxhdGZvcm0iLCJicm93c2VyIiwiZGV2aWNlIiwidG9rZW4iLCJ2ZXJzaW9uIiwidG90YWxTaGFyZHMiLCJsYXN0U2hhcmRJZCIsImZpcnN0U2hhcmRJZCIsInRvdGFsV29ya2VycyIsInNoYXJkc1BlcldvcmtlciIsInNwYXduU2hhcmREZWxheSIsInByZWZlclNuYWtlQ2FzZSIsIk1hcCIsImJ1Y2tldHMiLCJjYWNoZSIsInJlcXVlc3RNZW1iZXJzIiwiZW5hYmxlZCIsInBlbmRpbmciLCJyZXNoYXJkaW5nIiwic2hhcmRzRnVsbFBlcmNlbnRhZ2UiLCJjaGVja0ludGVydmFsIiwicGVuZGluZ1NoYXJkcyIsImdldFNlc3Npb25JbmZvIiwiRXJyb3IiLCJjaGVja0lmUmVzaGFyZGluZ0lzTmVlZGVkIiwid2FybiIsIm5lZWRlZCIsInNlc3Npb25JbmZvIiwiaW5mbyIsInBlcmNlbnRhZ2UiLCJyZXNoYXJkIiwiY2FsY3VsYXRlVG90YWxTaGFyZHMiLCJjbGVhciIsInByZXBhcmVCdWNrZXRzIiwiZm9yRWFjaCIsImJ1Y2tldCIsImJ1Y2tldElkIiwid29ya2VyIiwid29ya2VycyIsInNoYXJkSWQiLCJxdWV1ZSIsInRlbGxXb3JrZXJUb1ByZXBhcmUiLCJpZCIsIndvcmtlcklkIiwic2hhcmQiLCJtZXNzYWdlIiwiX3NoYXJkIiwicGF5bG9hZCIsInQiLCJ1cGRhdGVHdWlsZHNTaGFyZElkIiwiZCIsImd1aWxkcyIsIm1hcCIsImciLCJyZXF1ZXN0SWRlbnRpZnkiLCJpZGVudGlmeSIsInNoYXJkSXNSZWFkeSIsImRlYnVnIiwiZ2V0IiwiaWRlbnRpZnlSZXF1ZXN0cyIsInNoaWZ0IiwiZm9yd2FyZFRvQm90Iiwic2V0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJwdXNoIiwidGhlbiIsInNoYXJkSXNQZW5kaW5nIiwiZ3VpbGRJZHMiLCJqb2luIiwic2l6ZSIsInZhbHVlcyIsImV2ZW50Iiwib2xkSGFuZGxlciIsIl8iLCJzaHV0ZG93biIsIlJlc2hhcmRlZCIsIk1hdGgiLCJjZWlsIiwiY2FsY3VsYXRlV29ya2VySWQiLCJtaW4iLCJpIiwiZmluZCIsInciLCJzb3J0IiwiYSIsImIiLCJzcGF3blNoYXJkcyIsImFsbCIsImVudHJpZXMiLCJ0ZWxsV29ya2VyVG9JZGVudGlmeSIsImNoZWNrSW50ZXJ2YWxJZCIsInNldEludGVydmFsIiwicmVzaGFyZGluZ0luZm8iLCJjb2RlIiwicmVhc29uIiwiY2xlYXJSZXNoYXJkaW5nSW50ZXJ2YWwiLCJjbG9zZSIsImNsZWFySW50ZXJ2YWwiLCJzZW5kUGF5bG9hZCIsInNlbmQiLCJraWxsIiwiZGVsZXRlIiwiX3NoYXJkSWQiLCJjYWxjdWxhdGVTaGFyZElkIiwiZ3VpbGRJZCIsIk51bWJlciIsIkJpZ0ludCIsImpvaW5Wb2ljZUNoYW5uZWwiLCJjaGFubmVsSWQiLCJvcCIsIlZvaWNlU3RhdGVVcGRhdGUiLCJndWlsZF9pZCIsInRvU3RyaW5nIiwiY2hhbm5lbF9pZCIsInNlbGZfbXV0ZSIsInNlbGZNdXRlIiwic2VsZl9kZWFmIiwic2VsZkRlYWYiLCJlZGl0Qm90U3RhdHVzIiwiZGF0YSIsIkpTT04iLCJzdHJpbmdpZnkiLCJlZGl0U2hhcmRTdGF0dXMiLCJQcmVzZW5jZVVwZGF0ZSIsInNpbmNlIiwiYWZrIiwiYWN0aXZpdGllcyIsInN0YXR1cyIsImxpbWl0IiwiR3VpbGRNZW1iZXJzIiwidXNlcklkcyIsImxlbmd0aCIsIm1lbWJlcnMiLCJub25jZSIsInJlamVjdCIsIlJlcXVlc3RHdWlsZE1lbWJlcnMiLCJxdWVyeSIsInVuZGVmaW5lZCIsInByZXNlbmNlcyIsInVzZXJfaWRzIiwibGVhdmVWb2ljZUNoYW5uZWwiXSwibWFwcGluZ3MiOiJBQUFBLFNBT0VBLGNBQWMsRUFDZEMsY0FBYyxRQUVULG9CQUFtQjtBQUMxQixTQUFTQyxVQUFVLEVBQUVDLEtBQUssRUFBRUMsTUFBTSxRQUFRLG9CQUFtQjtBQUM3RCxPQUFPQyxXQUFXLGFBQVk7QUFDOUIsU0FBMkJDLHFCQUFxQixRQUEyRSxhQUFZO0FBRXZJLE9BQU8sU0FBU0MscUJBQXFCQyxPQUFvQztJQUN2RSxNQUFNQyxvQkFBb0JELFFBQVFFLFVBQVUsSUFBSTtRQUM5Q0MsS0FBSztRQUNMQyxRQUFRO1FBQ1JDLG1CQUFtQjtZQUNqQkMsZ0JBQWdCO1lBQ2hCQyxXQUFXO1lBQ1hDLE9BQU87WUFDUEMsWUFBWSxPQUFPLEtBQUssS0FBSztRQUMvQjtJQUNGO0lBRUEsTUFBTUMsVUFBMEI7UUFDOUJDLFFBQVFYLFFBQVFXLE1BQU0sSUFBSSxDQUFDO1FBQzNCQyxVQUFVWixRQUFRWSxRQUFRLElBQUk7UUFDOUJDLFNBQVNiLFFBQVFhLE9BQU8sSUFBSTtRQUM1QkMsWUFBWTtZQUNWQyxJQUFJZixRQUFRYyxVQUFVLEVBQUVDLE1BQU1DLFFBQVFDLFFBQVE7WUFDOUNDLFNBQVNsQixRQUFRYyxVQUFVLEVBQUVJLFdBQVc7WUFDeENDLFFBQVFuQixRQUFRYyxVQUFVLEVBQUVLLFVBQVU7UUFDeEM7UUFDQUMsT0FBT3BCLFFBQVFvQixLQUFLO1FBQ3BCakIsS0FBS0gsUUFBUUcsR0FBRyxJQUFJRixrQkFBa0JFLEdBQUcsSUFBSTtRQUM3Q2tCLFNBQVNyQixRQUFRcUIsT0FBTyxJQUFJO1FBQzVCbkIsWUFBWUQ7UUFDWnFCLGFBQWF0QixRQUFRc0IsV0FBVyxJQUFJckIsa0JBQWtCRyxNQUFNLElBQUk7UUFDaEVtQixhQUFhdkIsUUFBUXVCLFdBQVcsSUFBS3ZCLENBQUFBLFFBQVFzQixXQUFXLEdBQUd0QixRQUFRc0IsV0FBVyxHQUFHLElBQUlyQixvQkFBb0JBLGtCQUFrQkcsTUFBTSxHQUFHLElBQUksQ0FBQTtRQUN4SW9CLGNBQWN4QixRQUFRd0IsWUFBWSxJQUFJO1FBQ3RDQyxjQUFjekIsUUFBUXlCLFlBQVksSUFBSTtRQUN0Q0MsaUJBQWlCMUIsUUFBUTBCLGVBQWUsSUFBSTtRQUM1Q0MsaUJBQWlCM0IsUUFBUTJCLGVBQWUsSUFBSTtRQUM1Q0MsaUJBQWlCNUIsUUFBUTRCLGVBQWUsSUFBSTtRQUM1Q3hCLFFBQVEsSUFBSXlCO1FBQ1pDLFNBQVMsSUFBSUQ7UUFDYkUsT0FBTztZQUNMQyxnQkFBZ0I7Z0JBQ2RDLFNBQVNqQyxRQUFRK0IsS0FBSyxFQUFFQyxnQkFBZ0JDLFdBQVc7Z0JBQ25EQyxTQUFTLElBQUl4QztZQUNmO1FBQ0Y7UUFDQUUsUUFBUUksUUFBUUosTUFBTSxJQUFJQTtRQUMxQnVDLFlBQVk7WUFDVkYsU0FBUztZQUNURyxzQkFBc0I7WUFDdEJDLGVBQWU7WUFDZmpDLFFBQVEsSUFBSVY7WUFDWjRDLGVBQWUsSUFBSTVDO1lBQ25CLE1BQU02QztnQkFDSixNQUFNLElBQUlDLE1BQ1I7WUFFSjtZQUNBLE1BQU1DO2dCQUNKN0MsT0FBTzhDLElBQUksQ0FBQyxDQUFDLDhDQUE4QyxDQUFDO2dCQUM1RCwwQkFBMEI7Z0JBQzFCLElBQUksQ0FBQ2hDLFFBQVF5QixVQUFVLENBQUNGLE9BQU8sRUFBRSxPQUFPO29CQUFFVSxRQUFRO2dCQUFNO2dCQUN4RC9DLE9BQU84QyxJQUFJLENBQUMsQ0FBQyxtQ0FBbUMsQ0FBQztnQkFFakQsTUFBTUUsY0FBYyxNQUFNbEMsUUFBUXlCLFVBQVUsQ0FBQ0ksY0FBYztnQkFDM0QzQyxPQUFPOEMsSUFBSSxDQUFDLENBQUMsb0NBQW9DLENBQUM7Z0JBQ2xELHNEQUFzRDtnQkFDdEQsSUFBSUUsWUFBWXZDLGlCQUFpQixDQUFDRSxTQUFTLEdBQUdxQyxZQUFZeEMsTUFBTSxFQUFFLE9BQU87b0JBQUV1QyxRQUFRO29CQUFPRSxNQUFNRDtnQkFBWTtnQkFDNUdoRCxPQUFPOEMsSUFBSSxDQUFDLENBQUMsNkRBQTZELENBQUM7Z0JBRTNFLDZEQUE2RDtnQkFDN0QsdUZBQXVGO2dCQUN2RixpRUFBaUU7Z0JBQ2pFLE1BQU1JLGFBQWEsQUFBRSxPQUFPRixZQUFZeEMsTUFBTSxHQUFLTSxDQUFBQSxRQUFRWSxXQUFXLEdBQUcsSUFBRyxJQUFNO2dCQUNsRixnREFBZ0Q7Z0JBQ2hELElBQUl3QixhQUFhcEMsUUFBUXlCLFVBQVUsQ0FBQ0Msb0JBQW9CLEVBQUUsT0FBTztvQkFBRU8sUUFBUTtvQkFBT0UsTUFBTUQ7Z0JBQVk7Z0JBQ3BHaEQsT0FBTzhDLElBQUksQ0FBQyxDQUFDLGtDQUFrQyxDQUFDO2dCQUVoRCxPQUFPO29CQUFFQyxRQUFRO29CQUFNRSxNQUFNRDtnQkFBWTtZQUMzQztZQUNBLE1BQU1HLFNBQVFGLElBQUk7Z0JBQ2hCakQsT0FBTzhDLElBQUksQ0FBQyxDQUFDLGtFQUFrRSxFQUFFaEMsUUFBUVksV0FBVyxDQUFDLENBQUM7Z0JBQ3RHLHdCQUF3QjtnQkFDeEJaLFFBQVFZLFdBQVcsR0FBR3VCLEtBQUt6QyxNQUFNO2dCQUNqQywyQ0FBMkM7Z0JBQzNDTSxRQUFRWSxXQUFXLEdBQUdaLFFBQVFzQyxvQkFBb0I7Z0JBQ2xELHlDQUF5QztnQkFDekMsSUFBSSxPQUFPSCxLQUFLckIsWUFBWSxLQUFLLFVBQVVkLFFBQVFjLFlBQVksR0FBR3FCLEtBQUtyQixZQUFZO2dCQUNuRix3Q0FBd0M7Z0JBQ3hDLElBQUksT0FBT3FCLEtBQUt0QixXQUFXLEtBQUssVUFBVWIsUUFBUWEsV0FBVyxHQUFHc0IsS0FBS3RCLFdBQVc7Z0JBQ2hGM0IsT0FBTzhDLElBQUksQ0FBQyxDQUFDLDZEQUE2RCxFQUFFaEMsUUFBUVksV0FBVyxDQUFDLENBQUM7Z0JBRWpHLG9CQUFvQjtnQkFDcEJaLFFBQVFvQixPQUFPLENBQUNtQixLQUFLO2dCQUNyQixvQ0FBb0M7Z0JBQ3BDdkMsUUFBUXdDLGNBQWM7Z0JBRXRCLDREQUE0RDtnQkFDNUR4QyxRQUFRb0IsT0FBTyxDQUFDcUIsT0FBTyxDQUFDLE9BQU9DLFFBQVFDO29CQUNyQyxLQUFLLE1BQU1DLFVBQVVGLE9BQU9HLE9BQU8sQ0FBRTt3QkFDbkMsS0FBSyxNQUFNQyxXQUFXRixPQUFPRyxLQUFLLENBQUU7NEJBQ2xDLE1BQU0vQyxRQUFReUIsVUFBVSxDQUFDdUIsbUJBQW1CLENBQUNKLE9BQU9LLEVBQUUsRUFBRUgsU0FBU0g7d0JBQ25FO29CQUNGO2dCQUNGO1lBQ0Y7WUFDQSxNQUFNSyxxQkFBb0JFLFFBQVEsRUFBRUosT0FBTyxFQUFFSCxRQUFRO2dCQUNuRHpELE9BQU84QyxJQUFJLENBQUMsQ0FBQyxnREFBZ0QsRUFBRWtCLFNBQVMsVUFBVSxFQUFFSixRQUFRLFdBQVcsRUFBRUgsU0FBUyxDQUFDO2dCQUNuSCxNQUFNUSxRQUFRLElBQUloRSxNQUFNO29CQUN0QjhELElBQUlIO29CQUNKdEQsWUFBWTt3QkFDVlUsVUFBVUYsUUFBUUUsUUFBUTt3QkFDMUJDLFNBQVNILFFBQVFHLE9BQU87d0JBQ3hCQyxZQUFZSixRQUFRSSxVQUFVO3dCQUM5Qk0sT0FBT1YsUUFBUVUsS0FBSzt3QkFDcEJFLGFBQWFaLFFBQVFZLFdBQVc7d0JBQ2hDbkIsS0FBS08sUUFBUVAsR0FBRzt3QkFDaEJrQixTQUFTWCxRQUFRVyxPQUFPO29CQUMxQjtvQkFDQSxtQ0FBbUM7b0JBQ25DVixRQUFRO3dCQUNOLE1BQU1tRCxTQUFRQyxNQUFNLEVBQUVDLE9BQU87NEJBQzNCLElBQUlBLFFBQVFDLENBQUMsS0FBSyxTQUFTO2dDQUN6QixNQUFNdkQsUUFBUXlCLFVBQVUsQ0FBQytCLG1CQUFtQixDQUMxQyxBQUFDRixRQUFRRyxDQUFDLENBQWtCQyxNQUFNLENBQUNDLEdBQUcsQ0FBQyxDQUFDQyxJQUFNQSxFQUFFWCxFQUFFLEdBQ2xESDs0QkFFSjt3QkFDRjtvQkFDRjtvQkFDQWUsaUJBQWlCO3dCQUNmLE1BQU03RCxRQUFROEQsUUFBUSxDQUFDaEI7b0JBQ3pCO29CQUNBaUIsY0FBYzt3QkFDWjdFLE9BQU84RSxLQUFLLENBQUMsQ0FBQyxlQUFlLEVBQUVsQixRQUFRLFNBQVMsQ0FBQzt3QkFDakQsTUFBTTdELE1BQU1lLFFBQVFpQixlQUFlO3dCQUNuQy9CLE9BQU84RSxLQUFLLENBQUMsQ0FBQyx3Q0FBd0MsQ0FBQzt3QkFDdkRoRSxRQUFRb0IsT0FBTyxDQUFDNkMsR0FBRyxDQUFDbkIsVUFBVTlDLFFBQVFSLFVBQVUsQ0FBQ0csaUJBQWlCLENBQUNDLGNBQWMsRUFBR3NFLGdCQUFnQixDQUFDQyxLQUFLO29CQUM1RztnQkFDRjtnQkFFQSxJQUFJbkUsUUFBUWtCLGVBQWUsRUFBRTtvQkFDM0JpQyxNQUFNaUIsWUFBWSxHQUFHLE9BQU9kO3dCQUMxQkgsTUFBTWxELE1BQU0sRUFBRW1ELFVBQVVELE9BQU9HO29CQUNqQztnQkFDRjtnQkFFQXRELFFBQVF5QixVQUFVLENBQUMvQixNQUFNLENBQUMyRSxHQUFHLENBQUN2QixTQUFTSztnQkFFdkMsTUFBTVQsU0FBUzFDLFFBQVFvQixPQUFPLENBQUM2QyxHQUFHLENBQUNuQixVQUFVOUMsUUFBUVIsVUFBVSxDQUFDRyxpQkFBaUIsQ0FBQ0MsY0FBYztnQkFDaEcsSUFBSSxDQUFDOEMsUUFBUTtnQkFFYixPQUFPLE1BQU0sSUFBSTRCLFFBQVEsQ0FBQ0M7b0JBQ3hCLHNFQUFzRTtvQkFDdEU3QixPQUFPd0IsZ0JBQWdCLENBQUNNLElBQUksQ0FBQ0Q7b0JBQzdCckYsT0FBTzhFLEtBQUssQ0FBQyxDQUFDLDhCQUE4QixFQUFFbEIsUUFBUSxFQUFFLENBQUM7b0JBQ3pELDJGQUEyRjtvQkFDM0ZLLE9BQU9XLFdBQVdXLEtBQUs7d0JBQ3JCLDZDQUE2Qzt3QkFDN0MsT0FBTyxNQUFNekUsUUFBUXlCLFVBQVUsQ0FBQ2lELGNBQWMsQ0FBQ3ZCO29CQUNqRDtnQkFDRjtZQUNGO1lBQ0EsTUFBTUsscUJBQW9CbUIsUUFBUSxFQUFFN0IsT0FBTztnQkFDekM1RCxPQUFPOEUsS0FBSyxDQUNWLENBQUMsd0RBQXdELEVBQUVsQixRQUFRLEVBQUUsRUFBRTZCLFNBQVNDLElBQUksQ0FBQyxNQUFNLDZEQUE2RCxDQUFDO1lBRTdKO1lBQ0EsTUFBTUYsZ0JBQWV2QixLQUFLO2dCQUN4QixrRUFBa0U7Z0JBQ2xFbkQsUUFBUXlCLFVBQVUsQ0FBQ0csYUFBYSxDQUFDeUMsR0FBRyxDQUFDbEIsTUFBTUYsRUFBRSxFQUFFRTtnQkFDL0NqRSxPQUFPOEMsSUFBSSxDQUFDLENBQUMsb0JBQW9CLEVBQUVtQixNQUFNRixFQUFFLENBQUMsZUFBZSxDQUFDO2dCQUM1RCxzQ0FBc0M7Z0JBQ3RDLElBQUlqRCxRQUFRYSxXQUFXLEdBQUdiLFFBQVFjLFlBQVksR0FBRyxJQUFJZCxRQUFReUIsVUFBVSxDQUFDRyxhQUFhLENBQUNpRCxJQUFJLEVBQUU7Z0JBQzVGM0YsT0FBTzhDLElBQUksQ0FBQyxDQUFDLHVDQUF1QyxDQUFDO2dCQUVyRCxxQ0FBcUM7Z0JBQ3JDLEtBQUssTUFBTW1CLFNBQVNuRCxRQUFReUIsVUFBVSxDQUFDRyxhQUFhLENBQUNrRCxNQUFNLEdBQUk7b0JBQzdELElBQUssTUFBTUMsU0FBU3pGLFFBQVFXLE1BQU0sQ0FBRTt3QkFDbEMsb0dBQW9HO3dCQUNwR2tELE1BQU1sRCxNQUFNLENBQUM4RSxNQUFNLEdBQUd6RixRQUFRVyxNQUFNLENBQUM4RSxNQUFNO29CQUM3QztnQkFDRjtnQkFFQSxvQ0FBb0M7Z0JBQ3BDLEtBQUssTUFBTTVCLFNBQVNuRCxRQUFRTixNQUFNLENBQUNvRixNQUFNLEdBQUk7b0JBQzNDLE1BQU1FLGFBQWE3QixNQUFNbEQsTUFBTSxDQUFDbUQsT0FBTztvQkFFdkMsbUtBQW1LO29CQUNuS0QsTUFBTWxELE1BQU0sR0FBRzt3QkFDYixHQUFHa0QsTUFBTWxELE1BQU07d0JBQ2ZtRCxTQUFTLGVBQWdCNkIsQ0FBQyxFQUFFN0IsT0FBTzs0QkFDakMscURBQXFEOzRCQUNyRCxJQUFJQSxRQUFRRyxDQUFDLEtBQUssdUJBQXVCOzRCQUN6QyxtQ0FBbUM7NEJBQ25DeUIsYUFBYTdCLE9BQU9DO3dCQUN0QjtvQkFDRjtnQkFDRjtnQkFFQWxFLE9BQU84QyxJQUFJLENBQUMsQ0FBQyxzQ0FBc0MsQ0FBQztnQkFDcEQsbUJBQW1CO2dCQUNuQixNQUFNaEMsUUFBUWtGLFFBQVEsQ0FBQzlGLHNCQUFzQitGLFNBQVMsRUFBRSxjQUFjO2dCQUN0RWpHLE9BQU84QyxJQUFJLENBQUMsQ0FBQyx1QkFBdUIsQ0FBQztnQkFFckMscUJBQXFCO2dCQUNyQmhDLFFBQVFOLE1BQU0sR0FBR00sUUFBUXlCLFVBQVUsQ0FBQy9CLE1BQU07WUFDNUM7UUFDRjtRQUVBNEM7WUFDRSxxREFBcUQ7WUFDckQsSUFBSXRDLFFBQVFZLFdBQVcsR0FBRyxLQUFLO2dCQUM3QlosUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsb0NBQW9DLEVBQUVoRSxRQUFRWSxXQUFXLENBQUMsQ0FBQztnQkFDakYsT0FBT1osUUFBUVksV0FBVztZQUM1QjtZQUVBWixRQUFRZCxNQUFNLENBQUM4RSxLQUFLLENBQUMsQ0FBQyxrQ0FBa0MsQ0FBQyxFQUFFaEUsUUFBUVksV0FBVyxFQUFFWixRQUFRUixVQUFVLENBQUNHLGlCQUFpQixDQUFDQyxjQUFjO1lBQ25JLHdGQUF3RjtZQUN4RixPQUNFd0YsS0FBS0MsSUFBSSxDQUNQckYsUUFBUVksV0FBVyxHQUNqQix1SkFBdUo7WUFDdEpaLENBQUFBLFFBQVFSLFVBQVUsQ0FBQ0csaUJBQWlCLENBQUNDLGNBQWMsS0FBSyxJQUFJLEtBQUtJLFFBQVFSLFVBQVUsQ0FBQ0csaUJBQWlCLENBQUNDLGNBQWMsQUFBRCxLQUNuSEksQ0FBQUEsUUFBUVIsVUFBVSxDQUFDRyxpQkFBaUIsQ0FBQ0MsY0FBYyxLQUFLLElBQUksS0FBS0ksUUFBUVIsVUFBVSxDQUFDRyxpQkFBaUIsQ0FBQ0MsY0FBYyxBQUFEO1FBRTVIO1FBQ0EwRixtQkFBa0J4QyxPQUFPO1lBQ3ZCLE1BQU1JLFdBQVdrQyxLQUFLRyxHQUFHLENBQUN6QyxVQUFVOUMsUUFBUWdCLGVBQWUsRUFBRWhCLFFBQVFlLFlBQVksR0FBRztZQUNwRmYsUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUNsQixDQUFDLHVDQUF1QyxFQUFFbEIsUUFBUSxZQUFZLEVBQUVJLFNBQVMsZ0JBQWdCLEVBQUVsRCxRQUFRZ0IsZUFBZSxDQUFDLFdBQVcsRUFBRWhCLFFBQVFlLFlBQVksQ0FBQyxDQUFDO1lBRXhKLE9BQU9tQztRQUNUO1FBQ0FWO1lBQ0UsSUFBSyxJQUFJZ0QsSUFBSSxHQUFHQSxJQUFJeEYsUUFBUVIsVUFBVSxDQUFDRyxpQkFBaUIsQ0FBQ0MsY0FBYyxFQUFFLEVBQUU0RixFQUFHO2dCQUM1RXhGLFFBQVFkLE1BQU0sQ0FBQzhFLEtBQUssQ0FBQyxDQUFDLDZDQUE2QyxFQUFFd0IsRUFBRSxDQUFDO2dCQUN4RXhGLFFBQVFvQixPQUFPLENBQUNpRCxHQUFHLENBQUNtQixHQUFHO29CQUNyQjNDLFNBQVMsRUFBRTtvQkFDWHFCLGtCQUFrQixFQUFFO2dCQUN0QjtZQUNGO1lBRUEsNkNBQTZDO1lBQzdDLElBQUssSUFBSXBCLFVBQVU5QyxRQUFRYyxZQUFZLEVBQUVnQyxXQUFXOUMsUUFBUWEsV0FBVyxFQUFFLEVBQUVpQyxRQUFTO2dCQUNsRjlDLFFBQVFkLE1BQU0sQ0FBQzhFLEtBQUssQ0FBQyxDQUFDLHVDQUF1QyxFQUFFbEIsUUFBUSxDQUFDO2dCQUN4RSxJQUFJQSxXQUFXOUMsUUFBUVksV0FBVyxFQUFFO29CQUNsQyxNQUFNLElBQUlrQixNQUFNLENBQUMsV0FBVyxFQUFFZ0IsUUFBUSxnRUFBZ0UsRUFBRTlDLFFBQVFZLFdBQVcsQ0FBQyxDQUFDO2dCQUMvSDtnQkFFQSxNQUFNK0IsV0FBV0csVUFBVTlDLFFBQVFSLFVBQVUsQ0FBQ0csaUJBQWlCLENBQUNDLGNBQWM7Z0JBQzlFLE1BQU04QyxTQUFTMUMsUUFBUW9CLE9BQU8sQ0FBQzZDLEdBQUcsQ0FBQ3RCO2dCQUNuQyxJQUFJLENBQUNELFFBQVE7b0JBQ1gsTUFBTSxJQUFJWixNQUNSLENBQUMsV0FBVyxFQUFFZ0IsUUFBUSx3Q0FBd0MsRUFBRUgsU0FBUyxxQ0FBcUMsRUFDNUczQyxRQUFRUixVQUFVLENBQUNHLGlCQUFpQixDQUFDQyxjQUFjLEdBQUcsRUFDdkQsQ0FBQztnQkFFTjtnQkFFQSw2Q0FBNkM7Z0JBQzdDLHVGQUF1RjtnQkFDdkYsTUFBTXNELFdBQVdsRCxRQUFRc0YsaUJBQWlCLENBQUN4QztnQkFDM0MsTUFBTUYsU0FBU0YsT0FBT0csT0FBTyxDQUFDNEMsSUFBSSxDQUFDLENBQUNDLElBQU1BLEVBQUV6QyxFQUFFLEtBQUtDO2dCQUNuRCxJQUFJTixRQUFRO29CQUNWLG1EQUFtRDtvQkFDbkRBLE9BQU9HLEtBQUssQ0FBQ3lCLElBQUksQ0FBQzFCO2dCQUNwQixPQUFPO29CQUNMSixPQUFPRyxPQUFPLENBQUMyQixJQUFJLENBQUM7d0JBQUV2QixJQUFJQzt3QkFBVUgsT0FBTzs0QkFBQ0Q7eUJBQVE7b0JBQUM7Z0JBQ3ZEO1lBQ0Y7WUFFQSxLQUFLLE1BQU1KLFVBQVUxQyxRQUFRb0IsT0FBTyxDQUFDMEQsTUFBTSxHQUFJO2dCQUM3QyxLQUFLLE1BQU1sQyxVQUFVRixPQUFPRyxPQUFPLENBQUNpQyxNQUFNLEdBQUk7b0JBQzVDbEMsT0FBT0csS0FBSyxHQUFHSCxPQUFPRyxLQUFLLENBQUM0QyxJQUFJLENBQUMsQ0FBQ0MsR0FBR0MsSUFBTUQsSUFBSUM7Z0JBQ2pEO1lBQ0Y7UUFDRjtRQUNBLE1BQU1DO1lBQ0osMENBQTBDO1lBQzFDOUYsUUFBUXdDLGNBQWM7WUFFdEIsaURBQWlEO1lBQ2pELE1BQU04QixRQUFReUIsR0FBRyxDQUNmO21CQUFJL0YsUUFBUW9CLE9BQU8sQ0FBQzRFLE9BQU87YUFBRyxDQUFDckMsR0FBRyxDQUFDLE9BQU8sQ0FBQ2hCLFVBQVVELE9BQU87Z0JBQzFELEtBQUssTUFBTUUsVUFBVUYsT0FBT0csT0FBTyxDQUFFO29CQUNuQyxLQUFLLE1BQU1DLFdBQVdGLE9BQU9HLEtBQUssQ0FBRTt3QkFDbEMsTUFBTS9DLFFBQVFpRyxvQkFBb0IsQ0FBQ3JELE9BQU9LLEVBQUUsRUFBRUgsU0FBU0g7b0JBQ3pEO2dCQUNGO1lBQ0Y7WUFHRixpRUFBaUU7WUFDakUsSUFBSTNDLFFBQVF5QixVQUFVLENBQUNGLE9BQU8sSUFBSXZCLFFBQVF5QixVQUFVLENBQUNFLGFBQWEsS0FBSyxDQUFDLEdBQUc7Z0JBQ3pFM0IsUUFBUXlCLFVBQVUsQ0FBQ3lFLGVBQWUsR0FBR0MsWUFBWTtvQkFDL0MsTUFBTUMsaUJBQWlCLE1BQU1wRyxRQUFReUIsVUFBVSxDQUFDTSx5QkFBeUI7b0JBRXpFLElBQUlxRSxlQUFlbkUsTUFBTSxJQUFJbUUsZUFBZWpFLElBQUksRUFBRSxNQUFNbkMsUUFBUXlCLFVBQVUsQ0FBQ1ksT0FBTyxDQUFDK0QsZUFBZWpFLElBQUk7Z0JBQ3hHLEdBQUduQyxRQUFReUIsVUFBVSxDQUFDRSxhQUFhO1lBQ3JDO1FBQ0Y7UUFDQSxNQUFNdUQsVUFBU21CLElBQUksRUFBRUMsTUFBTSxFQUFFQywwQkFBMEIsSUFBSTtZQUN6RHZHLFFBQVFOLE1BQU0sQ0FBQytDLE9BQU8sQ0FBQyxDQUFDVSxRQUFVQSxNQUFNcUQsS0FBSyxDQUFDSCxNQUFNQztZQUVwRCxJQUFJQywyQkFBMkJ2RyxRQUFReUIsVUFBVSxDQUFDeUUsZUFBZSxFQUFFTyxjQUFjekcsUUFBUXlCLFVBQVUsQ0FBQ3lFLGVBQWU7WUFFbkgsTUFBTWpILE1BQU07UUFDZDtRQUNBLE1BQU15SCxhQUFZNUQsT0FBTyxFQUFFUSxPQUFPO1lBQ2hDLE1BQU1ILFFBQVFuRCxRQUFRTixNQUFNLENBQUN1RSxHQUFHLENBQUNuQjtZQUVqQyxJQUFJLENBQUNLLE9BQU87Z0JBQ1YsTUFBTSxJQUFJckIsTUFBTSxDQUFDLFdBQVcsRUFBRWdCLFFBQVEsVUFBVSxDQUFDO1lBQ25EO1lBRUEsTUFBTUssTUFBTXdELElBQUksQ0FBQ3JEO1FBQ25CO1FBQ0EsTUFBTTJDLHNCQUFxQi9DLFFBQVEsRUFBRUosT0FBTyxFQUFFSCxRQUFRO1lBQ3BEM0MsUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsbUNBQW1DLEVBQUVkLFNBQVMsRUFBRSxFQUFFSixRQUFRLEVBQUUsRUFBRUgsU0FBUyxDQUFDLENBQUM7WUFDL0YsTUFBTTNDLFFBQVE4RCxRQUFRLENBQUNoQjtRQUN6QjtRQUNBLE1BQU1nQixVQUFTaEIsT0FBZTtZQUM1QixJQUFJSyxRQUFRLElBQUksQ0FBQ3pELE1BQU0sQ0FBQ3VFLEdBQUcsQ0FBQ25CO1lBQzVCOUMsUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsc0JBQXNCLEVBQUViLFFBQVEsYUFBYSxNQUFNLFFBQVEsRUFBRUwsUUFBUSxDQUFDLENBQUM7WUFFN0YsSUFBSSxDQUFDSyxPQUFPO2dCQUNWQSxRQUFRLElBQUloRSxNQUFNO29CQUNoQjhELElBQUlIO29CQUNKdEQsWUFBWTt3QkFDVlUsVUFBVSxJQUFJLENBQUNBLFFBQVE7d0JBQ3ZCQyxTQUFTLElBQUksQ0FBQ0EsT0FBTzt3QkFDckJDLFlBQVksSUFBSSxDQUFDQSxVQUFVO3dCQUMzQk0sT0FBTyxJQUFJLENBQUNBLEtBQUs7d0JBQ2pCRSxhQUFhLElBQUksQ0FBQ0EsV0FBVzt3QkFDN0JuQixLQUFLLElBQUksQ0FBQ0EsR0FBRzt3QkFDYmtCLFNBQVMsSUFBSSxDQUFDQSxPQUFPO29CQUN2QjtvQkFDQVYsUUFBUVgsUUFBUVcsTUFBTSxJQUFJLENBQUM7b0JBQzNCZixRQUFRLElBQUksQ0FBQ0EsTUFBTTtvQkFDbkIyRSxpQkFBaUI7d0JBQ2YsTUFBTTdELFFBQVE4RCxRQUFRLENBQUNoQjtvQkFDekI7b0JBQ0FpQixjQUFjO3dCQUNaL0QsUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsZUFBZSxFQUFFbEIsUUFBUSxTQUFTLENBQUM7d0JBQ3pELE1BQU03RCxNQUFNZSxRQUFRaUIsZUFBZTt3QkFDbkNqQixRQUFRZCxNQUFNLENBQUM4RSxLQUFLLENBQUMsQ0FBQyx3Q0FBd0MsQ0FBQzt3QkFDL0RoRSxRQUFRb0IsT0FBTyxDQUFDNkMsR0FBRyxDQUFDbkIsVUFBVTlDLFFBQVFSLFVBQVUsQ0FBQ0csaUJBQWlCLENBQUNDLGNBQWMsRUFBR3NFLGdCQUFnQixDQUFDQyxLQUFLO29CQUM1RztnQkFDRjtnQkFFQSxJQUFJLElBQUksQ0FBQ2pELGVBQWUsRUFBRTtvQkFDeEJpQyxNQUFNaUIsWUFBWSxHQUFHLE9BQU9kO3dCQUMxQkgsTUFBT2xELE1BQU0sQ0FBQ21ELE9BQU8sR0FBR0QsT0FBUUc7b0JBQ2xDO2dCQUNGO2dCQUVBLElBQUksQ0FBQzVELE1BQU0sQ0FBQzJFLEdBQUcsQ0FBQ3ZCLFNBQVNLO1lBQzNCO1lBRUEsTUFBTVQsU0FBUzFDLFFBQVFvQixPQUFPLENBQUM2QyxHQUFHLENBQUNuQixVQUFVOUMsUUFBUVIsVUFBVSxDQUFDRyxpQkFBaUIsQ0FBQ0MsY0FBYztZQUNoRyxJQUFJLENBQUM4QyxRQUFRO1lBRWIsT0FBTyxNQUFNLElBQUk0QixRQUFRLENBQUNDO2dCQUN4QixzRUFBc0U7Z0JBQ3RFN0IsT0FBT3dCLGdCQUFnQixDQUFDTSxJQUFJLENBQUNEO2dCQUM3QnZFLFFBQVFkLE1BQU0sQ0FBQzhFLEtBQUssQ0FBQyxDQUFDLDhCQUE4QixFQUFFbEIsUUFBUSxFQUFFLENBQUM7Z0JBQ2pFLDJGQUEyRjtnQkFDM0ZLLE9BQU9XO1lBQ1Q7UUFDRjtRQUNBLE1BQU04QyxNQUFLOUQsT0FBZTtZQUN4QixNQUFNSyxRQUFRLElBQUksQ0FBQ3pELE1BQU0sQ0FBQ3VFLEdBQUcsQ0FBQ25CO1lBQzlCLElBQUksQ0FBQ0ssT0FBTztnQkFDVixPQUFPbkQsUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsb0NBQW9DLEVBQUVsQixRQUFRLENBQUMsQ0FBQztZQUMvRTtZQUVBOUMsUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsc0JBQXNCLEVBQUVsQixRQUFRLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUNwRCxNQUFNLENBQUNtSCxNQUFNLENBQUMvRDtZQUNuQixNQUFNSyxNQUFNK0IsUUFBUTtRQUN0QjtRQUNBLE1BQU1yQixpQkFBZ0JpRCxRQUFnQjtZQUNwQzlHLFFBQVFkLE1BQU0sQ0FBQzhFLEtBQUssQ0FBQyxDQUFDLDZCQUE2QixDQUFDO1FBQ3BELG9HQUFvRztRQUNwRyxzQkFBc0I7UUFFdEIsMENBQTBDO1FBQzFDLDBDQUEwQztRQUMxQyxLQUFLO1FBQ1A7UUFFQSw2QkFBNkI7UUFFN0IrQyxrQkFBaUJDLE9BQU8sRUFBRXBHLFdBQVc7WUFDbkMsd0VBQXdFO1lBQ3hFLElBQUksQ0FBQ0EsYUFBYUEsY0FBY1osUUFBUVksV0FBVztZQUNuRCxzREFBc0Q7WUFDdEQsSUFBSUEsZ0JBQWdCLEdBQUc7Z0JBQ3JCWixRQUFRZCxNQUFNLENBQUM4RSxLQUFLLENBQUMsQ0FBQyxvQ0FBb0MsQ0FBQztnQkFDM0QsT0FBTztZQUNUO1lBRUFoRSxRQUFRZCxNQUFNLENBQUM4RSxLQUFLLENBQUMsQ0FBQyxxQ0FBcUMsRUFBRWdELFFBQVEsZUFBZSxFQUFFcEcsWUFBWSxDQUFDLENBQUM7WUFDcEcsT0FBT3FHLE9BQU8sQUFBQ0MsQ0FBQUEsT0FBT0YsWUFBWSxHQUFHLEFBQUQsSUFBS0UsT0FBT3RHO1FBQ2xEO1FBRUEsTUFBTXVHLGtCQUFpQkgsT0FBTyxFQUFFSSxTQUFTLEVBQUU5SCxPQUFPO1lBQ2hELE1BQU13RCxVQUFVOUMsUUFBUStHLGdCQUFnQixDQUFDQztZQUV6Q2hILFFBQVFkLE1BQU0sQ0FBQzhFLEtBQUssQ0FBQyxDQUFDLG9DQUFvQyxFQUFFZ0QsUUFBUSxZQUFZLEVBQUVJLFVBQVUsQ0FBQztZQUU3RixNQUFNcEgsUUFBUTBHLFdBQVcsQ0FBQzVELFNBQVM7Z0JBQ2pDdUUsSUFBSXRJLGVBQWV1SSxnQkFBZ0I7Z0JBQ25DN0QsR0FBRztvQkFDRDhELFVBQVVQLFFBQVFRLFFBQVE7b0JBQzFCQyxZQUFZTCxVQUFVSSxRQUFRO29CQUM5QkUsV0FBV3BJLFNBQVNxSSxZQUFZO29CQUNoQ0MsV0FBV3RJLFNBQVN1SSxZQUFZO2dCQUNsQztZQUNGO1FBQ0Y7UUFFQSxNQUFNQyxlQUFjQyxJQUFJO1lBQ3RCL0gsUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsOEJBQThCLEVBQUVnRSxLQUFLQyxTQUFTLENBQUNGLE1BQU0sQ0FBQztZQUU1RSxNQUFNekQsUUFBUXlCLEdBQUcsQ0FDZjttQkFBSS9GLFFBQVFOLE1BQU0sQ0FBQ29GLE1BQU07YUFBRyxDQUFDbkIsR0FBRyxDQUFDLE9BQU9SO2dCQUN0Q25ELFFBQVFrSSxlQUFlLENBQUMvRSxNQUFNRixFQUFFLEVBQUU4RTtZQUNwQztRQUVKO1FBRUEsTUFBTUcsaUJBQWdCcEYsT0FBTyxFQUFFaUYsSUFBSTtZQUNqQy9ILFFBQVFkLE1BQU0sQ0FBQzhFLEtBQUssQ0FBQyxDQUFDLG1DQUFtQyxFQUFFbEIsUUFBUSxVQUFVLEVBQUVrRixLQUFLQyxTQUFTLENBQUNGLE1BQU0sQ0FBQztZQUVyRyxNQUFNL0gsUUFBUTBHLFdBQVcsQ0FBQzVELFNBQVM7Z0JBQ2pDdUUsSUFBSXRJLGVBQWVvSixjQUFjO2dCQUNqQzFFLEdBQUc7b0JBQ0QyRSxPQUFPO29CQUNQQyxLQUFLO29CQUNMQyxZQUFZUCxLQUFLTyxVQUFVO29CQUMzQkMsUUFBUVIsS0FBS1EsTUFBTTtnQkFDckI7WUFDRjtRQUNGO1FBRUEsTUFBTWpILGdCQUFlMEYsT0FBTyxFQUFFMUgsT0FBTztZQUNuQyxNQUFNd0QsVUFBVTlDLFFBQVErRyxnQkFBZ0IsQ0FBQ0M7WUFFekMsSUFBSWhILFFBQVFHLE9BQU8sSUFBSyxDQUFBLENBQUNiLFNBQVNrSixTQUFTbEosUUFBUWtKLEtBQUssR0FBRyxDQUFBLEtBQU0sQ0FBRXhJLENBQUFBLFFBQVFHLE9BQU8sR0FBR3JCLGVBQWUySixZQUFZLEFBQUQsR0FDN0csTUFBTSxJQUFJM0csTUFBTTtZQUVsQjlCLFFBQVFkLE1BQU0sQ0FBQzhFLEtBQUssQ0FBQyxDQUFDLGtDQUFrQyxFQUFFZ0QsUUFBUSxVQUFVLEVBQUVnQixLQUFLQyxTQUFTLENBQUMzSSxTQUFTLENBQUM7WUFFdkcsSUFBSUEsU0FBU29KLFNBQVNDLFFBQVE7Z0JBQzVCM0ksUUFBUWQsTUFBTSxDQUFDOEUsS0FBSyxDQUFDLENBQUMsa0NBQWtDLEVBQUVnRCxRQUFRLGdEQUFnRCxFQUFFMUgsUUFBUW9KLE9BQU8sQ0FBQ0MsTUFBTSxDQUFDLENBQUM7Z0JBRTVJckosUUFBUWtKLEtBQUssR0FBR2xKLFFBQVFvSixPQUFPLENBQUNDLE1BQU07WUFDeEM7WUFFQSxNQUFNQyxVQUNKLENBQUM1SSxRQUFRcUIsS0FBSyxDQUFDQyxjQUFjLENBQUNDLE9BQU8sSUFBSSxDQUFDakMsU0FBU3VKLFFBQy9DLEVBQUUsR0FDRixJQUFJdkUsUUFBMkMsQ0FBQ0MsU0FBU3VFO2dCQUN2RCx1QkFBdUI7Z0JBQ3ZCLElBQUksQ0FBQzlJLFFBQVFxQixLQUFLLENBQUNDLGNBQWMsQ0FBQ0MsT0FBTyxJQUFJLENBQUNqQyxTQUFTdUosT0FBTztvQkFDNURDLE9BQU8sSUFBSWhILE1BQU07b0JBQ2pCO2dCQUNGO2dCQUVBOUIsUUFBUXFCLEtBQUssQ0FBQ0MsY0FBYyxDQUFDRSxPQUFPLENBQUM2QyxHQUFHLENBQUMvRSxRQUFRdUosS0FBSyxFQUFFO29CQUN0REEsT0FBT3ZKLFFBQVF1SixLQUFLO29CQUNwQnRFO29CQUNBcUUsU0FBUyxFQUFFO2dCQUNiO1lBQ0Y7WUFFTixNQUFNNUksUUFBUTBHLFdBQVcsQ0FBQzVELFNBQVM7Z0JBQ2pDdUUsSUFBSXRJLGVBQWVnSyxtQkFBbUI7Z0JBQ3RDdEYsR0FBRztvQkFDRDhELFVBQVVQLFFBQVFRLFFBQVE7b0JBQzFCLHNFQUFzRTtvQkFDdEV3QixPQUFPMUosU0FBUzBKLFNBQVUxSixDQUFBQSxTQUFTa0osUUFBUVMsWUFBWSxFQUFDO29CQUN4RFQsT0FBT2xKLFNBQVNrSixTQUFTO29CQUN6QlUsV0FBVzVKLFNBQVM0SixhQUFhO29CQUNqQ0MsVUFBVTdKLFNBQVNvSixTQUFTL0UsSUFBSSxDQUFDVixLQUFPQSxHQUFHdUUsUUFBUTtvQkFDbkRxQixPQUFPdkosU0FBU3VKO2dCQUNsQjtZQUNGO1lBRUEsT0FBTyxNQUFNRDtRQUNmO1FBRUEsTUFBTVEsbUJBQWtCcEMsT0FBTztZQUM3QixNQUFNbEUsVUFBVTlDLFFBQVErRyxnQkFBZ0IsQ0FBQ0M7WUFFekNoSCxRQUFRZCxNQUFNLENBQUM4RSxLQUFLLENBQUMsQ0FBQyxxQ0FBcUMsRUFBRWdELFFBQVEsT0FBTyxFQUFFbEUsUUFBUSxDQUFDO1lBRXZGLE1BQU05QyxRQUFRMEcsV0FBVyxDQUFDNUQsU0FBUztnQkFDakN1RSxJQUFJdEksZUFBZXVJLGdCQUFnQjtnQkFDbkM3RCxHQUFHO29CQUNEOEQsVUFBVVAsUUFBUVEsUUFBUTtvQkFDMUJDLFlBQVk7b0JBQ1pDLFdBQVc7b0JBQ1hFLFdBQVc7Z0JBQ2I7WUFDRjtRQUNGO0lBQ0Y7SUFFQSxPQUFPNUg7QUFDVCJ9
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export var ShardState;
|
|
2
|
+
(function(ShardState) {
|
|
3
|
+
/** Shard is fully connected to the gateway and receiving events from Discord. */ ShardState[ShardState["Connected"] = 0] = "Connected";
|
|
4
|
+
/** Shard started to connect to the gateway. This is only used if the shard is not currently trying to identify or resume. */ ShardState[ShardState["Connecting"] = 1] = "Connecting";
|
|
5
|
+
/** Shard got disconnected and reconnection actions have been started. */ ShardState[ShardState["Disconnected"] = 2] = "Disconnected";
|
|
6
|
+
/** The shard is connected to the gateway but only heartbeating. At this state the shard has not been identified with discord. */ ShardState[ShardState["Unidentified"] = 3] = "Unidentified";
|
|
7
|
+
/** Shard is trying to identify with the gateway to create a new session. */ ShardState[ShardState["Identifying"] = 4] = "Identifying";
|
|
8
|
+
/** Shard is trying to resume a session with the gateway. */ ShardState[ShardState["Resuming"] = 5] = "Resuming";
|
|
9
|
+
/** Shard got shut down studied or due to a not (self) fixable error and may not attempt to reconnect on its own. */ ShardState[ShardState["Offline"] = 6] = "Offline";
|
|
10
|
+
})(ShardState || (ShardState = {}));
|
|
11
|
+
export var ShardSocketCloseCodes;
|
|
12
|
+
(function(ShardSocketCloseCodes) {
|
|
13
|
+
/** A regular Shard shutdown. */ ShardSocketCloseCodes[ShardSocketCloseCodes["Shutdown"] = 3000] = "Shutdown";
|
|
14
|
+
/** A resume has been requested and therefore the old connection needs to be closed. */ ShardSocketCloseCodes[ShardSocketCloseCodes["ResumeClosingOldConnection"] = 3024] = "ResumeClosingOldConnection";
|
|
15
|
+
/** Did not receive a heartbeat ACK in time.
|
|
16
|
+
* Closing the shard and creating a new session.
|
|
17
|
+
*/ ShardSocketCloseCodes[ShardSocketCloseCodes["ZombiedConnection"] = 3010] = "ZombiedConnection";
|
|
18
|
+
/** Discordeno's gateway tests hae been finished, therefore the Shard can be turned off. */ ShardSocketCloseCodes[ShardSocketCloseCodes["TestingFinished"] = 3064] = "TestingFinished";
|
|
19
|
+
/** Special close code reserved for Discordeno's zero-downtime resharding system. */ ShardSocketCloseCodes[ShardSocketCloseCodes["Resharded"] = 3065] = "Resharded";
|
|
20
|
+
/** Shard is re-identifying therefore the old connection needs to be closed. */ ShardSocketCloseCodes[ShardSocketCloseCodes["ReIdentifying"] = 3066] = "ReIdentifying";
|
|
21
|
+
})(ShardSocketCloseCodes || (ShardSocketCloseCodes = {}));
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eXBlcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEFjdGl2aXR5VHlwZXMsIENhbWVsaXplLCBEaXNjb3JkQWN0aXZpdHksIERpc2NvcmRHYXRld2F5UGF5bG9hZCwgR2F0ZXdheU9wY29kZXMsIFByZXNlbmNlU3RhdHVzIH0gZnJvbSAnQGRpc2NvcmRlbm8vdHlwZXMnXG5pbXBvcnQgdHlwZSBTaGFyZCBmcm9tICcuL1NoYXJkLmpzJ1xuXG5leHBvcnQgZW51bSBTaGFyZFN0YXRlIHtcbiAgLyoqIFNoYXJkIGlzIGZ1bGx5IGNvbm5lY3RlZCB0byB0aGUgZ2F0ZXdheSBhbmQgcmVjZWl2aW5nIGV2ZW50cyBmcm9tIERpc2NvcmQuICovXG4gIENvbm5lY3RlZCA9IDAsXG4gIC8qKiBTaGFyZCBzdGFydGVkIHRvIGNvbm5lY3QgdG8gdGhlIGdhdGV3YXkuIFRoaXMgaXMgb25seSB1c2VkIGlmIHRoZSBzaGFyZCBpcyBub3QgY3VycmVudGx5IHRyeWluZyB0byBpZGVudGlmeSBvciByZXN1bWUuICovXG4gIENvbm5lY3RpbmcgPSAxLFxuICAvKiogU2hhcmQgZ290IGRpc2Nvbm5lY3RlZCBhbmQgcmVjb25uZWN0aW9uIGFjdGlvbnMgaGF2ZSBiZWVuIHN0YXJ0ZWQuICovXG4gIERpc2Nvbm5lY3RlZCA9IDIsXG4gIC8qKiBUaGUgc2hhcmQgaXMgY29ubmVjdGVkIHRvIHRoZSBnYXRld2F5IGJ1dCBvbmx5IGhlYXJ0YmVhdGluZy4gQXQgdGhpcyBzdGF0ZSB0aGUgc2hhcmQgaGFzIG5vdCBiZWVuIGlkZW50aWZpZWQgd2l0aCBkaXNjb3JkLiAqL1xuICBVbmlkZW50aWZpZWQgPSAzLFxuICAvKiogU2hhcmQgaXMgdHJ5aW5nIHRvIGlkZW50aWZ5IHdpdGggdGhlIGdhdGV3YXkgdG8gY3JlYXRlIGEgbmV3IHNlc3Npb24uICovXG4gIElkZW50aWZ5aW5nID0gNCxcbiAgLyoqIFNoYXJkIGlzIHRyeWluZyB0byByZXN1bWUgYSBzZXNzaW9uIHdpdGggdGhlIGdhdGV3YXkuICovXG4gIFJlc3VtaW5nID0gNSxcbiAgLyoqIFNoYXJkIGdvdCBzaHV0IGRvd24gc3R1ZGllZCBvciBkdWUgdG8gYSBub3QgKHNlbGYpIGZpeGFibGUgZXJyb3IgYW5kIG1heSBub3QgYXR0ZW1wdCB0byByZWNvbm5lY3Qgb24gaXRzIG93bi4gKi9cbiAgT2ZmbGluZSA9IDYsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcmRHYXRld2F5Q29uZmlnIHtcbiAgLyoqIFdoZXRoZXIgaW5jb21pbmcgcGF5bG9hZHMgYXJlIGNvbXByZXNzZWQgdXNpbmcgemxpYi5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGNvbXByZXNzOiBib29sZWFuXG4gIC8qKiBUaGUgY2FsY3VsYXRlZCBpbnRlbnQgdmFsdWUgb2YgdGhlIGV2ZW50cyB3aGljaCB0aGUgc2hhcmQgc2hvdWxkIHJlY2VpdmUuXG4gICAqXG4gICAqIEBkZWZhdWx0IDBcbiAgICovXG4gIGludGVudHM6IG51bWJlclxuICAvKiogSWRlbnRpZnkgcHJvcGVydGllcyB0byB1c2UgKi9cbiAgcHJvcGVydGllczoge1xuICAgIC8qKiBPcGVyYXRpbmcgc3lzdGVtIHRoZSBzaGFyZCBydW5zIG9uLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgXCJkYXJ3aW5cIiB8IFwibGludXhcIiB8IFwid2luZG93c1wiXG4gICAgICovXG4gICAgb3M6IHN0cmluZ1xuICAgIC8qKiBUaGUgXCJicm93c2VyXCIgd2hlcmUgdGhpcyBzaGFyZCBpcyBydW5uaW5nIG9uLlxuICAgICAqXG4gICAgICogQGRlZmF1bHQgXCJEaXNjb3JkZW5vXCJcbiAgICAgKi9cbiAgICBicm93c2VyOiBzdHJpbmdcbiAgICAvKiogVGhlIGRldmljZSBvbiB3aGljaCB0aGUgc2hhcmQgaXMgcnVubmluZy5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IFwiRGlzY29yZGVub1wiXG4gICAgICovXG4gICAgZGV2aWNlOiBzdHJpbmdcbiAgfVxuICAvKiogQm90IHRva2VuIHdoaWNoIGlzIHVzZWQgdG8gY29ubmVjdCB0byBEaXNjb3JkICovXG4gIHRva2VuOiBzdHJpbmdcbiAgLyoqIFRoZSBVUkwgb2YgdGhlIGdhdGV3YXkgd2hpY2ggc2hvdWxkIGJlIGNvbm5lY3RlZCB0by5cbiAgICpcbiAgICogQGRlZmF1bHQgXCJ3c3M6Ly9nYXRld2F5LmRpc2NvcmQuZ2dcIlxuICAgKi9cbiAgdXJsOiBzdHJpbmdcbiAgLyoqIFRoZSBnYXRld2F5IHZlcnNpb24gd2hpY2ggc2hvdWxkIGJlIHVzZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IDEwXG4gICAqL1xuICB2ZXJzaW9uOiBudW1iZXJcbiAgLyoqXG4gICAqIFRoZSB0b3RhbCBudW1iZXIgb2Ygc2hhcmRzIHRvIGNvbm5lY3QgdG8gYWNyb3NzIHRoZSBlbnRpcmUgYm90LlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICB0b3RhbFNoYXJkczogbnVtYmVyXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcmRIZWFydCB7XG4gIC8qKiBXaGV0aGVyIG9yIG5vdCB0aGUgaGVhcnRiZWF0IHdhcyBhY2tub3dsZWRnZWQgYnkgRGlzY29yZCBpbiB0aW1lLiAqL1xuICBhY2tub3dsZWRnZWQ6IGJvb2xlYW5cbiAgLyoqIEludGVydmFsIGJldHdlZW4gaGVhcnRiZWF0cyByZXF1ZXN0ZWQgYnkgRGlzY29yZC4gKi9cbiAgaW50ZXJ2YWw6IG51bWJlclxuICAvKiogSWQgb2YgdGhlIGludGVydmFsLCB3aGljaCBpcyB1c2VkIGZvciBzZW5kaW5nIHRoZSBoZWFydGJlYXRzLiAqL1xuICBpbnRlcnZhbElkPzogTm9kZUpTLlRpbWVvdXRcbiAgLyoqIFVuaXggKGluIG1pbGxpc2Vjb25kcykgdGltZXN0YW1wIHdoZW4gdGhlIGxhc3QgaGVhcnRiZWF0IEFDSyB3YXMgcmVjZWl2ZWQgZnJvbSBEaXNjb3JkLiAqL1xuICBsYXN0QWNrPzogbnVtYmVyXG4gIC8qKiBVbml4IHRpbWVzdGFtcCAoaW4gbWlsbGlzZWNvbmRzKSB3aGVuIHRoZSBsYXN0IGhlYXJ0YmVhdCB3YXMgc2VudC4gKi9cbiAgbGFzdEJlYXQ/OiBudW1iZXJcbiAgLyoqIFJvdW5kIHRyaXAgdGltZSAoaW4gbWlsbGlzZWNvbmRzKSBmcm9tIFNoYXJkIHRvIERpc2NvcmQgYW5kIGJhY2suXG4gICAqIENhbGN1bGF0ZWQgdXNpbmcgdGhlIGhlYXJ0YmVhdCBzeXN0ZW0uXG4gICAqIE5vdGU6IHRoaXMgdmFsdWUgaXMgdW5kZWZpbmVkIHVudGlsIHRoZSBmaXJzdCBoZWFydGJlYXQgdG8gRGlzY29yZCBoYXMgaGFwcGVuZWQuXG4gICAqL1xuICBydHQ/OiBudW1iZXJcbiAgLyoqIElkIG9mIHRoZSB0aW1lb3V0IHdoaWNoIGlzIHVzZWQgZm9yIHNlbmRpbmcgdGhlIGZpcnN0IGhlYXJ0YmVhdCB0byBEaXNjb3JkIHNpbmNlIGl0J3MgXCJzcGVjaWFsXCIuICovXG4gIHRpbWVvdXRJZD86IE5vZGVKUy5UaW1lb3V0XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcmRFdmVudHMge1xuICAvKiogQSBoZWFydGJlYXQgaGFzIGJlZW4gc2VuZC4gKi9cbiAgaGVhcnRiZWF0PzogKHNoYXJkOiBTaGFyZCkgPT4gdW5rbm93blxuICAvKiogQSBoZWFydGJlYXQgQUNLIHdhcyByZWNlaXZlZC4gKi9cbiAgaGVhcnRiZWF0QWNrPzogKHNoYXJkOiBTaGFyZCkgPT4gdW5rbm93blxuICAvKiogU2hhcmQgaGFzIHJlY2VpdmVkIGEgSGVsbG8gcGF5bG9hZC4gKi9cbiAgaGVsbG8/OiAoc2hhcmQ6IFNoYXJkKSA9PiB1bmtub3duXG4gIC8qKiBUaGUgU2hhcmRzIHNlc3Npb24gaGFzIGJlZW4gaW52YWxpZGF0ZWQuICovXG4gIGludmFsaWRTZXNzaW9uPzogKHNoYXJkOiBTaGFyZCwgcmVzdW1hYmxlOiBib29sZWFuKSA9PiB1bmtub3duXG4gIC8qKiBUaGUgc2hhcmQgaGFzIHN0YXJ0ZWQgYSByZXN1bWUgYWN0aW9uLiAqL1xuICByZXN1bWluZz86IChzaGFyZDogU2hhcmQpID0+IHVua25vd25cbiAgLyoqIFRoZSBzaGFyZCBoYXMgc3VjY2Vzc2Z1bGx5IHJlc3VtZWQgYW4gb2xkIHNlc3Npb24uICovXG4gIHJlc3VtZWQ/OiAoc2hhcmQ6IFNoYXJkKSA9PiB1bmtub3duXG4gIC8qKiBEaXNjb3JkIGhhcyByZXF1ZXN0ZWQgdGhlIFNoYXJkIHRvIHJlY29ubmVjdC4gKi9cbiAgcmVxdWVzdGVkUmVjb25uZWN0PzogKHNoYXJkOiBTaGFyZCkgPT4gdW5rbm93blxuICAvKiogVGhlIHNoYXJkIHN0YXJ0ZWQgdG8gY29ubmVjdCB0byBEaXNjb3JkJ3MgZ2F0ZXdheS4gKi9cbiAgY29ubmVjdGluZz86IChzaGFyZDogU2hhcmQpID0+IHVua25vd25cbiAgLyoqIFRoZSBzaGFyZCBpcyBjb25uZWN0ZWQgd2l0aCBEaXNjb3JkJ3MgZ2F0ZXdheS4gKi9cbiAgY29ubmVjdGVkPzogKHNoYXJkOiBTaGFyZCkgPT4gdW5rbm93blxuICAvKiogVGhlIHNoYXJkIGhhcyBiZWVuIGRpc2Nvbm5lY3RlZCBmcm9tIERpc2NvcmQncyBnYXRld2F5LiAqL1xuICBkaXNjb25uZWN0ZWQ/OiAoc2hhcmQ6IFNoYXJkKSA9PiB1bmtub3duXG4gIC8qKiBUaGUgc2hhcmQgaGFzIHN0YXJ0ZWQgdG8gaWRlbnRpZnkgaXRzZWxmIHRvIERpc2NvcmQuICovXG4gIGlkZW50aWZ5aW5nPzogKHNoYXJkOiBTaGFyZCkgPT4gdW5rbm93blxuICAvKiogVGhlIHNoYXJkIGhhcyBzdWNjZXNzZnVsbHkgYmVlbiBpZGVudGlmaWVkIGl0c2VsZiB3aXRoIERpc2NvcmQuICovXG4gIGlkZW50aWZpZWQ/OiAoc2hhcmQ6IFNoYXJkKSA9PiB1bmtub3duXG4gIC8qKiBUaGUgc2hhcmQgaGFzIHJlY2VpdmVkIGEgbWVzc2FnZSBmcm9tIERpc2NvcmQuICovXG4gIG1lc3NhZ2U/OiAoc2hhcmQ6IFNoYXJkLCBwYXlsb2FkOiBDYW1lbGl6ZTxEaXNjb3JkR2F0ZXdheVBheWxvYWQ+KSA9PiB1bmtub3duXG59XG5cbmV4cG9ydCBlbnVtIFNoYXJkU29ja2V0Q2xvc2VDb2RlcyB7XG4gIC8qKiBBIHJlZ3VsYXIgU2hhcmQgc2h1dGRvd24uICovXG4gIFNodXRkb3duID0gMzAwMCxcbiAgLyoqIEEgcmVzdW1lIGhhcyBiZWVuIHJlcXVlc3RlZCBhbmQgdGhlcmVmb3JlIHRoZSBvbGQgY29ubmVjdGlvbiBuZWVkcyB0byBiZSBjbG9zZWQuICovXG4gIFJlc3VtZUNsb3NpbmdPbGRDb25uZWN0aW9uID0gMzAyNCxcbiAgLyoqIERpZCBub3QgcmVjZWl2ZSBhIGhlYXJ0YmVhdCBBQ0sgaW4gdGltZS5cbiAgICogQ2xvc2luZyB0aGUgc2hhcmQgYW5kIGNyZWF0aW5nIGEgbmV3IHNlc3Npb24uXG4gICAqL1xuICBab21iaWVkQ29ubmVjdGlvbiA9IDMwMTAsXG4gIC8qKiBEaXNjb3JkZW5vJ3MgZ2F0ZXdheSB0ZXN0cyBoYWUgYmVlbiBmaW5pc2hlZCwgdGhlcmVmb3JlIHRoZSBTaGFyZCBjYW4gYmUgdHVybmVkIG9mZi4gKi9cbiAgVGVzdGluZ0ZpbmlzaGVkID0gMzA2NCxcbiAgLyoqIFNwZWNpYWwgY2xvc2UgY29kZSByZXNlcnZlZCBmb3IgRGlzY29yZGVubydzIHplcm8tZG93bnRpbWUgcmVzaGFyZGluZyBzeXN0ZW0uICovXG4gIFJlc2hhcmRlZCA9IDMwNjUsXG4gIC8qKiBTaGFyZCBpcyByZS1pZGVudGlmeWluZyB0aGVyZWZvcmUgdGhlIG9sZCBjb25uZWN0aW9uIG5lZWRzIHRvIGJlIGNsb3NlZC4gKi9cbiAgUmVJZGVudGlmeWluZyA9IDMwNjYsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2hhcmRTb2NrZXRSZXF1ZXN0IHtcbiAgLyoqIFRoZSBPUC1Db2RlIGZvciB0aGUgcGF5bG9hZCB0byBzZW5kLiAqL1xuICBvcDogR2F0ZXdheU9wY29kZXNcbiAgLyoqIFBheWxvYWQgZGF0YS4gKi9cbiAgZDogdW5rbm93blxufVxuXG4vKiogaHR0cHM6Ly9kaXNjb3JkLmNvbS9kZXZlbG9wZXJzL2RvY3MvdG9waWNzL2dhdGV3YXktZXZlbnRzI3VwZGF0ZS1wcmVzZW5jZSAqL1xuZXhwb3J0IGludGVyZmFjZSBCb3RTdGF0dXNVcGRhdGUge1xuICAvLyAvKiogVW5peCB0aW1lIChpbiBtaWxsaXNlY29uZHMpIG9mIHdoZW4gdGhlIGNsaWVudCB3ZW50IGlkbGUsIG9yIG51bGwgaWYgdGhlIGNsaWVudCBpcyBub3QgaWRsZSAqL1xuICBzaW5jZTogbnVtYmVyIHwgbnVsbFxuICAvKiogVGhlIHVzZXIncyBhY3Rpdml0aWVzICovXG4gIGFjdGl2aXRpZXM6IEJvdEFjdGl2aXR5W11cbiAgLyoqIFRoZSB1c2VyJ3MgbmV3IHN0YXR1cyAqL1xuICBzdGF0dXM6IGtleW9mIHR5cGVvZiBQcmVzZW5jZVN0YXR1c1xufVxuXG4vKiogaHR0cHM6Ly9kaXNjb3JkLmNvbS9kZXZlbG9wZXJzL2RvY3MvdG9waWNzL2dhdGV3YXktZXZlbnRzI2FjdGl2aXR5LW9iamVjdCAqL1xuZXhwb3J0IGludGVyZmFjZSBCb3RBY3Rpdml0eSB7XG4gIG5hbWU6IHN0cmluZ1xuICB0eXBlOiBBY3Rpdml0eVR5cGVzXG4gIHVybD86IHN0cmluZ1xufVxuXG4vKiogaHR0cHM6Ly9kaXNjb3JkLmNvbS9kZXZlbG9wZXJzL2RvY3MvdG9waWNzL2dhdGV3YXkjdXBkYXRlLXZvaWNlLXN0YXRlICovXG5leHBvcnQgaW50ZXJmYWNlIFVwZGF0ZVZvaWNlU3RhdGUge1xuICAvKiogaWQgb2YgdGhlIGd1aWxkICovXG4gIGd1aWxkSWQ6IHN0cmluZ1xuICAvKiogaWQgb2YgdGhlIHZvaWNlIGNoYW5uZWwgY2xpZW50IHdhbnRzIHRvIGpvaW4gKG51bGwgaWYgZGlzY29ubmVjdGluZykgKi9cbiAgY2hhbm5lbElkOiBzdHJpbmcgfCBudWxsXG4gIC8qKiBJcyB0aGUgY2xpZW50IG11dGVkICovXG4gIHNlbGZNdXRlOiBib29sZWFuXG4gIC8qKiBJcyB0aGUgY2xpZW50IGRlYWZlbmVkICovXG4gIHNlbGZEZWFmOiBib29sZWFuXG59XG5cbi8qKiBodHRwczovL2Rpc2NvcmQuY29tL2RldmVsb3BlcnMvZG9jcy90b3BpY3MvZ2F0ZXdheS1ldmVudHMjdXBkYXRlLXByZXNlbmNlICovXG5leHBvcnQgaW50ZXJmYWNlIFN0YXR1c1VwZGF0ZSB7XG4gIC8vIC8qKiBVbml4IHRpbWUgKGluIG1pbGxpc2Vjb25kcykgb2Ygd2hlbiB0aGUgY2xpZW50IHdlbnQgaWRsZSwgb3IgbnVsbCBpZiB0aGUgY2xpZW50IGlzIG5vdCBpZGxlICovXG4gIC8vIHNpbmNlOiBudW1iZXIgfCBudWxsO1xuICAvKiogVGhlIHVzZXIncyBhY3Rpdml0aWVzICovXG4gIGFjdGl2aXRpZXM/OiBDYW1lbGl6ZTxPbWl0PERpc2NvcmRBY3Rpdml0eSwgJ2NyZWF0ZWRfYXQnPltdPlxuICAvKiogVGhlIHVzZXIncyBuZXcgc3RhdHVzICovXG4gIHN0YXR1czoga2V5b2YgdHlwZW9mIFByZXNlbmNlU3RhdHVzXG4gIC8vIC8qKiBXaGV0aGVyIG9yIG5vdCB0aGUgY2xpZW50IGlzIGFmayAqL1xuICAvLyBhZms6IGJvb2xlYW47XG59XG4iXSwibmFtZXMiOlsiU2hhcmRTdGF0ZSIsIlNoYXJkU29ja2V0Q2xvc2VDb2RlcyJdLCJtYXBwaW5ncyI6IjtVQUdZQTtJQUNWLCtFQUErRTtJQUUvRSwySEFBMkg7SUFFM0gsdUVBQXVFO0lBRXZFLCtIQUErSDtJQUUvSCwwRUFBMEU7SUFFMUUsMERBQTBEO0lBRTFELGtIQUFrSDtHQWJ4R0EsZUFBQUE7O1VBa0hBQztJQUNWLDhCQUE4QjtJQUU5QixxRkFBcUY7SUFFckY7O0dBRUM7SUFFRCx5RkFBeUY7SUFFekYsa0ZBQWtGO0lBRWxGLDZFQUE2RTtHQWJuRUEsMEJBQUFBIn0=
|