@discordeno/gateway 19.0.0-next.fb8af2b → 19.0.0-next.fb9aac0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Shard.cjs +250 -89
- package/dist/cjs/manager.cjs +98 -58
- package/dist/cjs/types.cjs +31 -8
- package/dist/esm/Shard.js +211 -91
- package/dist/esm/manager.js +98 -58
- package/dist/esm/types.js +28 -8
- package/dist/types/Shard.d.ts +36 -11
- package/dist/types/Shard.d.ts.map +1 -1
- package/dist/types/manager.d.ts +60 -23
- package/dist/types/manager.d.ts.map +1 -1
- package/dist/types/types.d.ts +37 -2
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +19 -16
package/dist/cjs/Shard.cjs
CHANGED
|
@@ -16,6 +16,7 @@ _export(exports, {
|
|
|
16
16
|
return _default;
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
|
+
const _nodebuffer = require("node:buffer");
|
|
19
20
|
const _nodezlib = require("node:zlib");
|
|
20
21
|
const _types = require("@discordeno/types");
|
|
21
22
|
const _utils = require("@discordeno/utils");
|
|
@@ -26,6 +27,57 @@ function _interop_require_default(obj) {
|
|
|
26
27
|
default: obj
|
|
27
28
|
};
|
|
28
29
|
}
|
|
30
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
31
|
+
if (typeof WeakMap !== "function") return null;
|
|
32
|
+
var cacheBabelInterop = new WeakMap();
|
|
33
|
+
var cacheNodeInterop = new WeakMap();
|
|
34
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
35
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
36
|
+
})(nodeInterop);
|
|
37
|
+
}
|
|
38
|
+
function _interop_require_wildcard(obj, nodeInterop) {
|
|
39
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
40
|
+
return obj;
|
|
41
|
+
}
|
|
42
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
43
|
+
return {
|
|
44
|
+
default: obj
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
48
|
+
if (cache && cache.has(obj)) {
|
|
49
|
+
return cache.get(obj);
|
|
50
|
+
}
|
|
51
|
+
var newObj = {
|
|
52
|
+
__proto__: null
|
|
53
|
+
};
|
|
54
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
55
|
+
for(var key in obj){
|
|
56
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
57
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
58
|
+
if (desc && (desc.get || desc.set)) {
|
|
59
|
+
Object.defineProperty(newObj, key, desc);
|
|
60
|
+
} else {
|
|
61
|
+
newObj[key] = obj[key];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
newObj.default = obj;
|
|
66
|
+
if (cache) {
|
|
67
|
+
cache.set(obj, newObj);
|
|
68
|
+
}
|
|
69
|
+
return newObj;
|
|
70
|
+
}
|
|
71
|
+
const ZLIB_SYNC_FLUSH = new Uint8Array([
|
|
72
|
+
0x0,
|
|
73
|
+
0x0,
|
|
74
|
+
0xff,
|
|
75
|
+
0xff
|
|
76
|
+
]);
|
|
77
|
+
let fzstd;
|
|
78
|
+
/** Since fzstd is an optional dependency, we need to import it lazily */ async function getFZStd() {
|
|
79
|
+
return fzstd ??= await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("fzstd")));
|
|
80
|
+
}
|
|
29
81
|
let DiscordenoShard = class DiscordenoShard {
|
|
30
82
|
constructor(options){
|
|
31
83
|
/** The maximum of requests which can be send to discord per rate limit tick. Typically this value should not be changed. */ this.maxRequestsPerRateLimitTick = 120;
|
|
@@ -36,6 +88,9 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
36
88
|
/** The shard related event handlers. */ this.events = {};
|
|
37
89
|
/** Cache for pending gateway requests which should have been send while the gateway went offline. */ this.offlineSendQueue = [];
|
|
38
90
|
/** Resolve internal waiting states. Mapped by SelectedEvents => ResolveFunction */ this.resolves = new Map();
|
|
91
|
+
/** Text decoder used for compressed payloads */ this.textDecoder = new TextDecoder();
|
|
92
|
+
/** ZLib inflate buffer */ this.inflateBuffer = null;
|
|
93
|
+
/** Queue for compressed payloads for Zstd Decompress */ this.decompressionPromisesQueue = [];
|
|
39
94
|
this.id = options.id;
|
|
40
95
|
this.connection = options.connection;
|
|
41
96
|
this.events = options.events;
|
|
@@ -46,6 +101,7 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
46
101
|
};
|
|
47
102
|
if (options.requestIdentify) this.requestIdentify = options.requestIdentify;
|
|
48
103
|
if (options.shardIsReady) this.shardIsReady = options.shardIsReady;
|
|
104
|
+
if (options.makePresence) this.makePresence = options.makePresence;
|
|
49
105
|
this.bucket = new _utils.LeakyBucket({
|
|
50
106
|
max: this.calculateSafeRequests(),
|
|
51
107
|
refillAmount: this.calculateSafeRequests(),
|
|
@@ -66,13 +122,12 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
66
122
|
return safeRequests < 0 ? 0 : safeRequests;
|
|
67
123
|
}
|
|
68
124
|
async checkOffline(highPriority) {
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
125
|
+
if (this.isOpen()) return;
|
|
126
|
+
return await new Promise((resolve)=>{
|
|
127
|
+
// Higher priority requests get added at the beginning of the array.
|
|
128
|
+
if (highPriority) this.offlineSendQueue.unshift(resolve);
|
|
129
|
+
else this.offlineSendQueue.push(resolve);
|
|
130
|
+
});
|
|
76
131
|
}
|
|
77
132
|
/** Close the socket connection to discord if present. */ close(code, reason) {
|
|
78
133
|
if (this.socket?.readyState !== _ws.default.OPEN) return;
|
|
@@ -91,20 +146,62 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
91
146
|
const url = new URL(this.connectionUrl);
|
|
92
147
|
url.searchParams.set('v', this.gatewayConfig.version.toString());
|
|
93
148
|
url.searchParams.set('encoding', 'json');
|
|
94
|
-
|
|
95
|
-
|
|
149
|
+
// Set the compress url param and initialize the decompression contexts
|
|
150
|
+
if (this.gatewayConfig.transportCompression) {
|
|
151
|
+
url.searchParams.set('compress', this.gatewayConfig.transportCompression);
|
|
152
|
+
if (this.gatewayConfig.transportCompression === _types1.TransportCompression.zlib) {
|
|
153
|
+
this.inflateBuffer = null;
|
|
154
|
+
this.inflate = (0, _nodezlib.createInflate)({
|
|
155
|
+
finishFlush: _nodezlib.constants.Z_SYNC_FLUSH,
|
|
156
|
+
chunkSize: 64 * 1024
|
|
157
|
+
});
|
|
158
|
+
this.inflate.on('error', (e)=>{
|
|
159
|
+
this.logger.error('The was an error in decompressing a ZLib compressed payload', e);
|
|
160
|
+
});
|
|
161
|
+
this.inflate.on('data', (data)=>{
|
|
162
|
+
if (!(data instanceof Uint8Array)) return;
|
|
163
|
+
if (this.inflateBuffer) {
|
|
164
|
+
const newBuffer = new Uint8Array(this.inflateBuffer.byteLength + data.byteLength);
|
|
165
|
+
newBuffer.set(this.inflateBuffer);
|
|
166
|
+
newBuffer.set(data, this.inflateBuffer.byteLength);
|
|
167
|
+
this.inflateBuffer = newBuffer;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.inflateBuffer = data;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (this.gatewayConfig.transportCompression === _types1.TransportCompression.zstd) {
|
|
174
|
+
const fzstd = await getFZStd().catch(()=>{
|
|
175
|
+
this.logger.warn('[Shard] "fzstd" is not installed. Disabled transport compression.');
|
|
176
|
+
url.searchParams.delete('compress');
|
|
177
|
+
return null;
|
|
178
|
+
});
|
|
179
|
+
if (fzstd) {
|
|
180
|
+
this.zstdDecompress = new fzstd.Decompress((data)=>{
|
|
181
|
+
const decodedData = this.textDecoder.decode(data);
|
|
182
|
+
const parsedData = JSON.parse(decodedData);
|
|
183
|
+
this.decompressionPromisesQueue.shift()?.(parsedData);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (this.gatewayConfig.compress && this.gatewayConfig.transportCompression) {
|
|
189
|
+
this.logger.warn('[Shard] Payload compression has been disabled since transport compression is enabled as well.');
|
|
190
|
+
this.gatewayConfig.compress = false;
|
|
191
|
+
}
|
|
192
|
+
// We check for built-in WebSocket implementations in Bun or Deno, NodeJS v22 has an implementation too but it seems to be less optimized so for now it is better to use the ws npm package
|
|
193
|
+
const shouldUseBuiltin = Reflect.has(globalThis, 'WebSocket') && (Reflect.has(globalThis, 'Bun') || Reflect.has(globalThis, 'Deno'));
|
|
194
|
+
// @ts-expect-error NodeWebSocket doesn't support "dispatchEvent", and while we don't use it, it is required on the "WebSocket" type
|
|
195
|
+
const socket = shouldUseBuiltin ? new WebSocket(url) : new _ws.default(url);
|
|
96
196
|
this.socket = socket;
|
|
97
|
-
//
|
|
98
|
-
socket.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
socket.onclose = async (event)=>await this.handleClose(event);
|
|
103
|
-
socket.onmessage = async (message)=>await this.handleMessage(message);
|
|
197
|
+
// By default WebSocket will give us a Blob, this changes it so that it gives us an ArrayBuffer
|
|
198
|
+
socket.binaryType = 'arraybuffer';
|
|
199
|
+
socket.onerror = (event)=>this.handleError(event);
|
|
200
|
+
socket.onclose = (closeEvent)=>this.handleClose(closeEvent);
|
|
201
|
+
socket.onmessage = (messageEvent)=>this.handleMessage(messageEvent);
|
|
104
202
|
return await new Promise((resolve)=>{
|
|
105
203
|
socket.onopen = ()=>{
|
|
106
|
-
// Only set the shard to `Unidentified` state
|
|
107
|
-
// if the connection request does not come from an identify or resume action.
|
|
204
|
+
// Only set the shard to `Unidentified` state if the connection request does not come from an identify or resume action.
|
|
108
205
|
if (![
|
|
109
206
|
_types1.ShardState.Identifying,
|
|
110
207
|
_types1.ShardState.Resuming
|
|
@@ -120,7 +217,7 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
120
217
|
// A new identify has been requested even though there is already a connection open.
|
|
121
218
|
// Therefore we need to close the old connection and heartbeating before creating a new one.
|
|
122
219
|
if (this.isOpen()) {
|
|
123
|
-
this.logger.debug(`
|
|
220
|
+
this.logger.debug(`[Shard] Identifying open Shard #${this.id}, closing the connection`);
|
|
124
221
|
this.close(_types1.ShardSocketCloseCodes.ReIdentifying, 'Re-identifying closure of old connection.');
|
|
125
222
|
}
|
|
126
223
|
this.state = _types1.ShardState.Identifying;
|
|
@@ -142,7 +239,7 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
142
239
|
this.id,
|
|
143
240
|
this.gatewayConfig.totalShards
|
|
144
241
|
],
|
|
145
|
-
presence: await this.makePresence
|
|
242
|
+
presence: await this.makePresence()
|
|
146
243
|
}
|
|
147
244
|
}, true);
|
|
148
245
|
return await new Promise((resolve)=>{
|
|
@@ -152,8 +249,7 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
152
249
|
this.shardIsReady();
|
|
153
250
|
resolve();
|
|
154
251
|
});
|
|
155
|
-
// When identifying too fast,
|
|
156
|
-
// Discord sends an invalid session payload.
|
|
252
|
+
// When identifying too fast, Discord sends an invalid session payload.
|
|
157
253
|
// This can safely be ignored though and the shard starts a new identify action.
|
|
158
254
|
this.resolves.set('INVALID_SESSION', ()=>{
|
|
159
255
|
this.resolves.delete('READY');
|
|
@@ -165,23 +261,23 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
165
261
|
return this.socket?.readyState === _ws.default.OPEN;
|
|
166
262
|
}
|
|
167
263
|
/** Attempt to resume the previous shards session with the gateway. */ async resume() {
|
|
168
|
-
this.logger.debug(`[
|
|
264
|
+
this.logger.debug(`[Shard] Resuming Shard #${this.id}`);
|
|
169
265
|
// It has been requested to resume the Shards session.
|
|
170
266
|
// It's possible that the shard is still connected with Discord's gateway therefore we need to forcefully close it.
|
|
171
267
|
if (this.isOpen()) {
|
|
172
|
-
this.logger.debug(`[
|
|
268
|
+
this.logger.debug(`[Shard] Resuming open Shard #${this.id}, closing the connection`);
|
|
173
269
|
this.close(_types1.ShardSocketCloseCodes.ResumeClosingOldConnection, 'Reconnecting the shard, closing old connection.');
|
|
174
270
|
}
|
|
175
271
|
// Shard has never identified, so we cannot resume.
|
|
176
272
|
if (!this.sessionId) {
|
|
177
|
-
this.logger.debug(`[Shard] Trying to resume
|
|
178
|
-
|
|
273
|
+
this.logger.debug(`[Shard] Trying to resume Shard #${this.id} without the session id. Identifying the shard instead.`);
|
|
274
|
+
await this.identify();
|
|
275
|
+
return;
|
|
179
276
|
}
|
|
180
277
|
this.state = _types1.ShardState.Resuming;
|
|
181
|
-
this.logger.debug(`[Gateway] Resuming Shard #${this.id}, before connecting`);
|
|
182
278
|
// Before we can resume, we need to create a new connection with Discord's gateway.
|
|
183
279
|
await this.connect();
|
|
184
|
-
this.logger.debug(`[
|
|
280
|
+
this.logger.debug(`[Shard] Resuming Shard #${this.id} connected. Session id: ${this.sessionId} | Sequence: ${this.previousSequenceNumber}`);
|
|
185
281
|
this.send({
|
|
186
282
|
op: _types.GatewayOpcodes.Resume,
|
|
187
283
|
d: {
|
|
@@ -190,11 +286,9 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
190
286
|
seq: this.previousSequenceNumber ?? 0
|
|
191
287
|
}
|
|
192
288
|
}, true);
|
|
193
|
-
this.logger.debug(`[Gateway] Resuming Shard #${this.id} after send resumg`);
|
|
194
289
|
return await new Promise((resolve)=>{
|
|
195
290
|
this.resolves.set('RESUMED', ()=>resolve());
|
|
196
|
-
// If it is attempted to resume with an invalid session id,
|
|
197
|
-
// Discord sends an invalid session payload
|
|
291
|
+
// If it is attempted to resume with an invalid session id, Discord sends an invalid session payload
|
|
198
292
|
// Not erroring here since it is easy that this happens, also it would be not catchable
|
|
199
293
|
this.resolves.set('INVALID_SESSION', ()=>{
|
|
200
294
|
this.resolves.delete('RESUMED');
|
|
@@ -202,8 +296,9 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
202
296
|
});
|
|
203
297
|
});
|
|
204
298
|
}
|
|
205
|
-
/**
|
|
206
|
-
*
|
|
299
|
+
/**
|
|
300
|
+
* Send a message to Discord.
|
|
301
|
+
* @param highPriority - Whether this message should be send asap.
|
|
207
302
|
*/ async send(message, highPriority = false) {
|
|
208
303
|
// Before acquiring a token from the bucket, check whether the shard is currently offline or not.
|
|
209
304
|
// Else bucket and token wait time just get wasted.
|
|
@@ -217,10 +312,18 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
217
312
|
this.close(_types1.ShardSocketCloseCodes.Shutdown, 'Shard shutting down.');
|
|
218
313
|
this.state = _types1.ShardState.Offline;
|
|
219
314
|
}
|
|
315
|
+
/** Handle a gateway connection error */ handleError(error) {
|
|
316
|
+
this.logger.error(`[Shard] There was an error connecting Shard #${this.id}.`, error);
|
|
317
|
+
}
|
|
220
318
|
/** Handle a gateway connection close. */ async handleClose(close) {
|
|
221
|
-
|
|
319
|
+
this.socket = undefined;
|
|
222
320
|
this.stopHeartbeating();
|
|
223
|
-
|
|
321
|
+
// Clear the zlib/zstd data
|
|
322
|
+
this.inflate = undefined;
|
|
323
|
+
this.zstdDecompress = undefined;
|
|
324
|
+
this.inflateBuffer = null;
|
|
325
|
+
this.decompressionPromisesQueue = [];
|
|
326
|
+
this.logger.debug(`[Shard] Shard #${this.id} closed with code ${close.code}${close.reason ? `, and reason: ${close.reason}` : ''}.`);
|
|
224
327
|
switch(close.code){
|
|
225
328
|
case _types1.ShardSocketCloseCodes.TestingFinished:
|
|
226
329
|
{
|
|
@@ -237,21 +340,8 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
237
340
|
{
|
|
238
341
|
this.state = _types1.ShardState.Disconnected;
|
|
239
342
|
this.events.disconnected?.(this);
|
|
240
|
-
// gateway.debug("GW CLOSED_RECONNECT", { shardId, payload: event });
|
|
241
343
|
return;
|
|
242
344
|
}
|
|
243
|
-
// Gateway connection closes which require a new identify.
|
|
244
|
-
case _types.GatewayCloseEventCodes.UnknownOpcode:
|
|
245
|
-
case _types.GatewayCloseEventCodes.NotAuthenticated:
|
|
246
|
-
case _types.GatewayCloseEventCodes.InvalidSeq:
|
|
247
|
-
case _types.GatewayCloseEventCodes.RateLimited:
|
|
248
|
-
case _types.GatewayCloseEventCodes.SessionTimedOut:
|
|
249
|
-
{
|
|
250
|
-
this.logger.debug('[Shard] Gateway connection closing requiring re-identify.');
|
|
251
|
-
this.state = _types1.ShardState.Identifying;
|
|
252
|
-
this.events.disconnected?.(this);
|
|
253
|
-
return await this.identify();
|
|
254
|
-
}
|
|
255
345
|
// When these codes are received something went really wrong.
|
|
256
346
|
// On those we cannot start a reconnect attempt.
|
|
257
347
|
case _types.GatewayCloseEventCodes.AuthenticationFailed:
|
|
@@ -265,19 +355,89 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
265
355
|
this.events.disconnected?.(this);
|
|
266
356
|
throw new Error(close.reason || 'Discord gave no reason! GG! You broke Discord!');
|
|
267
357
|
}
|
|
358
|
+
// Gateway connection closes which require a new identify.
|
|
359
|
+
case _types.GatewayCloseEventCodes.NotAuthenticated:
|
|
360
|
+
case _types.GatewayCloseEventCodes.InvalidSeq:
|
|
361
|
+
case _types.GatewayCloseEventCodes.SessionTimedOut:
|
|
362
|
+
{
|
|
363
|
+
this.logger.debug(`[Shard] Shard #${this.id} closed requiring re-identify.`);
|
|
364
|
+
this.state = _types1.ShardState.Identifying;
|
|
365
|
+
this.events.disconnected?.(this);
|
|
366
|
+
await this.identify();
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
268
369
|
// Gateway connection closes on which a resume is allowed.
|
|
269
370
|
case _types.GatewayCloseEventCodes.UnknownError:
|
|
371
|
+
case _types.GatewayCloseEventCodes.UnknownOpcode:
|
|
270
372
|
case _types.GatewayCloseEventCodes.DecodeError:
|
|
373
|
+
case _types.GatewayCloseEventCodes.RateLimited:
|
|
271
374
|
case _types.GatewayCloseEventCodes.AlreadyAuthenticated:
|
|
272
375
|
default:
|
|
273
376
|
{
|
|
274
|
-
this.logger.info(`[Shard]
|
|
275
|
-
|
|
377
|
+
this.logger.info(`[Shard] Shard #${this.id} closed with code ${close.code}. Attempting to resume...`);
|
|
378
|
+
// We don't want to get into an infinite loop where we resume forever, so if we were already resuming we identify instead
|
|
379
|
+
this.state = this.state === _types1.ShardState.Resuming ? _types1.ShardState.Identifying : _types1.ShardState.Resuming;
|
|
276
380
|
this.events.disconnected?.(this);
|
|
277
|
-
|
|
381
|
+
if (this.state === _types1.ShardState.Resuming) {
|
|
382
|
+
await this.resume();
|
|
383
|
+
} else {
|
|
384
|
+
await this.identify();
|
|
385
|
+
}
|
|
386
|
+
return;
|
|
278
387
|
}
|
|
279
388
|
}
|
|
280
389
|
}
|
|
390
|
+
/** Handle an incoming gateway message. */ async handleMessage(message) {
|
|
391
|
+
// The ws npm package will use a Buffer, while the global built-in will use ArrayBuffer
|
|
392
|
+
const isCompressed = message.data instanceof ArrayBuffer || message.data instanceof _nodebuffer.Buffer;
|
|
393
|
+
const data = isCompressed ? await this.decompressPacket(message.data) : JSON.parse(message.data);
|
|
394
|
+
// Check if the decompression was not successful
|
|
395
|
+
if (!data) return;
|
|
396
|
+
await this.handleDiscordPacket(data);
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Decompress a zlib/zstd compressed packet
|
|
400
|
+
*
|
|
401
|
+
* @private
|
|
402
|
+
*/ async decompressPacket(data) {
|
|
403
|
+
// A buffer is a Uint8Array under the hood. An ArrayBuffer is generic, so we need to create the Uint8Array that uses the whole ArrayBuffer
|
|
404
|
+
const compressedData = data instanceof _nodebuffer.Buffer ? data : new Uint8Array(data);
|
|
405
|
+
if (this.gatewayConfig.transportCompression === _types1.TransportCompression.zlib) {
|
|
406
|
+
if (!this.inflate) {
|
|
407
|
+
this.logger.fatal('[Shard] zlib-stream transport compression was enabled but no instance of Inflate was found.');
|
|
408
|
+
return null;
|
|
409
|
+
}
|
|
410
|
+
// Alias, used to avoid some null checks in the Promise constructor
|
|
411
|
+
const inflate = this.inflate;
|
|
412
|
+
const writePromise = new Promise((resolve, reject)=>{
|
|
413
|
+
inflate.write(compressedData, 'binary', (error)=>error ? reject(error) : resolve());
|
|
414
|
+
});
|
|
415
|
+
if (!endsWithMarker(compressedData, ZLIB_SYNC_FLUSH)) return null;
|
|
416
|
+
await writePromise;
|
|
417
|
+
if (!this.inflateBuffer) {
|
|
418
|
+
this.logger.warn('[Shard] The ZLib inflate buffer was cleared at an unexpected moment.');
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
const decodedData = this.textDecoder.decode(this.inflateBuffer);
|
|
422
|
+
this.inflateBuffer = null;
|
|
423
|
+
return JSON.parse(decodedData);
|
|
424
|
+
}
|
|
425
|
+
if (this.gatewayConfig.transportCompression === _types1.TransportCompression.zstd) {
|
|
426
|
+
if (!this.zstdDecompress) {
|
|
427
|
+
this.logger.fatal('[Shard] zstd-stream transport compression was enabled but no instance of Decompress was found.');
|
|
428
|
+
return null;
|
|
429
|
+
}
|
|
430
|
+
this.zstdDecompress.push(compressedData);
|
|
431
|
+
const decompressionPromise = new Promise((r)=>this.decompressionPromisesQueue.push(r));
|
|
432
|
+
return await decompressionPromise;
|
|
433
|
+
}
|
|
434
|
+
if (this.gatewayConfig.compress) {
|
|
435
|
+
const decompressed = (0, _nodezlib.inflateSync)(compressedData);
|
|
436
|
+
const decodedData = this.textDecoder.decode(decompressed);
|
|
437
|
+
return JSON.parse(decodedData);
|
|
438
|
+
}
|
|
439
|
+
return null;
|
|
440
|
+
}
|
|
281
441
|
/** Handles a incoming gateway packet. */ async handleDiscordPacket(packet) {
|
|
282
442
|
// Edge case start: https://github.com/discordeno/discordeno/issues/2311
|
|
283
443
|
this.heart.lastAck = Date.now();
|
|
@@ -286,7 +446,6 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
286
446
|
switch(packet.op){
|
|
287
447
|
case _types.GatewayOpcodes.Heartbeat:
|
|
288
448
|
{
|
|
289
|
-
// TODO: can this actually happen
|
|
290
449
|
if (!this.isOpen()) return;
|
|
291
450
|
this.heart.lastBeat = Date.now();
|
|
292
451
|
// Discord randomly sends this requiring an immediate heartbeat back.
|
|
@@ -301,7 +460,7 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
301
460
|
case _types.GatewayOpcodes.Hello:
|
|
302
461
|
{
|
|
303
462
|
const interval = packet.d.heartbeat_interval;
|
|
304
|
-
this.logger.debug(`[
|
|
463
|
+
this.logger.debug(`[Shard] Shard #${this.id} received Hello`);
|
|
305
464
|
this.startHeartbeating(interval);
|
|
306
465
|
if (this.state !== _types1.ShardState.Resuming) {
|
|
307
466
|
const currentQueue = [
|
|
@@ -313,7 +472,8 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
313
472
|
this.bucket = new _utils.LeakyBucket({
|
|
314
473
|
max: this.calculateSafeRequests(),
|
|
315
474
|
refillInterval: 60000,
|
|
316
|
-
refillAmount: this.calculateSafeRequests()
|
|
475
|
+
refillAmount: this.calculateSafeRequests(),
|
|
476
|
+
logger: this.logger
|
|
317
477
|
});
|
|
318
478
|
// Queue should not be lost on a re-identify.
|
|
319
479
|
this.bucket.queue.unshift(...currentQueue);
|
|
@@ -332,7 +492,6 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
332
492
|
}
|
|
333
493
|
case _types.GatewayOpcodes.Reconnect:
|
|
334
494
|
{
|
|
335
|
-
// gateway.debug("GW RECONNECT", { shardId });
|
|
336
495
|
this.events.requestedReconnect?.(this);
|
|
337
496
|
await this.resume();
|
|
338
497
|
break;
|
|
@@ -340,7 +499,7 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
340
499
|
case _types.GatewayOpcodes.InvalidSession:
|
|
341
500
|
{
|
|
342
501
|
const resumable = packet.d;
|
|
343
|
-
this.logger.debug(`[Shard] Received Invalid Session for Shard #${this.id} with
|
|
502
|
+
this.logger.debug(`[Shard] Received Invalid Session for Shard #${this.id} with resumable as ${resumable}`);
|
|
344
503
|
this.events.invalidSession?.(this, resumable);
|
|
345
504
|
// We need to wait for a random amount of time between 1 and 5
|
|
346
505
|
// Reference: https://discord.com/developers/docs/topics/gateway#resuming
|
|
@@ -361,21 +520,27 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
361
520
|
case 'RESUMED':
|
|
362
521
|
this.state = _types1.ShardState.Connected;
|
|
363
522
|
this.events.resumed?.(this);
|
|
523
|
+
this.logger.debug(`[Shard] Shard #${this.id} received RESUMED`);
|
|
364
524
|
// Continue the requests which have been queued since the shard went offline.
|
|
365
|
-
this.offlineSendQueue.
|
|
525
|
+
this.offlineSendQueue.forEach((resolve)=>resolve());
|
|
526
|
+
// Setting the length to 0 will delete the elements in it
|
|
527
|
+
this.offlineSendQueue.length = 0;
|
|
366
528
|
this.resolves.get('RESUMED')?.(packet);
|
|
367
529
|
this.resolves.delete('RESUMED');
|
|
368
530
|
break;
|
|
369
531
|
case 'READY':
|
|
370
532
|
{
|
|
371
|
-
// Important for future resumes.
|
|
372
533
|
const payload = packet.d;
|
|
534
|
+
// Important for future resumes.
|
|
373
535
|
this.resumeGatewayUrl = payload.resume_gateway_url;
|
|
374
536
|
this.sessionId = payload.session_id;
|
|
375
537
|
this.state = _types1.ShardState.Connected;
|
|
538
|
+
this.logger.debug(`[Shard] Shard #${this.id} received READY`);
|
|
376
539
|
// Continue the requests which have been queued since the shard went offline.
|
|
377
540
|
// Important when this is a re-identify
|
|
378
|
-
this.offlineSendQueue.
|
|
541
|
+
this.offlineSendQueue.forEach((resolve)=>resolve());
|
|
542
|
+
// Setting the length to 0 will delete the elements in it
|
|
543
|
+
this.offlineSendQueue.length = 0;
|
|
379
544
|
this.resolves.get('READY')?.(packet);
|
|
380
545
|
this.resolves.delete('READY');
|
|
381
546
|
break;
|
|
@@ -394,17 +559,6 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
394
559
|
// Now the event can be safely forwarded.
|
|
395
560
|
this.events.message?.(this, (0, _utils.camelize)(packet));
|
|
396
561
|
}
|
|
397
|
-
/** Handle an incoming gateway message. */ async handleMessage(message) {
|
|
398
|
-
let preProcessMessage = message.data;
|
|
399
|
-
// If message compression is enabled,
|
|
400
|
-
// Discord might send zlib compressed payloads.
|
|
401
|
-
if (this.gatewayConfig.compress && preProcessMessage instanceof Blob) {
|
|
402
|
-
preProcessMessage = (0, _nodezlib.inflateSync)(await preProcessMessage.arrayBuffer()).toString();
|
|
403
|
-
}
|
|
404
|
-
// Safeguard incase decompression failed to make a string.
|
|
405
|
-
if (typeof preProcessMessage !== 'string') return;
|
|
406
|
-
return await this.handleDiscordPacket(JSON.parse(preProcessMessage));
|
|
407
|
-
}
|
|
408
562
|
/**
|
|
409
563
|
* Override in order to make the shards presence.
|
|
410
564
|
* async in case devs create the presence based on eg. database values.
|
|
@@ -412,13 +566,15 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
412
566
|
*/ async makePresence() {
|
|
413
567
|
return;
|
|
414
568
|
}
|
|
415
|
-
/**
|
|
569
|
+
/**
|
|
570
|
+
* This function communicates with the management process, in order to know whether its free to identify.
|
|
571
|
+
* When this function resolves, this means that the shard is allowed to send an identify payload to discord.
|
|
572
|
+
*/ async requestIdentify() {}
|
|
416
573
|
/** This function communicates with the management process, in order to tell it can identify the next shard. */ async shardIsReady() {}
|
|
417
574
|
/** Start sending heartbeat payloads to Discord in the provided interval. */ startHeartbeating(interval) {
|
|
418
|
-
this.logger.debug(`[
|
|
575
|
+
this.logger.debug(`[Shard] Start heartbeating on Shard #${this.id}`);
|
|
419
576
|
// If old heartbeast exist like after resume, clear the old ones.
|
|
420
|
-
|
|
421
|
-
if (this.heart.timeoutId) clearTimeout(this.heart.timeoutId);
|
|
577
|
+
this.stopHeartbeating();
|
|
422
578
|
this.heart.interval = interval;
|
|
423
579
|
// Only set the shard's state to `Unidentified`
|
|
424
580
|
// if heartbeating has not been started due to an identify or resume action.
|
|
@@ -426,7 +582,7 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
426
582
|
_types1.ShardState.Disconnected,
|
|
427
583
|
_types1.ShardState.Offline
|
|
428
584
|
].includes(this.state)) {
|
|
429
|
-
this.logger.debug(`[
|
|
585
|
+
this.logger.debug(`[Shard] Shard is disconnected or offline but the heartbeat was started #${this.id}`);
|
|
430
586
|
this.state = _types1.ShardState.Unidentified;
|
|
431
587
|
}
|
|
432
588
|
// The first heartbeat needs to be send with a random delay between `0` and `interval`
|
|
@@ -435,42 +591,40 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
435
591
|
// Reference: https://discord.com/developers/docs/topics/gateway#heartbeating
|
|
436
592
|
const jitter = Math.ceil(this.heart.interval * (Math.random() || 0.5));
|
|
437
593
|
this.heart.timeoutId = setTimeout(()=>{
|
|
438
|
-
this.logger.debug(`[
|
|
594
|
+
this.logger.debug(`[Shard] Beginning heartbeating process for Shard #${this.id}`);
|
|
439
595
|
if (!this.isOpen()) return;
|
|
440
|
-
this.logger.debug(`[
|
|
596
|
+
this.logger.debug(`[Shard] Heartbeating on Shard #${this.id}. Previous sequence number: ${this.previousSequenceNumber}`);
|
|
441
597
|
// Using a direct socket.send call here because heartbeat requests are reserved by us.
|
|
442
598
|
this.socket?.send(JSON.stringify({
|
|
443
599
|
op: _types.GatewayOpcodes.Heartbeat,
|
|
444
600
|
d: this.previousSequenceNumber
|
|
445
601
|
}));
|
|
446
|
-
this.logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} d`);
|
|
447
602
|
this.heart.lastBeat = Date.now();
|
|
448
603
|
this.heart.acknowledged = false;
|
|
449
604
|
// After the random heartbeat jitter we can start a normal interval.
|
|
450
605
|
this.heart.intervalId = setInterval(async ()=>{
|
|
451
|
-
this.
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
// gateway.debug("GW HEARTBEATING", { shardId, shard: currentShard });
|
|
606
|
+
if (!this.isOpen()) {
|
|
607
|
+
this.logger.debug(`[Shard] Shard #${this.id} is not open, but attempted heartbeat, ignoring.`);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
456
610
|
// The Shard did not receive a heartbeat ACK from Discord in time,
|
|
457
611
|
// therefore we have to assume that the connection has failed or got "zombied".
|
|
458
612
|
// The Shard needs to start a re-identify action accordingly.
|
|
459
613
|
// Reference: https://discord.com/developers/docs/topics/gateway#heartbeating-example-gateway-heartbeat-ack
|
|
460
614
|
if (!this.heart.acknowledged) {
|
|
461
|
-
this.logger.debug(`[Shard] Heartbeat not acknowledged for
|
|
615
|
+
this.logger.debug(`[Shard] Heartbeat not acknowledged for Shard #${this.id}. Assuming zombied connection.`);
|
|
462
616
|
this.close(_types1.ShardSocketCloseCodes.ZombiedConnection, 'Zombied connection, did not receive an heartbeat ACK in time.');
|
|
463
|
-
|
|
617
|
+
await this.resume();
|
|
618
|
+
return;
|
|
464
619
|
}
|
|
465
|
-
this.
|
|
466
|
-
this.logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} g`);
|
|
620
|
+
this.logger.debug(`[Shard] Heartbeating on Shard #${this.id}. Previous sequence number: ${this.previousSequenceNumber}`);
|
|
467
621
|
// Using a direct socket.send call here because heartbeat requests are reserved by us.
|
|
468
622
|
this.socket?.send(JSON.stringify({
|
|
469
623
|
op: _types.GatewayOpcodes.Heartbeat,
|
|
470
624
|
d: this.previousSequenceNumber
|
|
471
625
|
}));
|
|
472
|
-
this.logger.debug(`[Gateway] Start Heartbeating Shard #${this.id} h`);
|
|
473
626
|
this.heart.lastBeat = Date.now();
|
|
627
|
+
this.heart.acknowledged = false;
|
|
474
628
|
this.events.heartbeat?.(this);
|
|
475
629
|
}, this.heart.interval);
|
|
476
630
|
}, jitter);
|
|
@@ -483,6 +637,13 @@ let DiscordenoShard = class DiscordenoShard {
|
|
|
483
637
|
clearTimeout(this.heart.timeoutId);
|
|
484
638
|
}
|
|
485
639
|
};
|
|
640
|
+
/** Check if the buffer ends with the marker */ function endsWithMarker(buffer, marker) {
|
|
641
|
+
if (buffer.length < marker.length) return false;
|
|
642
|
+
for(let i = 0; i < marker.length; i++){
|
|
643
|
+
if (buffer[buffer.length - marker.length + i] !== marker[i]) return false;
|
|
644
|
+
}
|
|
645
|
+
return true;
|
|
646
|
+
}
|
|
486
647
|
const _default = DiscordenoShard;
|
|
487
648
|
|
|
488
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TaGFyZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmZsYXRlU3luYyB9IGZyb20gJ25vZGU6emxpYidcbmltcG9ydCB0eXBlIHsgRGlzY29yZEdhdGV3YXlQYXlsb2FkLCBEaXNjb3JkSGVsbG8sIERpc2NvcmRSZWFkeSB9IGZyb20gJ0BkaXNjb3JkZW5vL3R5cGVzJ1xuaW1wb3J0IHsgR2F0ZXdheUNsb3NlRXZlbnRDb2RlcywgR2F0ZXdheU9wY29kZXMgfSBmcm9tICdAZGlzY29yZGVuby90eXBlcydcbmltcG9ydCB7IExlYWt5QnVja2V0LCBjYW1lbGl6ZSwgZGVsYXksIGxvZ2dlciB9IGZyb20gJ0BkaXNjb3JkZW5vL3V0aWxzJ1xuaW1wb3J0IE5vZGVXZWJTb2NrZXQgZnJvbSAnd3MnXG5pbXBvcnQgdHlwZSB7IEJvdFN0YXR1c1VwZGF0ZSwgU2hhcmRFdmVudHMsIFNoYXJkR2F0ZXdheUNvbmZpZywgU2hhcmRIZWFydCwgU2hhcmRTb2NrZXRSZXF1ZXN0IH0gZnJvbSAnLi90eXBlcy5qcydcbmltcG9ydCB7IFNoYXJkU29ja2V0Q2xvc2VDb2RlcywgU2hhcmRTdGF0ZSB9IGZyb20gJy4vdHlwZXMuanMnXG5cbmRlY2xhcmUgbGV0IFdlYlNvY2tldDogYW55XG5cbmV4cG9ydCBjbGFzcyBEaXNjb3JkZW5vU2hhcmQge1xuICAvKiogVGhlIGlkIG9mIHRoZSBzaGFyZCAqL1xuICBpZDogbnVtYmVyXG4gIC8qKiBUaGUgY29ubmVjdGlvbiBjb25maWcgZGV0YWlscyB0aGF0IHRoaXMgc2hhcmQgd2lsbCB1c2VkIHRvIGNvbm5lY3QgdG8gZGlzY29yZC4gKi9cbiAgY29ubmVjdGlvbjogU2hhcmRHYXRld2F5Q29uZmlnXG4gIC8qKiBUaGlzIGNvbnRhaW5zIGFsbCB0aGUgaGVhcnRiZWF0IGluZm9ybWF0aW9uICovXG4gIGhlYXJ0OiBTaGFyZEhlYXJ0XG4gIC8qKiBUaGUgbWF4aW11bSBvZiByZXF1ZXN0cyB3aGljaCBjYW4gYmUgc2VuZCB0byBkaXNjb3JkIHBlciByYXRlIGxpbWl0IHRpY2suIFR5cGljYWxseSB0aGlzIHZhbHVlIHNob3VsZCBub3QgYmUgY2hhbmdlZC4gKi9cbiAgbWF4UmVxdWVzdHNQZXJSYXRlTGltaXRUaWNrOiBudW1iZXIgPSAxMjBcbiAgLyoqIFRoZSBwcmV2aW91cyBwYXlsb2FkIHNlcXVlbmNlIG51bWJlci4gKi9cbiAgcHJldmlvdXNTZXF1ZW5jZU51bWJlcjogbnVtYmVyIHwgbnVsbCA9IG51bGxcbiAgLyoqIEluIHdoaWNoIGludGVydmFsIChpbiBtaWxsaXNlY29uZHMpIHRoZSBnYXRld2F5IHJlc2V0cyBpdCdzIHJhdGUgbGltaXQuICovXG4gIHJhdGVMaW1pdFJlc2V0SW50ZXJ2YWw6IG51bWJlciA9IDYwMDAwXG4gIC8qKiBDdXJyZW50IHNlc3Npb24gaWQgb2YgdGhlIHNoYXJkIGlmIHByZXNlbnQuICovXG4gIHNlc3Npb25JZD86IHN0cmluZ1xuICAvKiogVGhpcyBjb250YWlucyB0aGUgV2ViU29ja2V0IGNvbm5lY3Rpb24gdG8gRGlzY29yZCwgaWYgY3VycmVudGx5IGNvbm5lY3RlZC4gKi9cbiAgc29ja2V0PzogTm9kZVdlYlNvY2tldFxuICAvKiogQ3VycmVudCBpbnRlcm5hbCBzdGF0ZSBvZiB0aGUgdGhpcy4gKi9cbiAgc3RhdGUgPSBTaGFyZFN0YXRlLk9mZmxpbmVcbiAgLyoqIFRoZSB1cmwgcHJvdmlkZWQgYnkgZGlzY29yZCB0byB1c2Ugd2hlbiByZXN1bWluZyBhIGNvbm5lY3Rpb24gZm9yIHRoaXMgdGhpcy4gKi9cbiAgcmVzdW1lR2F0ZXdheVVybDogc3RyaW5nID0gJydcbiAgLyoqIFRoZSBzaGFyZCByZWxhdGVkIGV2ZW50IGhhbmRsZXJzLiAqL1xuICBldmVudHM6IFNoYXJkRXZlbnRzID0ge31cbiAgLyoqIENhY2hlIGZvciBwZW5kaW5nIGdhdGV3YXkgcmVxdWVzdHMgd2hpY2ggc2hvdWxkIGhhdmUgYmVlbiBzZW5kIHdoaWxlIHRoZSBnYXRld2F5IHdlbnQgb2ZmbGluZS4gKi9cbiAgb2ZmbGluZVNlbmRRdWV1ZTogQXJyYXk8KF8/OiB1bmtub3duKSA9PiB2b2lkPiA9IFtdXG4gIC8qKiBSZXNvbHZlIGludGVybmFsIHdhaXRpbmcgc3RhdGVzLiBNYXBwZWQgYnkgU2VsZWN0ZWRFdmVudHMgPT4gUmVzb2x2ZUZ1bmN0aW9uICovXG4gIHJlc29sdmVzID0gbmV3IE1hcDwnUkVBRFknIHwgJ1JFU1VNRUQnIHwgJ0lOVkFMSURfU0VTU0lPTicsIChwYXlsb2FkOiBEaXNjb3JkR2F0ZXdheVBheWxvYWQpID0+IHZvaWQ+KClcbiAgLyoqIFNoYXJkIGJ1Y2tldC4gT25seSBhY2Nlc3MgdGhpcyBpZiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuIEJ1Y2tldCBmb3IgaGFuZGxpbmcgc2hhcmQgcmVxdWVzdCByYXRlIGxpbWl0cy4gKi9cbiAgYnVja2V0OiBMZWFreUJ1Y2tldFxuICAvKiogTG9nZ2VyIGZvciB0aGUgYnVja2V0ICovXG4gIGxvZ2dlcjogUGljazx0eXBlb2YgbG9nZ2VyLCAnZGVidWcnIHwgJ2luZm8nIHwgJ3dhcm4nIHwgJ2Vycm9yJyB8ICdmYXRhbCc+XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogU2hhcmRDcmVhdGVPcHRpb25zKSB7XG4gICAgdGhpcy5pZCA9IG9wdGlvbnMuaWRcbiAgICB0aGlzLmNvbm5lY3Rpb24gPSBvcHRpb25zLmNvbm5lY3Rpb25cbiAgICB0aGlzLmV2ZW50cyA9IG9wdGlvbnMuZXZlbnRzXG4gICAgdGhpcy5sb2dnZXIgPSBvcHRpb25zLmxvZ2dlciA/PyBsb2dnZXJcblxuICAgIHRoaXMuaGVhcnQgPSB7XG4gICAgICBhY2tub3dsZWRnZWQ6IGZhbHNlLFxuICAgICAgaW50ZXJ2YWw6IDQ1MDAwLFxuICAgIH1cblxuICAgIGlmIChvcHRpb25zLnJlcXVlc3RJZGVudGlmeSkgdGhpcy5yZXF1ZXN0SWRlbnRpZnkgPSBvcHRpb25zLnJlcXVlc3RJZGVudGlmeVxuICAgIGlmIChvcHRpb25zLnNoYXJkSXNSZWFkeSkgdGhpcy5zaGFyZElzUmVhZHkgPSBvcHRpb25zLnNoYXJkSXNSZWFkeVxuXG4gICAgdGhpcy5idWNrZXQgPSBuZXcgTGVha3lCdWNrZXQoe1xuICAgICAgbWF4OiB0aGlzLmNhbGN1bGF0ZVNhZmVSZXF1ZXN0cygpLFxuICAgICAgcmVmaWxsQW1vdW50OiB0aGlzLmNhbGN1bGF0ZVNhZmVSZXF1ZXN0cygpLFxuICAgICAgcmVmaWxsSW50ZXJ2YWw6IDYwMDAwLFxuICAgICAgbG9nZ2VyOiB0aGlzLmxvZ2dlcixcbiAgICB9KVxuICB9XG5cbiAgLyoqIFRoZSBnYXRld2F5IGNvbmZpZ3VyYXRpb24gd2hpY2ggaXMgdXNlZCB0byBjb25uZWN0IHRvIERpc2NvcmQuICovXG4gIGdldCBnYXRld2F5Q29uZmlnKCk6IFNoYXJkR2F0ZXdheUNvbmZpZyB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvblxuICB9XG5cbiAgLyoqIFRoZSB1cmwgdG8gY29ubmVjdCB0by4gSW5pdGlhbGx5IHRoaXMgaXMgdGhlIGRpc2NvcmQgZ2F0ZXdheSB1cmwsIGFuZCB0aGVuIGlzIHN3aXRjaGVkIHRvIHJlc3VtZSBnYXRld2F5IHVybCBvbmNlIGEgUkVBRFkgaXMgcmVjZWl2ZWQuICovXG4gIGdldCBjb25uZWN0aW9uVXJsKCk6IHN0cmluZyB7XG4gICAgLy8gVXNlIHx8IGFuZCBub3QgPz8gaGVyZS4gPz8gd2lsbCBjYXVzZSBhIGJ1Zy5cbiAgICByZXR1cm4gdGhpcy5yZXN1bWVHYXRld2F5VXJsIHx8IHRoaXMuZ2F0ZXdheUNvbmZpZy51cmxcbiAgfVxuXG4gIC8qKiBDYWxjdWxhdGUgdGhlIGFtb3VudCBvZiByZXF1ZXN0cyB3aGljaCBjYW4gc2FmZWx5IGJlIG1hZGUgcGVyIHJhdGUgbGltaXQgaW50ZXJ2YWwsIGJlZm9yZSB0aGUgZ2F0ZXdheSBnZXRzIGRpc2Nvbm5lY3RlZCBkdWUgdG8gYW4gZXhjZWVkZWQgcmF0ZSBsaW1pdC4gKi9cbiAgY2FsY3VsYXRlU2FmZVJlcXVlc3RzKCk6IG51bWJlciB7XG4gICAgLy8gKiAyIGFkZHMgZXh0cmEgc2FmZXR5IGxheWVyIGZvciBkaXNjb3JkcyBPUCAxIHJlcXVlc3RzIHRoYXQgd2UgbmVlZCB0byByZXNwb25kIHRvXG4gICAgY29uc3Qgc2FmZVJlcXVlc3RzID0gdGhpcy5tYXhSZXF1ZXN0c1BlclJhdGVMaW1pdFRpY2sgLSBNYXRoLmNlaWwodGhpcy5yYXRlTGltaXRSZXNldEludGVydmFsIC8gdGhpcy5oZWFydC5pbnRlcnZhbCkgKiAyXG5cbiAgICByZXR1cm4gc2FmZVJlcXVlc3RzIDwgMCA/IDAgOiBzYWZlUmVxdWVzdHNcbiAgfVxuXG4gIGFzeW5jIGNoZWNrT2ZmbGluZShoaWdoUHJpb3JpdHk6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIC8vIEhpZ2hlciBwcmlvcml0eSByZXF1ZXN0cyBnZXQgYWRkZWQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgYXJyYXkuXG4gICAgICAgIGlmIChoaWdoUHJpb3JpdHkpIHRoaXMub2ZmbGluZVNlbmRRdWV1ZS51bnNoaWZ0KHJlc29sdmUpXG4gICAgICAgIGVsc2UgdGhpcy5vZmZsaW5lU2VuZFF1ZXVlLnB1c2gocmVzb2x2ZSlcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqIENsb3NlIHRoZSBzb2NrZXQgY29ubmVjdGlvbiB0byBkaXNjb3JkIGlmIHByZXNlbnQuICovXG4gIGNsb3NlKGNvZGU6IG51bWJlciwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zb2NrZXQ/LnJlYWR5U3RhdGUgIT09IE5vZGVXZWJTb2NrZXQuT1BFTikgcmV0dXJuXG5cbiAgICB0aGlzLnNvY2tldD8uY2xvc2UoY29kZSwgcmVhc29uKVxuICB9XG5cbiAgLyoqIENvbm5lY3QgdGhlIHNoYXJkIHdpdGggdGhlIGdhdGV3YXkgYW5kIHN0YXJ0IGhlYXJ0YmVhdGluZy4gVGhpcyB3aWxsIG5vdCBpZGVudGlmeSB0aGUgc2hhcmQgdG8gdGhlIGdhdGV3YXkuICovXG4gIGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTxEaXNjb3JkZW5vU2hhcmQ+IHtcbiAgICAvLyBPbmx5IHNldCB0aGUgc2hhcmQgdG8gYENvbm5lY3RpbmdgIHN0YXRlLFxuICAgIC8vIGlmIHRoZSBjb25uZWN0aW9uIHJlcXVlc3QgZG9lcyBub3QgY29tZSBmcm9tIGFuIGlkZW50aWZ5IG9yIHJlc3VtZSBhY3Rpb24uXG4gICAgaWYgKCFbU2hhcmRTdGF0ZS5JZGVudGlmeWluZywgU2hhcmRTdGF0ZS5SZXN1bWluZ10uaW5jbHVkZXModGhpcy5zdGF0ZSkpIHtcbiAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLkNvbm5lY3RpbmdcbiAgICB9XG4gICAgdGhpcy5ldmVudHMuY29ubmVjdGluZz8uKHRoaXMpXG5cbiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHRoaXMuY29ubmVjdGlvblVybClcbiAgICB1cmwuc2VhcmNoUGFyYW1zLnNldCgndicsIHRoaXMuZ2F0ZXdheUNvbmZpZy52ZXJzaW9uLnRvU3RyaW5nKCkpXG4gICAgdXJsLnNlYXJjaFBhcmFtcy5zZXQoJ2VuY29kaW5nJywgJ2pzb24nKVxuXG4gICAgY29uc3Qgc29ja2V0OiBOb2RlV2ViU29ja2V0ID1cbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgRGVub1xuICAgICAgZ2xvYmFsVGhpcy5EZW5vICE9PSB1bmRlZmluZWQgJiYgUmVmbGVjdC5oYXMoZ2xvYmFsVGhpcywgJ0Rlbm8nKSA/IG5ldyBXZWJTb2NrZXQodXJsLnRvU3RyaW5nKCkpIDogbmV3IE5vZGVXZWJTb2NrZXQodXJsLnRvU3RyaW5nKCkpXG4gICAgdGhpcy5zb2NrZXQgPSBzb2NrZXRcblxuICAgIC8vIFRPRE86IHByb3BlciBldmVudCBoYW5kbGluZ1xuICAgIHNvY2tldC5vbmVycm9yID0gKGV2ZW50OiBOb2RlV2ViU29ja2V0LkVycm9yRXZlbnQpID0+IGNvbnNvbGUubG9nKHsgZXJyb3I6IGV2ZW50LCBzaGFyZElkOiB0aGlzLmlkIH0pXG4gICAgc29ja2V0Lm9uY2xvc2UgPSBhc3luYyAoZXZlbnQ6IE5vZGVXZWJTb2NrZXQuQ2xvc2VFdmVudCkgPT4gYXdhaXQgdGhpcy5oYW5kbGVDbG9zZShldmVudClcbiAgICBzb2NrZXQub25tZXNzYWdlID0gYXN5bmMgKG1lc3NhZ2U6IE5vZGVXZWJTb2NrZXQuTWVzc2FnZUV2ZW50KSA9PiBhd2FpdCB0aGlzLmhhbmRsZU1lc3NhZ2UobWVzc2FnZSlcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgc29ja2V0Lm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgLy8gT25seSBzZXQgdGhlIHNoYXJkIHRvIGBVbmlkZW50aWZpZWRgIHN0YXRlLFxuICAgICAgICAvLyBpZiB0aGUgY29ubmVjdGlvbiByZXF1ZXN0IGRvZXMgbm90IGNvbWUgZnJvbSBhbiBpZGVudGlmeSBvciByZXN1bWUgYWN0aW9uLlxuICAgICAgICBpZiAoIVtTaGFyZFN0YXRlLklkZW50aWZ5aW5nLCBTaGFyZFN0YXRlLlJlc3VtaW5nXS5pbmNsdWRlcyh0aGlzLnN0YXRlKSkge1xuICAgICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLlVuaWRlbnRpZmllZFxuICAgICAgICB9XG4gICAgICAgIHRoaXMuZXZlbnRzLmNvbm5lY3RlZD8uKHRoaXMpXG5cbiAgICAgICAgcmVzb2x2ZSh0aGlzKVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICAvKiogSWRlbnRpZnkgdGhlIHNoYXJkIHRvIHRoZSBnYXRld2F5LiBJZiBub3QgY29ubmVjdGVkLCB0aGlzIHdpbGwgYWxzbyBjb25uZWN0IHRoZSBzaGFyZCB0byB0aGUgZ2F0ZXdheS4gKi9cbiAgYXN5bmMgaWRlbnRpZnkoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQSBuZXcgaWRlbnRpZnkgaGFzIGJlZW4gcmVxdWVzdGVkIGV2ZW4gdGhvdWdoIHRoZXJlIGlzIGFscmVhZHkgYSBjb25uZWN0aW9uIG9wZW4uXG4gICAgLy8gVGhlcmVmb3JlIHdlIG5lZWQgdG8gY2xvc2UgdGhlIG9sZCBjb25uZWN0aW9uIGFuZCBoZWFydGJlYXRpbmcgYmVmb3JlIGNyZWF0aW5nIGEgbmV3IG9uZS5cbiAgICBpZiAodGhpcy5pc09wZW4oKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYENMT1NJTkcgRVhJU1RJTkcgU0hBUkQ6ICMke3RoaXMuaWR9YClcbiAgICAgIHRoaXMuY2xvc2UoU2hhcmRTb2NrZXRDbG9zZUNvZGVzLlJlSWRlbnRpZnlpbmcsICdSZS1pZGVudGlmeWluZyBjbG9zdXJlIG9mIG9sZCBjb25uZWN0aW9uLicpXG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZSA9IFNoYXJkU3RhdGUuSWRlbnRpZnlpbmdcbiAgICB0aGlzLmV2ZW50cy5pZGVudGlmeWluZz8uKHRoaXMpXG5cbiAgICAvLyBJdCBpcyBwb3NzaWJsZSB0aGF0IHRoZSBzaGFyZCBpcyBpbiBIZWFydGJlYXRpbmcgc3RhdGUgYnV0IG5vdCBpZGVudGlmaWVkLFxuICAgIC8vIHNvIGNoZWNrIHdoZXRoZXIgdGhlcmUgaXMgYWxyZWFkeSBhIGdhdGV3YXkgY29ubmVjdGlvbiBleGlzdGluZy5cbiAgICAvLyBJZiBub3Qgd2UgbmVlZCB0byBjcmVhdGUgb25lIGJlZm9yZSB3ZSBpZGVudGlmeS5cbiAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIGF3YWl0IHRoaXMuY29ubmVjdCgpXG4gICAgfVxuXG4gICAgdGhpcy5zZW5kKFxuICAgICAge1xuICAgICAgICBvcDogR2F0ZXdheU9wY29kZXMuSWRlbnRpZnksXG4gICAgICAgIGQ6IHtcbiAgICAgICAgICB0b2tlbjogYEJvdCAke3RoaXMuZ2F0ZXdheUNvbmZpZy50b2tlbn1gLFxuICAgICAgICAgIGNvbXByZXNzOiB0aGlzLmdhdGV3YXlDb25maWcuY29tcHJlc3MsXG4gICAgICAgICAgcHJvcGVydGllczogdGhpcy5nYXRld2F5Q29uZmlnLnByb3BlcnRpZXMsXG4gICAgICAgICAgaW50ZW50czogdGhpcy5nYXRld2F5Q29uZmlnLmludGVudHMsXG4gICAgICAgICAgc2hhcmQ6IFt0aGlzLmlkLCB0aGlzLmdhdGV3YXlDb25maWcudG90YWxTaGFyZHNdLFxuICAgICAgICAgIHByZXNlbmNlOiBhd2FpdCB0aGlzLm1ha2VQcmVzZW5jZT8uKCksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdHJ1ZSxcbiAgICApXG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHRoaXMucmVzb2x2ZXMuc2V0KCdSRUFEWScsICgpID0+IHtcbiAgICAgICAgdGhpcy5ldmVudHMuaWRlbnRpZmllZD8uKHRoaXMpXG4gICAgICAgIC8vIFRlbGxzIHRoZSBtYW5hZ2VyIHRoYXQgdGhpcyBzaGFyZCBpcyByZWFkeVxuICAgICAgICB0aGlzLnNoYXJkSXNSZWFkeSgpXG4gICAgICAgIHJlc29sdmUoKVxuICAgICAgfSlcbiAgICAgIC8vIFdoZW4gaWRlbnRpZnlpbmcgdG9vIGZhc3QsXG4gICAgICAvLyBEaXNjb3JkIHNlbmRzIGFuIGludmFsaWQgc2Vzc2lvbiBwYXlsb2FkLlxuICAgICAgLy8gVGhpcyBjYW4gc2FmZWx5IGJlIGlnbm9yZWQgdGhvdWdoIGFuZCB0aGUgc2hhcmQgc3RhcnRzIGEgbmV3IGlkZW50aWZ5IGFjdGlvbi5cbiAgICAgIHRoaXMucmVzb2x2ZXMuc2V0KCdJTlZBTElEX1NFU1NJT04nLCAoKSA9PiB7XG4gICAgICAgIHRoaXMucmVzb2x2ZXMuZGVsZXRlKCdSRUFEWScpXG4gICAgICAgIHJlc29sdmUoKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqIENoZWNrIHdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gdG8gRGlzY29yZCBpcyBjdXJyZW50bHkgb3Blbi4gKi9cbiAgaXNPcGVuKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNvY2tldD8ucmVhZHlTdGF0ZSA9PT0gTm9kZVdlYlNvY2tldC5PUEVOXG4gIH1cblxuICAvKiogQXR0ZW1wdCB0byByZXN1bWUgdGhlIHByZXZpb3VzIHNoYXJkcyBzZXNzaW9uIHdpdGggdGhlIGdhdGV3YXkuICovXG4gIGFzeW5jIHJlc3VtZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIFJlc3VtaW5nIFNoYXJkICMke3RoaXMuaWR9YClcbiAgICAvLyBJdCBoYXMgYmVlbiByZXF1ZXN0ZWQgdG8gcmVzdW1lIHRoZSBTaGFyZHMgc2Vzc2lvbi5cbiAgICAvLyBJdCdzIHBvc3NpYmxlIHRoYXQgdGhlIHNoYXJkIGlzIHN0aWxsIGNvbm5lY3RlZCB3aXRoIERpc2NvcmQncyBnYXRld2F5IHRoZXJlZm9yZSB3ZSBuZWVkIHRvIGZvcmNlZnVsbHkgY2xvc2UgaXQuXG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gUmVzdW1pbmcgU2hhcmQgIyR7dGhpcy5pZH0gaW4gaXNPcGVuYClcbiAgICAgIHRoaXMuY2xvc2UoU2hhcmRTb2NrZXRDbG9zZUNvZGVzLlJlc3VtZUNsb3NpbmdPbGRDb25uZWN0aW9uLCAnUmVjb25uZWN0aW5nIHRoZSBzaGFyZCwgY2xvc2luZyBvbGQgY29ubmVjdGlvbi4nKVxuICAgIH1cblxuICAgIC8vIFNoYXJkIGhhcyBuZXZlciBpZGVudGlmaWVkLCBzbyB3ZSBjYW5ub3QgcmVzdW1lLlxuICAgIGlmICghdGhpcy5zZXNzaW9uSWQpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFRyeWluZyB0byByZXN1bWUgYSBzaGFyZCAjJHt0aGlzLmlkfSB0aGF0IHdhcyBOT1QgZmlyc3QgaWRlbnRpZmllZC4gKE5vIHNlc3Npb24gaWQgZm91bmQpYClcblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaWRlbnRpZnkoKVxuICAgIH1cblxuICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLlJlc3VtaW5nXG5cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIFJlc3VtaW5nIFNoYXJkICMke3RoaXMuaWR9LCBiZWZvcmUgY29ubmVjdGluZ2ApXG4gICAgLy8gQmVmb3JlIHdlIGNhbiByZXN1bWUsIHdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3IGNvbm5lY3Rpb24gd2l0aCBEaXNjb3JkJ3MgZ2F0ZXdheS5cbiAgICBhd2FpdCB0aGlzLmNvbm5lY3QoKVxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gUmVzdW1pbmcgU2hhcmQgIyR7dGhpcy5pZH0sIGFmdGVyIGNvbm5lY3RpbmcuICR7dGhpcy5zZXNzaW9uSWR9IHwgJHt0aGlzLnByZXZpb3VzU2VxdWVuY2VOdW1iZXJ9YClcblxuICAgIHRoaXMuc2VuZChcbiAgICAgIHtcbiAgICAgICAgb3A6IEdhdGV3YXlPcGNvZGVzLlJlc3VtZSxcbiAgICAgICAgZDoge1xuICAgICAgICAgIHRva2VuOiBgQm90ICR7dGhpcy5nYXRld2F5Q29uZmlnLnRva2VufWAsXG4gICAgICAgICAgc2Vzc2lvbl9pZDogdGhpcy5zZXNzaW9uSWQsXG4gICAgICAgICAgc2VxOiB0aGlzLnByZXZpb3VzU2VxdWVuY2VOdW1iZXIgPz8gMCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB0cnVlLFxuICAgIClcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIFJlc3VtaW5nIFNoYXJkICMke3RoaXMuaWR9IGFmdGVyIHNlbmQgcmVzdW1nYClcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgdGhpcy5yZXNvbHZlcy5zZXQoJ1JFU1VNRUQnLCAoKSA9PiByZXNvbHZlKCkpXG4gICAgICAvLyBJZiBpdCBpcyBhdHRlbXB0ZWQgdG8gcmVzdW1lIHdpdGggYW4gaW52YWxpZCBzZXNzaW9uIGlkLFxuICAgICAgLy8gRGlzY29yZCBzZW5kcyBhbiBpbnZhbGlkIHNlc3Npb24gcGF5bG9hZFxuICAgICAgLy8gTm90IGVycm9yaW5nIGhlcmUgc2luY2UgaXQgaXMgZWFzeSB0aGF0IHRoaXMgaGFwcGVucywgYWxzbyBpdCB3b3VsZCBiZSBub3QgY2F0Y2hhYmxlXG4gICAgICB0aGlzLnJlc29sdmVzLnNldCgnSU5WQUxJRF9TRVNTSU9OJywgKCkgPT4ge1xuICAgICAgICB0aGlzLnJlc29sdmVzLmRlbGV0ZSgnUkVTVU1FRCcpXG4gICAgICAgIHJlc29sdmUoKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqIFNlbmQgYSBtZXNzYWdlIHRvIERpc2NvcmQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hpZ2hQcmlvcml0eT1mYWxzZV0gLSBXaGV0aGVyIHRoaXMgbWVzc2FnZSBzaG91bGQgYmUgc2VuZCBhc2FwLlxuICAgKi9cbiAgYXN5bmMgc2VuZChtZXNzYWdlOiBTaGFyZFNvY2tldFJlcXVlc3QsIGhpZ2hQcmlvcml0eTogYm9vbGVhbiA9IGZhbHNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gQmVmb3JlIGFjcXVpcmluZyBhIHRva2VuIGZyb20gdGhlIGJ1Y2tldCwgY2hlY2sgd2hldGhlciB0aGUgc2hhcmQgaXMgY3VycmVudGx5IG9mZmxpbmUgb3Igbm90LlxuICAgIC8vIEVsc2UgYnVja2V0IGFuZCB0b2tlbiB3YWl0IHRpbWUganVzdCBnZXQgd2FzdGVkLlxuICAgIGF3YWl0IHRoaXMuY2hlY2tPZmZsaW5lKGhpZ2hQcmlvcml0eSlcblxuICAgIGF3YWl0IHRoaXMuYnVja2V0LmFjcXVpcmUoaGlnaFByaW9yaXR5KVxuXG4gICAgLy8gSXQncyBwb3NzaWJsZSwgdGhhdCB0aGUgc2hhcmQgd2VudCBvZmZsaW5lIGFmdGVyIGEgdG9rZW4gaGFzIGJlZW4gYWNxdWlyZWQgZnJvbSB0aGUgYnVja2V0LlxuICAgIGF3YWl0IHRoaXMuY2hlY2tPZmZsaW5lKGhpZ2hQcmlvcml0eSlcblxuICAgIHRoaXMuc29ja2V0Py5zZW5kKEpTT04uc3RyaW5naWZ5KG1lc3NhZ2UpKVxuICB9XG5cbiAgLyoqIFNodXRkb3duIHRoZSB0aGlzLiBGb3JjZWZ1bGx5IGRpc2Nvbm5lY3QgdGhlIHNoYXJkIGZyb20gRGlzY29yZC4gVGhlIHNoYXJkIG1heSBub3QgYXR0ZW1wdCB0byByZWNvbm5lY3Qgd2l0aCBEaXNjb3JkLiAqL1xuICBhc3luYyBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmNsb3NlKFNoYXJkU29ja2V0Q2xvc2VDb2Rlcy5TaHV0ZG93biwgJ1NoYXJkIHNodXR0aW5nIGRvd24uJylcbiAgICB0aGlzLnN0YXRlID0gU2hhcmRTdGF0ZS5PZmZsaW5lXG4gIH1cblxuICAvKiogSGFuZGxlIGEgZ2F0ZXdheSBjb25uZWN0aW9uIGNsb3NlLiAqL1xuICBhc3luYyBoYW5kbGVDbG9zZShjbG9zZTogTm9kZVdlYlNvY2tldC5DbG9zZUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gICBnYXRld2F5LmRlYnVnKFwiR1cgQ0xPU0VEXCIsIHsgc2hhcmRJZCwgcGF5bG9hZDogZXZlbnQgfSk7XG5cbiAgICB0aGlzLnN0b3BIZWFydGJlYXRpbmcoKVxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIEdhdGV3YXkgY29ubmVjdGlvbiBjbG9zZWQgd2l0aCBjb2RlICR7Y2xvc2UuY29kZX0uYClcblxuICAgIHN3aXRjaCAoY2xvc2UuY29kZSkge1xuICAgICAgY2FzZSBTaGFyZFNvY2tldENsb3NlQ29kZXMuVGVzdGluZ0ZpbmlzaGVkOiB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLk9mZmxpbmVcbiAgICAgICAgdGhpcy5ldmVudHMuZGlzY29ubmVjdGVkPy4odGhpcylcblxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIC8vIE9uIHRoZXNlIGNvZGVzIGEgbWFudWFsIHN0YXJ0IHdpbGwgYmUgZG9uZS5cbiAgICAgIGNhc2UgU2hhcmRTb2NrZXRDbG9zZUNvZGVzLlNodXRkb3duOlxuICAgICAgY2FzZSBTaGFyZFNvY2tldENsb3NlQ29kZXMuUmVJZGVudGlmeWluZzpcbiAgICAgIGNhc2UgU2hhcmRTb2NrZXRDbG9zZUNvZGVzLlJlc2hhcmRlZDpcbiAgICAgIGNhc2UgU2hhcmRTb2NrZXRDbG9zZUNvZGVzLlJlc3VtZUNsb3NpbmdPbGRDb25uZWN0aW9uOlxuICAgICAgY2FzZSBTaGFyZFNvY2tldENsb3NlQ29kZXMuWm9tYmllZENvbm5lY3Rpb246IHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNoYXJkU3RhdGUuRGlzY29ubmVjdGVkXG4gICAgICAgIHRoaXMuZXZlbnRzLmRpc2Nvbm5lY3RlZD8uKHRoaXMpXG5cbiAgICAgICAgLy8gZ2F0ZXdheS5kZWJ1ZyhcIkdXIENMT1NFRF9SRUNPTk5FQ1RcIiwgeyBzaGFyZElkLCBwYXlsb2FkOiBldmVudCB9KTtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICAvLyBHYXRld2F5IGNvbm5lY3Rpb24gY2xvc2VzIHdoaWNoIHJlcXVpcmUgYSBuZXcgaWRlbnRpZnkuXG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuVW5rbm93bk9wY29kZTpcbiAgICAgIGNhc2UgR2F0ZXdheUNsb3NlRXZlbnRDb2Rlcy5Ob3RBdXRoZW50aWNhdGVkOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRTZXE6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuUmF0ZUxpbWl0ZWQ6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuU2Vzc2lvblRpbWVkT3V0OiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKCdbU2hhcmRdIEdhdGV3YXkgY29ubmVjdGlvbiBjbG9zaW5nIHJlcXVpcmluZyByZS1pZGVudGlmeS4nKVxuICAgICAgICB0aGlzLnN0YXRlID0gU2hhcmRTdGF0ZS5JZGVudGlmeWluZ1xuICAgICAgICB0aGlzLmV2ZW50cy5kaXNjb25uZWN0ZWQ/Lih0aGlzKVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmlkZW50aWZ5KClcbiAgICAgIH1cbiAgICAgIC8vIFdoZW4gdGhlc2UgY29kZXMgYXJlIHJlY2VpdmVkIHNvbWV0aGluZyB3ZW50IHJlYWxseSB3cm9uZy5cbiAgICAgIC8vIE9uIHRob3NlIHdlIGNhbm5vdCBzdGFydCBhIHJlY29ubmVjdCBhdHRlbXB0LlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkF1dGhlbnRpY2F0aW9uRmFpbGVkOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRTaGFyZDpcbiAgICAgIGNhc2UgR2F0ZXdheUNsb3NlRXZlbnRDb2Rlcy5TaGFyZGluZ1JlcXVpcmVkOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRBcGlWZXJzaW9uOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRJbnRlbnRzOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkRpc2FsbG93ZWRJbnRlbnRzOiB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLk9mZmxpbmVcbiAgICAgICAgdGhpcy5ldmVudHMuZGlzY29ubmVjdGVkPy4odGhpcylcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoY2xvc2UucmVhc29uIHx8ICdEaXNjb3JkIGdhdmUgbm8gcmVhc29uISBHRyEgWW91IGJyb2tlIERpc2NvcmQhJylcbiAgICAgIH1cbiAgICAgIC8vIEdhdGV3YXkgY29ubmVjdGlvbiBjbG9zZXMgb24gd2hpY2ggYSByZXN1bWUgaXMgYWxsb3dlZC5cbiAgICAgIGNhc2UgR2F0ZXdheUNsb3NlRXZlbnRDb2Rlcy5Vbmtub3duRXJyb3I6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuRGVjb2RlRXJyb3I6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuQWxyZWFkeUF1dGhlbnRpY2F0ZWQ6XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmluZm8oYFtTaGFyZF0gQ2xvc2VkIHNoYXJkICMke3RoaXMuaWR9IHdpdGggY29kZSAke2Nsb3NlLmNvZGV9LiBBdHRlbXB0aW5nIHRvIHJlc3VtZS4uLmApXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLlJlc3VtaW5nXG4gICAgICAgIHRoaXMuZXZlbnRzLmRpc2Nvbm5lY3RlZD8uKHRoaXMpXG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVzdW1lKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogSGFuZGxlcyBhIGluY29taW5nIGdhdGV3YXkgcGFja2V0LiAqL1xuICBhc3luYyBoYW5kbGVEaXNjb3JkUGFja2V0KHBhY2tldDogRGlzY29yZEdhdGV3YXlQYXlsb2FkKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gRWRnZSBjYXNlIHN0YXJ0OiBodHRwczovL2dpdGh1Yi5jb20vZGlzY29yZGVuby9kaXNjb3JkZW5vL2lzc3Vlcy8yMzExXG4gICAgdGhpcy5oZWFydC5sYXN0QWNrID0gRGF0ZS5ub3coKVxuICAgIHRoaXMuaGVhcnQuYWNrbm93bGVkZ2VkID0gdHJ1ZVxuICAgIC8vIEVkZ2UgY2FzZSBlbmQhXG5cbiAgICBzd2l0Y2ggKHBhY2tldC5vcCkge1xuICAgICAgY2FzZSBHYXRld2F5T3Bjb2Rlcy5IZWFydGJlYXQ6IHtcbiAgICAgICAgLy8gVE9ETzogY2FuIHRoaXMgYWN0dWFsbHkgaGFwcGVuXG4gICAgICAgIGlmICghdGhpcy5pc09wZW4oKSkgcmV0dXJuXG5cbiAgICAgICAgdGhpcy5oZWFydC5sYXN0QmVhdCA9IERhdGUubm93KClcbiAgICAgICAgLy8gRGlzY29yZCByYW5kb21seSBzZW5kcyB0aGlzIHJlcXVpcmluZyBhbiBpbW1lZGlhdGUgaGVhcnRiZWF0IGJhY2suXG4gICAgICAgIC8vIFVzaW5nIGEgZGlyZWN0IHNvY2tldC5zZW5kIGNhbGwgaGVyZSBiZWNhdXNlIGhlYXJ0YmVhdCByZXF1ZXN0cyBhcmUgcmVzZXJ2ZWQgYnkgdXMuXG4gICAgICAgIHRoaXMuc29ja2V0Py5zZW5kKFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIG9wOiBHYXRld2F5T3Bjb2Rlcy5IZWFydGJlYXQsXG4gICAgICAgICAgICBkOiB0aGlzLnByZXZpb3VzU2VxdWVuY2VOdW1iZXIsXG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICAgdGhpcy5ldmVudHMuaGVhcnRiZWF0Py4odGhpcylcblxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSBHYXRld2F5T3Bjb2Rlcy5IZWxsbzoge1xuICAgICAgICBjb25zdCBpbnRlcnZhbCA9IChwYWNrZXQuZCBhcyBEaXNjb3JkSGVsbG8pLmhlYXJ0YmVhdF9pbnRlcnZhbFxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIEhlbGxvIG9uIFNoYXJkICMke3RoaXMuaWR9YClcbiAgICAgICAgdGhpcy5zdGFydEhlYXJ0YmVhdGluZyhpbnRlcnZhbClcblxuICAgICAgICBpZiAodGhpcy5zdGF0ZSAhPT0gU2hhcmRTdGF0ZS5SZXN1bWluZykge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRRdWV1ZSA9IFsuLi50aGlzLmJ1Y2tldC5xdWV1ZV1cbiAgICAgICAgICAvLyBIRUxMTyBoYXMgYmVlbiBzZW5kIG9uIGEgbm9uIHJlc3VtZSBhY3Rpb24uXG4gICAgICAgICAgLy8gVGhpcyBtZWFucyB0aGF0IHRoZSBzaGFyZCBzdGFydHMgYSBuZXcgc2Vzc2lvbixcbiAgICAgICAgICAvLyB0aGVyZWZvcmUgdGhlIHJhdGUgbGltaXQgaW50ZXJ2YWwgaGFzIGJlZW4gcmVzZXQgdG9vLlxuICAgICAgICAgIHRoaXMuYnVja2V0ID0gbmV3IExlYWt5QnVja2V0KHtcbiAgICAgICAgICAgIG1heDogdGhpcy5jYWxjdWxhdGVTYWZlUmVxdWVzdHMoKSxcbiAgICAgICAgICAgIHJlZmlsbEludGVydmFsOiA2MDAwMCxcbiAgICAgICAgICAgIHJlZmlsbEFtb3VudDogdGhpcy5jYWxjdWxhdGVTYWZlUmVxdWVzdHMoKSxcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgLy8gUXVldWUgc2hvdWxkIG5vdCBiZSBsb3N0IG9uIGEgcmUtaWRlbnRpZnkuXG4gICAgICAgICAgdGhpcy5idWNrZXQucXVldWUudW5zaGlmdCguLi5jdXJyZW50UXVldWUpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50cy5oZWxsbz8uKHRoaXMpXG5cbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgR2F0ZXdheU9wY29kZXMuSGVhcnRiZWF0QUNLOiB7XG4gICAgICAgIC8vIE1hbnVhbGx5IGNhbGN1bGF0aW5nIHRoZSByb3VuZCB0cmlwIHRpbWUgZm9yIHVzZXJzIHdobyBuZWVkIGl0LlxuICAgICAgICBpZiAodGhpcy5oZWFydC5sYXN0QmVhdCkge1xuICAgICAgICAgIHRoaXMuaGVhcnQucnR0ID0gdGhpcy5oZWFydC5sYXN0QWNrIC0gdGhpcy5oZWFydC5sYXN0QmVhdFxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ldmVudHMuaGVhcnRiZWF0QWNrPy4odGhpcylcblxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSBHYXRld2F5T3Bjb2Rlcy5SZWNvbm5lY3Q6IHtcbiAgICAgICAgLy8gICBnYXRld2F5LmRlYnVnKFwiR1cgUkVDT05ORUNUXCIsIHsgc2hhcmRJZCB9KTtcblxuICAgICAgICB0aGlzLmV2ZW50cy5yZXF1ZXN0ZWRSZWNvbm5lY3Q/Lih0aGlzKVxuXG4gICAgICAgIGF3YWl0IHRoaXMucmVzdW1lKClcblxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSBHYXRld2F5T3Bjb2Rlcy5JbnZhbGlkU2Vzc2lvbjoge1xuICAgICAgICBjb25zdCByZXN1bWFibGUgPSBwYWNrZXQuZCBhcyBib29sZWFuXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFJlY2VpdmVkIEludmFsaWQgU2Vzc2lvbiBmb3IgU2hhcmQgIyR7dGhpcy5pZH0gd2l0aCByZXN1bWVhYmxlIGFzICR7cmVzdW1hYmxlLnRvU3RyaW5nKCl9YClcblxuICAgICAgICB0aGlzLmV2ZW50cy5pbnZhbGlkU2Vzc2lvbj8uKHRoaXMsIHJlc3VtYWJsZSlcblxuICAgICAgICAvLyBXZSBuZWVkIHRvIHdhaXQgZm9yIGEgcmFuZG9tIGFtb3VudCBvZiB0aW1lIGJldHdlZW4gMSBhbmQgNVxuICAgICAgICAvLyBSZWZlcmVuY2U6IGh0dHBzOi8vZGlzY29yZC5jb20vZGV2ZWxvcGVycy9kb2NzL3RvcGljcy9nYXRld2F5I3Jlc3VtaW5nXG4gICAgICAgIGF3YWl0IGRlbGF5KE1hdGguZmxvb3IoKE1hdGgucmFuZG9tKCkgKiA0ICsgMSkgKiAxMDAwKSlcblxuICAgICAgICB0aGlzLnJlc29sdmVzLmdldCgnSU5WQUxJRF9TRVNTSU9OJyk/LihwYWNrZXQpXG4gICAgICAgIHRoaXMucmVzb2x2ZXMuZGVsZXRlKCdJTlZBTElEX1NFU1NJT04nKVxuXG4gICAgICAgIC8vIFdoZW4gcmVzdW1hYmxlIGlzIGZhbHNlIHdlIG5lZWQgdG8gcmUtaWRlbnRpZnlcbiAgICAgICAgaWYgKCFyZXN1bWFibGUpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnJlcXVlc3RJZGVudGlmeSgpXG5cbiAgICAgICAgICBicmVha1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlIHNlc3Npb24gaXMgaW52YWxpZCBidXQgYXBwYXJlbnRseSBpdCBpcyByZXN1bWFibGVcbiAgICAgICAgYXdhaXQgdGhpcy5yZXN1bWUoKVxuXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuXG4gICAgc3dpdGNoIChwYWNrZXQudCkge1xuICAgICAgY2FzZSAnUkVTVU1FRCc6XG4gICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLkNvbm5lY3RlZFxuICAgICAgICB0aGlzLmV2ZW50cy5yZXN1bWVkPy4odGhpcylcblxuICAgICAgICAvLyBDb250aW51ZSB0aGUgcmVxdWVzdHMgd2hpY2ggaGF2ZSBiZWVuIHF1ZXVlZCBzaW5jZSB0aGUgc2hhcmQgd2VudCBvZmZsaW5lLlxuICAgICAgICB0aGlzLm9mZmxpbmVTZW5kUXVldWUubWFwKChyZXNvbHZlKSA9PiByZXNvbHZlKCkpXG5cbiAgICAgICAgdGhpcy5yZXNvbHZlcy5nZXQoJ1JFU1VNRUQnKT8uKHBhY2tldClcbiAgICAgICAgdGhpcy5yZXNvbHZlcy5kZWxldGUoJ1JFU1VNRUQnKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnUkVBRFknOiB7XG4gICAgICAgIC8vIEltcG9ydGFudCBmb3IgZnV0dXJlIHJlc3VtZXMuXG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBwYWNrZXQuZCBhcyBEaXNjb3JkUmVhZHlcblxuICAgICAgICB0aGlzLnJlc3VtZUdhdGV3YXlVcmwgPSBwYXlsb2FkLnJlc3VtZV9nYXRld2F5X3VybFxuXG4gICAgICAgIHRoaXMuc2Vzc2lvbklkID0gcGF5bG9hZC5zZXNzaW9uX2lkXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLkNvbm5lY3RlZFxuXG4gICAgICAgIC8vIENvbnRpbnVlIHRoZSByZXF1ZXN0cyB3aGljaCBoYXZlIGJlZW4gcXVldWVkIHNpbmNlIHRoZSBzaGFyZCB3ZW50IG9mZmxpbmUuXG4gICAgICAgIC8vIEltcG9ydGFudCB3aGVuIHRoaXMgaXMgYSByZS1pZGVudGlmeVxuICAgICAgICB0aGlzLm9mZmxpbmVTZW5kUXVldWUubWFwKChyZXNvbHZlKSA9PiByZXNvbHZlKCkpXG5cbiAgICAgICAgdGhpcy5yZXNvbHZlcy5nZXQoJ1JFQURZJyk/LihwYWNrZXQpXG4gICAgICAgIHRoaXMucmVzb2x2ZXMuZGVsZXRlKCdSRUFEWScpXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIHRoZSBzZXF1ZW5jZSBudW1iZXIgaWYgaXQgaXMgcHJlc2VudFxuICAgIC8vIGBzYCBjYW4gYmUgZWl0aGVyIGBudWxsYCBvciBhIGBudW1iZXJgLlxuICAgIC8vIEluIG9yZGVyIHRvIHByZXZlbnQgdXBkYXRlIG1pc3NlcyB3aGVuIGBzYCBpcyBgMGAgd2UgY2hlY2sgYWdhaW5zdCBudWxsLlxuICAgIGlmIChwYWNrZXQucyAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5wcmV2aW91c1NlcXVlbmNlTnVtYmVyID0gcGFja2V0LnNcbiAgICB9XG5cbiAgICB0aGlzLmZvcndhcmRUb0JvdChwYWNrZXQpXG4gIH1cblxuICBmb3J3YXJkVG9Cb3QocGFja2V0OiBEaXNjb3JkR2F0ZXdheVBheWxvYWQpOiB2b2lkIHtcbiAgICAvLyBUaGUgbmVjZXNzYXJ5IGhhbmRsaW5nIHJlcXVpcmVkIGZvciB0aGUgU2hhcmRzIGNvbm5lY3Rpb24gaGFzIGJlZW4gZmluaXNoZWQuXG4gICAgLy8gTm93IHRoZSBldmVudCBjYW4gYmUgc2FmZWx5IGZvcndhcmRlZC5cbiAgICB0aGlzLmV2ZW50cy5tZXNzYWdlPy4odGhpcywgY2FtZWxpemUocGFja2V0KSlcbiAgfVxuXG4gIC8qKiBIYW5kbGUgYW4gaW5jb21pbmcgZ2F0ZXdheSBtZXNzYWdlLiAqL1xuICBhc3luYyBoYW5kbGVNZXNzYWdlKG1lc3NhZ2U6IE5vZGVXZWJTb2NrZXQuTWVzc2FnZUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IHByZVByb2Nlc3NNZXNzYWdlID0gbWVzc2FnZS5kYXRhXG5cbiAgICAvLyBJZiBtZXNzYWdlIGNvbXByZXNzaW9uIGlzIGVuYWJsZWQsXG4gICAgLy8gRGlzY29yZCBtaWdodCBzZW5kIHpsaWIgY29tcHJlc3NlZCBwYXlsb2Fkcy5cbiAgICBpZiAodGhpcy5nYXRld2F5Q29uZmlnLmNvbXByZXNzICYmIHByZVByb2Nlc3NNZXNzYWdlIGluc3RhbmNlb2YgQmxvYikge1xuICAgICAgcHJlUHJvY2Vzc01lc3NhZ2UgPSBpbmZsYXRlU3luYyhhd2FpdCBwcmVQcm9jZXNzTWVzc2FnZS5hcnJheUJ1ZmZlcigpKS50b1N0cmluZygpXG4gICAgfVxuXG4gICAgLy8gU2FmZWd1YXJkIGluY2FzZSBkZWNvbXByZXNzaW9uIGZhaWxlZCB0byBtYWtlIGEgc3RyaW5nLlxuICAgIGlmICh0eXBlb2YgcHJlUHJvY2Vzc01lc3NhZ2UgIT09ICdzdHJpbmcnKSByZXR1cm5cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmhhbmRsZURpc2NvcmRQYWNrZXQoSlNPTi5wYXJzZShwcmVQcm9jZXNzTWVzc2FnZSkgYXMgRGlzY29yZEdhdGV3YXlQYXlsb2FkKVxuICB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIGluIG9yZGVyIHRvIG1ha2UgdGhlIHNoYXJkcyBwcmVzZW5jZS5cbiAgICogYXN5bmMgaW4gY2FzZSBkZXZzIGNyZWF0ZSB0aGUgcHJlc2VuY2UgYmFzZWQgb24gZWcuIGRhdGFiYXNlIHZhbHVlcy5cbiAgICogUGFzc2luZyB0aGUgc2hhcmQncyBpZCB0aGVyZSB0byBtYWtlIGl0IGVhc2llciBmb3IgdGhlIGRldiB0byB1c2UgdGhpcyBmdW5jdGlvbi5cbiAgICovXG4gIGFzeW5jIG1ha2VQcmVzZW5jZSgpOiBQcm9taXNlPEJvdFN0YXR1c1VwZGF0ZSB8IHVuZGVmaW5lZD4ge1xuICAgIHJldHVyblxuICB9XG5cbiAgLyoqIFRoaXMgZnVuY3Rpb24gY29tbXVuaWNhdGVzIHdpdGggdGhlIG1hbmFnZW1lbnQgcHJvY2VzcywgaW4gb3JkZXIgdG8ga25vdyB3aGV0aGVyIGl0cyBmcmVlIHRvIGlkZW50aWZ5LiBXaGVuIHRoaXMgZnVuY3Rpb24gcmVzb2x2ZXMsIHRoaXMgbWVhbnMgdGhhdCB0aGUgc2hhcmQgaXMgYWxsb3dlZCB0byBzZW5kIGFuIGlkZW50aWZ5IHBheWxvYWQgdG8gZGlzY29yZC4gKi9cbiAgYXN5bmMgcmVxdWVzdElkZW50aWZ5KCk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogVGhpcyBmdW5jdGlvbiBjb21tdW5pY2F0ZXMgd2l0aCB0aGUgbWFuYWdlbWVudCBwcm9jZXNzLCBpbiBvcmRlciB0byB0ZWxsIGl0IGNhbiBpZGVudGlmeSB0aGUgbmV4dCBzaGFyZC4gKi9cbiAgYXN5bmMgc2hhcmRJc1JlYWR5KCk6IFByb21pc2U8dm9pZD4ge31cblxuICAvKiogU3RhcnQgc2VuZGluZyBoZWFydGJlYXQgcGF5bG9hZHMgdG8gRGlzY29yZCBpbiB0aGUgcHJvdmlkZWQgaW50ZXJ2YWwuICovXG4gIHN0YXJ0SGVhcnRiZWF0aW5nKGludGVydmFsOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIFN0YXJ0IEhlYXJ0YmVhdGluZyBTaGFyZCAjJHt0aGlzLmlkfWApXG4gICAgLy8gSWYgb2xkIGhlYXJ0YmVhc3QgZXhpc3QgbGlrZSBhZnRlciByZXN1bWUsIGNsZWFyIHRoZSBvbGQgb25lcy5cbiAgICBpZiAodGhpcy5oZWFydC5pbnRlcnZhbElkKSBjbGVhckludGVydmFsKHRoaXMuaGVhcnQuaW50ZXJ2YWxJZClcbiAgICBpZiAodGhpcy5oZWFydC50aW1lb3V0SWQpIGNsZWFyVGltZW91dCh0aGlzLmhlYXJ0LnRpbWVvdXRJZClcblxuICAgIHRoaXMuaGVhcnQuaW50ZXJ2YWwgPSBpbnRlcnZhbFxuXG4gICAgLy8gT25seSBzZXQgdGhlIHNoYXJkJ3Mgc3RhdGUgdG8gYFVuaWRlbnRpZmllZGBcbiAgICAvLyBpZiBoZWFydGJlYXRpbmcgaGFzIG5vdCBiZWVuIHN0YXJ0ZWQgZHVlIHRvIGFuIGlkZW50aWZ5IG9yIHJlc3VtZSBhY3Rpb24uXG4gICAgaWYgKFtTaGFyZFN0YXRlLkRpc2Nvbm5lY3RlZCwgU2hhcmRTdGF0ZS5PZmZsaW5lXS5pbmNsdWRlcyh0aGlzLnN0YXRlKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtHYXRld2F5XSBTdGFydCBIZWFydGJlYXRpbmcgU2hhcmQgIyR7dGhpcy5pZH0gYWApXG4gICAgICB0aGlzLnN0YXRlID0gU2hhcmRTdGF0ZS5VbmlkZW50aWZpZWRcbiAgICB9XG5cbiAgICAvLyBUaGUgZmlyc3QgaGVhcnRiZWF0IG5lZWRzIHRvIGJlIHNlbmQgd2l0aCBhIHJhbmRvbSBkZWxheSBiZXR3ZWVuIGAwYCBhbmQgYGludGVydmFsYFxuICAgIC8vIFVzaW5nIGEgYHNldFRpbWVvdXQoXywgaml0dGVyKWAgaGVyZSB0byBhY2NvbXBsaXNoIHRoYXQuXG4gICAgLy8gYE1hdGgucmFuZG9tKClgIGNhbiBiZSBgMGAgc28gd2UgdXNlIGAwLjVgIGlmIHRoaXMgaGFwcGVuc1xuICAgIC8vIFJlZmVyZW5jZTogaHR0cHM6Ly9kaXNjb3JkLmNvbS9kZXZlbG9wZXJzL2RvY3MvdG9waWNzL2dhdGV3YXkjaGVhcnRiZWF0aW5nXG4gICAgY29uc3Qgaml0dGVyID0gTWF0aC5jZWlsKHRoaXMuaGVhcnQuaW50ZXJ2YWwgKiAoTWF0aC5yYW5kb20oKSB8fCAwLjUpKVxuICAgIHRoaXMuaGVhcnQudGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIFN0YXJ0IEhlYXJ0YmVhdGluZyBTaGFyZCAjJHt0aGlzLmlkfSBiYClcbiAgICAgIGlmICghdGhpcy5pc09wZW4oKSkgcmV0dXJuXG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW0dhdGV3YXldIFN0YXJ0IEhlYXJ0YmVhdGluZyBTaGFyZCAjJHt0aGlzLmlkfSBjICR7dGhpcy5wcmV2aW91c1NlcXVlbmNlTnVtYmVyIX1gKVxuXG4gICAgICAvLyBVc2luZyBhIGRpcmVjdCBzb2NrZXQuc2VuZCBjYWxsIGhlcmUgYmVjYXVzZSBoZWFydGJlYXQgcmVxdWVzdHMgYXJlIHJlc2VydmVkIGJ5IHVzLlxuICAgICAgdGhpcy5zb2NrZXQ/LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBvcDogR2F0ZXdheU9wY29kZXMuSGVhcnRiZWF0LFxuICAgICAgICAgIGQ6IHRoaXMucHJldmlvdXNTZXF1ZW5jZU51bWJlcixcbiAgICAgICAgfSksXG4gICAgICApXG5cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gU3RhcnQgSGVhcnRiZWF0aW5nIFNoYXJkICMke3RoaXMuaWR9IGRgKVxuICAgICAgdGhpcy5oZWFydC5sYXN0QmVhdCA9IERhdGUubm93KClcbiAgICAgIHRoaXMuaGVhcnQuYWNrbm93bGVkZ2VkID0gZmFsc2VcblxuICAgICAgLy8gQWZ0ZXIgdGhlIHJhbmRvbSBoZWFydGJlYXQgaml0dGVyIHdlIGNhbiBzdGFydCBhIG5vcm1hbCBpbnRlcnZhbC5cbiAgICAgIHRoaXMuaGVhcnQuaW50ZXJ2YWxJZCA9IHNldEludGVydmFsKGFzeW5jICgpID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtHYXRld2F5XSBTdGFydCBIZWFydGJlYXRpbmcgU2hhcmQgIyR7dGhpcy5pZH0gZWApXG4gICAgICAgIGlmICghdGhpcy5pc09wZW4oKSkgcmV0dXJuXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gU3RhcnQgSGVhcnRiZWF0aW5nIFNoYXJkICMke3RoaXMuaWR9IGZgKVxuICAgICAgICAvLyBnYXRld2F5LmRlYnVnKFwiR1cgREVCVUdcIiwgYFJ1bm5pbmcgc2V0SW50ZXJ2YWwgaW4gaGVhcnRiZWF0IGZpbGUuIFNoYXJkOiAke3NoYXJkSWR9YCk7XG5cbiAgICAgICAgLy8gZ2F0ZXdheS5kZWJ1ZyhcIkdXIEhFQVJUQkVBVElOR1wiLCB7IHNoYXJkSWQsIHNoYXJkOiBjdXJyZW50U2hhcmQgfSk7XG5cbiAgICAgICAgLy8gVGhlIFNoYXJkIGRpZCBub3QgcmVjZWl2ZSBhIGhlYXJ0YmVhdCBBQ0sgZnJvbSBEaXNjb3JkIGluIHRpbWUsXG4gICAgICAgIC8vIHRoZXJlZm9yZSB3ZSBoYXZlIHRvIGFzc3VtZSB0aGF0IHRoZSBjb25uZWN0aW9uIGhhcyBmYWlsZWQgb3IgZ290IFwiem9tYmllZFwiLlxuICAgICAgICAvLyBUaGUgU2hhcmQgbmVlZHMgdG8gc3RhcnQgYSByZS1pZGVudGlmeSBhY3Rpb24gYWNjb3JkaW5nbHkuXG4gICAgICAgIC8vIFJlZmVyZW5jZTogaHR0cHM6Ly9kaXNjb3JkLmNvbS9kZXZlbG9wZXJzL2RvY3MvdG9waWNzL2dhdGV3YXkjaGVhcnRiZWF0aW5nLWV4YW1wbGUtZ2F0ZXdheS1oZWFydGJlYXQtYWNrXG4gICAgICAgIGlmICghdGhpcy5oZWFydC5hY2tub3dsZWRnZWQpIHtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW1NoYXJkXSBIZWFydGJlYXQgbm90IGFja25vd2xlZGdlZCBmb3Igc2hhcmQgIyR7dGhpcy5pZH0uYClcbiAgICAgICAgICB0aGlzLmNsb3NlKFNoYXJkU29ja2V0Q2xvc2VDb2Rlcy5ab21iaWVkQ29ubmVjdGlvbiwgJ1pvbWJpZWQgY29ubmVjdGlvbiwgZGlkIG5vdCByZWNlaXZlIGFuIGhlYXJ0YmVhdCBBQ0sgaW4gdGltZS4nKVxuXG4gICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaWRlbnRpZnkoKVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5oZWFydC5hY2tub3dsZWRnZWQgPSBmYWxzZVxuXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gU3RhcnQgSGVhcnRiZWF0aW5nIFNoYXJkICMke3RoaXMuaWR9IGdgKVxuICAgICAgICAvLyBVc2luZyBhIGRpcmVjdCBzb2NrZXQuc2VuZCBjYWxsIGhlcmUgYmVjYXVzZSBoZWFydGJlYXQgcmVxdWVzdHMgYXJlIHJlc2VydmVkIGJ5IHVzLlxuICAgICAgICB0aGlzLnNvY2tldD8uc2VuZChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBvcDogR2F0ZXdheU9wY29kZXMuSGVhcnRiZWF0LFxuICAgICAgICAgICAgZDogdGhpcy5wcmV2aW91c1NlcXVlbmNlTnVtYmVyLFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbR2F0ZXdheV0gU3RhcnQgSGVhcnRiZWF0aW5nIFNoYXJkICMke3RoaXMuaWR9IGhgKVxuXG4gICAgICAgIHRoaXMuaGVhcnQubGFzdEJlYXQgPSBEYXRlLm5vdygpXG5cbiAgICAgICAgdGhpcy5ldmVudHMuaGVhcnRiZWF0Py4odGhpcylcbiAgICAgIH0sIHRoaXMuaGVhcnQuaW50ZXJ2YWwpXG4gICAgfSwgaml0dGVyKVxuICB9XG5cbiAgLyoqIFN0b3AgdGhlIGhlYXJ0YmVhdGluZyBwcm9jZXNzIHdpdGggZGlzY29yZC4gKi9cbiAgc3RvcEhlYXJ0YmVhdGluZygpOiB2b2lkIHtcbiAgICAvLyBDbGVhciB0aGUgcmVndWxhciBoZWFydGJlYXQgaW50ZXJ2YWwuXG4gICAgY2xlYXJJbnRlcnZhbCh0aGlzLmhlYXJ0LmludGVydmFsSWQpXG4gICAgLy8gSXQncyBwb3NzaWJsZSB0aGF0IHRoZSBTaGFyZCBnb3QgY2xvc2VkIGJlZm9yZSB0aGUgZmlyc3Qgaml0dGVyZWQgaGVhcnRiZWF0LlxuICAgIC8vIFRvIGdvIHNhZmUgd2Ugc2hvdWxkIGNsZWFyIHRoZSByZWxhdGVkIHRpbWVvdXQgdG9vLlxuICAgIGNsZWFyVGltZW91dCh0aGlzLmhlYXJ0LnRpbWVvdXRJZClcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJkQ3JlYXRlT3B0aW9ucyB7XG4gIC8qKiBUaGUgc2hhcmQgaWQgKi9cbiAgaWQ6IG51bWJlclxuICAvKiogVGhlIGNvbm5lY3Rpb24gZGV0YWlscyAqL1xuICBjb25uZWN0aW9uOiBTaGFyZEdhdGV3YXlDb25maWdcbiAgLyoqIFRoZSBldmVudCBoYW5kbGVycyBmb3IgZXZlbnRzIG9uIHRoZSBzaGFyZC4gKi9cbiAgZXZlbnRzOiBTaGFyZEV2ZW50c1xuICAvKiogVGhlIGxvZ2dlciBmb3IgdGhlIHNoYXJkICovXG4gIGxvZ2dlcj86IFBpY2s8dHlwZW9mIGxvZ2dlciwgJ2RlYnVnJyB8ICdpbmZvJyB8ICd3YXJuJyB8ICdlcnJvcicgfCAnZmF0YWwnPlxuICAvKiogVGhlIGhhbmRsZXIgdG8gcmVxdWVzdCBhIHNwYWNlIHRvIG1ha2UgYW4gaWRlbnRpZnkgcmVxdWVzdC4gKi9cbiAgcmVxdWVzdElkZW50aWZ5PzogKCkgPT4gUHJvbWlzZTx2b2lkPlxuICAvKiogVGhlIGhhbmRsZXIgdG8gYWxlcnQgdGhlIGdhdGV3YXkgbWFuYWdlciB0aGF0IHRoaXMgc2hhcmQgaGFzIHJlY2VpdmVkIGEgUkVBRFkgZXZlbnQuICovXG4gIHNoYXJkSXNSZWFkeT86ICgpID0+IFByb21pc2U8dm9pZD5cbn1cblxuZXhwb3J0IGRlZmF1bHQgRGlzY29yZGVub1NoYXJkXG4iXSwibmFtZXMiOlsiRGlzY29yZGVub1NoYXJkIiwiY29uc3RydWN0b3IiLCJvcHRpb25zIiwibWF4UmVxdWVzdHNQZXJSYXRlTGltaXRUaWNrIiwicHJldmlvdXNTZXF1ZW5jZU51bWJlciIsInJhdGVMaW1pdFJlc2V0SW50ZXJ2YWwiLCJzdGF0ZSIsIlNoYXJkU3RhdGUiLCJPZmZsaW5lIiwicmVzdW1lR2F0ZXdheVVybCIsImV2ZW50cyIsIm9mZmxpbmVTZW5kUXVldWUiLCJyZXNvbHZlcyIsIk1hcCIsImlkIiwiY29ubmVjdGlvbiIsImxvZ2dlciIsImhlYXJ0IiwiYWNrbm93bGVkZ2VkIiwiaW50ZXJ2YWwiLCJyZXF1ZXN0SWRlbnRpZnkiLCJzaGFyZElzUmVhZHkiLCJidWNrZXQiLCJMZWFreUJ1Y2tldCIsIm1heCIsImNhbGN1bGF0ZVNhZmVSZXF1ZXN0cyIsInJlZmlsbEFtb3VudCIsInJlZmlsbEludGVydmFsIiwiZ2F0ZXdheUNvbmZpZyIsImNvbm5lY3Rpb25VcmwiLCJ1cmwiLCJzYWZlUmVxdWVzdHMiLCJNYXRoIiwiY2VpbCIsImNoZWNrT2ZmbGluZSIsImhpZ2hQcmlvcml0eSIsImlzT3BlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwidW5zaGlmdCIsInB1c2giLCJjbG9zZSIsImNvZGUiLCJyZWFzb24iLCJzb2NrZXQiLCJyZWFkeVN0YXRlIiwiTm9kZVdlYlNvY2tldCIsIk9QRU4iLCJjb25uZWN0IiwiSWRlbnRpZnlpbmciLCJSZXN1bWluZyIsImluY2x1ZGVzIiwiQ29ubmVjdGluZyIsImNvbm5lY3RpbmciLCJVUkwiLCJzZWFyY2hQYXJhbXMiLCJzZXQiLCJ2ZXJzaW9uIiwidG9TdHJpbmciLCJnbG9iYWxUaGlzIiwiRGVubyIsInVuZGVmaW5lZCIsIlJlZmxlY3QiLCJoYXMiLCJXZWJTb2NrZXQiLCJvbmVycm9yIiwiZXZlbnQiLCJjb25zb2xlIiwibG9nIiwiZXJyb3IiLCJzaGFyZElkIiwib25jbG9zZSIsImhhbmRsZUNsb3NlIiwib25tZXNzYWdlIiwibWVzc2FnZSIsImhhbmRsZU1lc3NhZ2UiLCJvbm9wZW4iLCJVbmlkZW50aWZpZWQiLCJjb25uZWN0ZWQiLCJpZGVudGlmeSIsImRlYnVnIiwiU2hhcmRTb2NrZXRDbG9zZUNvZGVzIiwiUmVJZGVudGlmeWluZyIsImlkZW50aWZ5aW5nIiwic2VuZCIsIm9wIiwiR2F0ZXdheU9wY29kZXMiLCJJZGVudGlmeSIsImQiLCJ0b2tlbiIsImNvbXByZXNzIiwicHJvcGVydGllcyIsImludGVudHMiLCJzaGFyZCIsInRvdGFsU2hhcmRzIiwicHJlc2VuY2UiLCJtYWtlUHJlc2VuY2UiLCJpZGVudGlmaWVkIiwiZGVsZXRlIiwicmVzdW1lIiwiUmVzdW1lQ2xvc2luZ09sZENvbm5lY3Rpb24iLCJzZXNzaW9uSWQiLCJSZXN1bWUiLCJzZXNzaW9uX2lkIiwic2VxIiwiYWNxdWlyZSIsIkpTT04iLCJzdHJpbmdpZnkiLCJzaHV0ZG93biIsIlNodXRkb3duIiwic3RvcEhlYXJ0YmVhdGluZyIsIlRlc3RpbmdGaW5pc2hlZCIsImRpc2Nvbm5lY3RlZCIsIlJlc2hhcmRlZCIsIlpvbWJpZWRDb25uZWN0aW9uIiwiRGlzY29ubmVjdGVkIiwiR2F0ZXdheUNsb3NlRXZlbnRDb2RlcyIsIlVua25vd25PcGNvZGUiLCJOb3RBdXRoZW50aWNhdGVkIiwiSW52YWxpZFNlcSIsIlJhdGVMaW1pdGVkIiwiU2Vzc2lvblRpbWVkT3V0IiwiQXV0aGVudGljYXRpb25GYWlsZWQiLCJJbnZhbGlkU2hhcmQiLCJTaGFyZGluZ1JlcXVpcmVkIiwiSW52YWxpZEFwaVZlcnNpb24iLCJJbnZhbGlkSW50ZW50cyIsIkRpc2FsbG93ZWRJbnRlbnRzIiwiRXJyb3IiLCJVbmtub3duRXJyb3IiLCJEZWNvZGVFcnJvciIsIkFscmVhZHlBdXRoZW50aWNhdGVkIiwiaW5mbyIsImhhbmRsZURpc2NvcmRQYWNrZXQiLCJwYWNrZXQiLCJsYXN0QWNrIiwiRGF0ZSIsIm5vdyIsIkhlYXJ0YmVhdCIsImxhc3RCZWF0IiwiaGVhcnRiZWF0IiwiSGVsbG8iLCJoZWFydGJlYXRfaW50ZXJ2YWwiLCJzdGFydEhlYXJ0YmVhdGluZyIsImN1cnJlbnRRdWV1ZSIsInF1ZXVlIiwiaGVsbG8iLCJIZWFydGJlYXRBQ0siLCJydHQiLCJoZWFydGJlYXRBY2siLCJSZWNvbm5lY3QiLCJyZXF1ZXN0ZWRSZWNvbm5lY3QiLCJJbnZhbGlkU2Vzc2lvbiIsInJlc3VtYWJsZSIsImludmFsaWRTZXNzaW9uIiwiZGVsYXkiLCJmbG9vciIsInJhbmRvbSIsImdldCIsInQiLCJDb25uZWN0ZWQiLCJyZXN1bWVkIiwibWFwIiwicGF5bG9hZCIsInJlc3VtZV9nYXRld2F5X3VybCIsInMiLCJmb3J3YXJkVG9Cb3QiLCJjYW1lbGl6ZSIsInByZVByb2Nlc3NNZXNzYWdlIiwiZGF0YSIsIkJsb2IiLCJpbmZsYXRlU3luYyIsImFycmF5QnVmZmVyIiwicGFyc2UiLCJpbnRlcnZhbElkIiwiY2xlYXJJbnRlcnZhbCIsInRpbWVvdXRJZCIsImNsZWFyVGltZW91dCIsImppdHRlciIsInNldFRpbWVvdXQiLCJzZXRJbnRlcnZhbCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7SUFVYUEsZUFBZTtlQUFmQTs7SUFpbEJiLE9BQThCO2VBQTlCOzs7MEJBM2xCNEI7dUJBRTJCO3VCQUNGOzJEQUMzQjt3QkFFd0I7Ozs7OztBQUkzQyxJQUFBLEFBQU1BLGtCQUFOLE1BQU1BO0lBZ0NYQyxZQUFZQyxPQUEyQixDQUFFO1FBekJ6QywwSEFBMEgsUUFDMUhDLDhCQUFzQztRQUN0QywwQ0FBMEMsUUFDMUNDLHlCQUF3QztRQUN4Qyw0RUFBNEUsUUFDNUVD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
|
|
649
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TaGFyZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCdWZmZXIgfSBmcm9tICdub2RlOmJ1ZmZlcidcbmltcG9ydCB7IHR5cGUgSW5mbGF0ZSwgY3JlYXRlSW5mbGF0ZSwgaW5mbGF0ZVN5bmMsIGNvbnN0YW50cyBhcyB6bGliQ29uc3RhbnRzIH0gZnJvbSAnbm9kZTp6bGliJ1xuaW1wb3J0IHR5cGUgeyBEaXNjb3JkR2F0ZXdheVBheWxvYWQsIERpc2NvcmRIZWxsbywgRGlzY29yZFJlYWR5IH0gZnJvbSAnQGRpc2NvcmRlbm8vdHlwZXMnXG5pbXBvcnQgeyBHYXRld2F5Q2xvc2VFdmVudENvZGVzLCBHYXRld2F5T3Bjb2RlcyB9IGZyb20gJ0BkaXNjb3JkZW5vL3R5cGVzJ1xuaW1wb3J0IHsgTGVha3lCdWNrZXQsIGNhbWVsaXplLCBkZWxheSwgbG9nZ2VyIH0gZnJvbSAnQGRpc2NvcmRlbm8vdXRpbHMnXG5pbXBvcnQgdHlwZSB7IERlY29tcHJlc3MgYXMgWnN0ZERlY29tcHJlc3MgfSBmcm9tICdmenN0ZCdcbmltcG9ydCBOb2RlV2ViU29ja2V0IGZyb20gJ3dzJ1xuaW1wb3J0IHtcbiAgdHlwZSBCb3RTdGF0dXNVcGRhdGUsXG4gIHR5cGUgU2hhcmRFdmVudHMsXG4gIHR5cGUgU2hhcmRHYXRld2F5Q29uZmlnLFxuICB0eXBlIFNoYXJkSGVhcnQsXG4gIFNoYXJkU29ja2V0Q2xvc2VDb2RlcyxcbiAgdHlwZSBTaGFyZFNvY2tldFJlcXVlc3QsXG4gIFNoYXJkU3RhdGUsXG4gIFRyYW5zcG9ydENvbXByZXNzaW9uLFxufSBmcm9tICcuL3R5cGVzLmpzJ1xuXG5jb25zdCBaTElCX1NZTkNfRkxVU0ggPSBuZXcgVWludDhBcnJheShbMHgwLCAweDAsIDB4ZmYsIDB4ZmZdKVxuXG5sZXQgZnpzdGQ6IHR5cGVvZiBpbXBvcnQoJ2Z6c3RkJylcblxuLyoqIFNpbmNlIGZ6c3RkIGlzIGFuIG9wdGlvbmFsIGRlcGVuZGVuY3ksIHdlIG5lZWQgdG8gaW1wb3J0IGl0IGxhemlseSAqL1xuYXN5bmMgZnVuY3Rpb24gZ2V0RlpTdGQoKSB7XG4gIHJldHVybiAoZnpzdGQgPz89IGF3YWl0IGltcG9ydCgnZnpzdGQnKSlcbn1cblxuZXhwb3J0IGNsYXNzIERpc2NvcmRlbm9TaGFyZCB7XG4gIC8qKiBUaGUgaWQgb2YgdGhlIHNoYXJkICovXG4gIGlkOiBudW1iZXJcbiAgLyoqIFRoZSBjb25uZWN0aW9uIGNvbmZpZyBkZXRhaWxzIHRoYXQgdGhpcyBzaGFyZCB3aWxsIHVzZWQgdG8gY29ubmVjdCB0byBkaXNjb3JkLiAqL1xuICBjb25uZWN0aW9uOiBTaGFyZEdhdGV3YXlDb25maWdcbiAgLyoqIFRoaXMgY29udGFpbnMgYWxsIHRoZSBoZWFydGJlYXQgaW5mb3JtYXRpb24gKi9cbiAgaGVhcnQ6IFNoYXJkSGVhcnRcbiAgLyoqIFRoZSBtYXhpbXVtIG9mIHJlcXVlc3RzIHdoaWNoIGNhbiBiZSBzZW5kIHRvIGRpc2NvcmQgcGVyIHJhdGUgbGltaXQgdGljay4gVHlwaWNhbGx5IHRoaXMgdmFsdWUgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkLiAqL1xuICBtYXhSZXF1ZXN0c1BlclJhdGVMaW1pdFRpY2s6IG51bWJlciA9IDEyMFxuICAvKiogVGhlIHByZXZpb3VzIHBheWxvYWQgc2VxdWVuY2UgbnVtYmVyLiAqL1xuICBwcmV2aW91c1NlcXVlbmNlTnVtYmVyOiBudW1iZXIgfCBudWxsID0gbnVsbFxuICAvKiogSW4gd2hpY2ggaW50ZXJ2YWwgKGluIG1pbGxpc2Vjb25kcykgdGhlIGdhdGV3YXkgcmVzZXRzIGl0J3MgcmF0ZSBsaW1pdC4gKi9cbiAgcmF0ZUxpbWl0UmVzZXRJbnRlcnZhbDogbnVtYmVyID0gNjAwMDBcbiAgLyoqIEN1cnJlbnQgc2Vzc2lvbiBpZCBvZiB0aGUgc2hhcmQgaWYgcHJlc2VudC4gKi9cbiAgc2Vzc2lvbklkPzogc3RyaW5nXG4gIC8qKiBUaGlzIGNvbnRhaW5zIHRoZSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0byBEaXNjb3JkLCBpZiBjdXJyZW50bHkgY29ubmVjdGVkLiAqL1xuICBzb2NrZXQ/OiBXZWJTb2NrZXRcbiAgLyoqIEN1cnJlbnQgaW50ZXJuYWwgc3RhdGUgb2YgdGhlIHRoaXMuICovXG4gIHN0YXRlID0gU2hhcmRTdGF0ZS5PZmZsaW5lXG4gIC8qKiBUaGUgdXJsIHByb3ZpZGVkIGJ5IGRpc2NvcmQgdG8gdXNlIHdoZW4gcmVzdW1pbmcgYSBjb25uZWN0aW9uIGZvciB0aGlzIHRoaXMuICovXG4gIHJlc3VtZUdhdGV3YXlVcmw6IHN0cmluZyA9ICcnXG4gIC8qKiBUaGUgc2hhcmQgcmVsYXRlZCBldmVudCBoYW5kbGVycy4gKi9cbiAgZXZlbnRzOiBTaGFyZEV2ZW50cyA9IHt9XG4gIC8qKiBDYWNoZSBmb3IgcGVuZGluZyBnYXRld2F5IHJlcXVlc3RzIHdoaWNoIHNob3VsZCBoYXZlIGJlZW4gc2VuZCB3aGlsZSB0aGUgZ2F0ZXdheSB3ZW50IG9mZmxpbmUuICovXG4gIG9mZmxpbmVTZW5kUXVldWU6ICgoKSA9PiB2b2lkKVtdID0gW11cbiAgLyoqIFJlc29sdmUgaW50ZXJuYWwgd2FpdGluZyBzdGF0ZXMuIE1hcHBlZCBieSBTZWxlY3RlZEV2ZW50cyA9PiBSZXNvbHZlRnVuY3Rpb24gKi9cbiAgcmVzb2x2ZXMgPSBuZXcgTWFwPCdSRUFEWScgfCAnUkVTVU1FRCcgfCAnSU5WQUxJRF9TRVNTSU9OJywgKHBheWxvYWQ6IERpc2NvcmRHYXRld2F5UGF5bG9hZCkgPT4gdm9pZD4oKVxuICAvKiogU2hhcmQgYnVja2V0LiBPbmx5IGFjY2VzcyB0aGlzIGlmIHlvdSBrbm93IHdoYXQgeW91IGFyZSBkb2luZy4gQnVja2V0IGZvciBoYW5kbGluZyBzaGFyZCByZXF1ZXN0IHJhdGUgbGltaXRzLiAqL1xuICBidWNrZXQ6IExlYWt5QnVja2V0XG4gIC8qKiBMb2dnZXIgZm9yIHRoZSBidWNrZXQgKi9cbiAgbG9nZ2VyOiBQaWNrPHR5cGVvZiBsb2dnZXIsICdkZWJ1ZycgfCAnaW5mbycgfCAnd2FybicgfCAnZXJyb3InIHwgJ2ZhdGFsJz5cbiAgLyoqIFRleHQgZGVjb2RlciB1c2VkIGZvciBjb21wcmVzc2VkIHBheWxvYWRzICovXG4gIHRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKClcbiAgLyoqIFpMaWIgSW5mbGF0ZSBpbnN0YW5jZSBmb3IgWkxpYi1zdHJlYW0gdHJhbnNwb3J0IHBheWxvYWRzICovXG4gIGluZmxhdGU/OiBJbmZsYXRlXG4gIC8qKiBaTGliIGluZmxhdGUgYnVmZmVyICovXG4gIGluZmxhdGVCdWZmZXI6IFVpbnQ4QXJyYXkgfCBudWxsID0gbnVsbFxuICAvKiogWlN0ZCBEZWNvbXByZXNzIGluc3RhbmNlIGZvciBaU3RkLXN0cmVhbSB0cmFuc3BvcnQgcGF5bG9hZHMgKi9cbiAgenN0ZERlY29tcHJlc3M/OiBac3RkRGVjb21wcmVzc1xuICAvKiogUXVldWUgZm9yIGNvbXByZXNzZWQgcGF5bG9hZHMgZm9yIFpzdGQgRGVjb21wcmVzcyAqL1xuICBkZWNvbXByZXNzaW9uUHJvbWlzZXNRdWV1ZTogKChkYXRhOiBEaXNjb3JkR2F0ZXdheVBheWxvYWQpID0+IHZvaWQpW10gPSBbXVxuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IFNoYXJkQ3JlYXRlT3B0aW9ucykge1xuICAgIHRoaXMuaWQgPSBvcHRpb25zLmlkXG4gICAgdGhpcy5jb25uZWN0aW9uID0gb3B0aW9ucy5jb25uZWN0aW9uXG4gICAgdGhpcy5ldmVudHMgPSBvcHRpb25zLmV2ZW50c1xuICAgIHRoaXMubG9nZ2VyID0gb3B0aW9ucy5sb2dnZXIgPz8gbG9nZ2VyXG5cbiAgICB0aGlzLmhlYXJ0ID0ge1xuICAgICAgYWNrbm93bGVkZ2VkOiBmYWxzZSxcbiAgICAgIGludGVydmFsOiA0NTAwMCxcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy5yZXF1ZXN0SWRlbnRpZnkpIHRoaXMucmVxdWVzdElkZW50aWZ5ID0gb3B0aW9ucy5yZXF1ZXN0SWRlbnRpZnlcbiAgICBpZiAob3B0aW9ucy5zaGFyZElzUmVhZHkpIHRoaXMuc2hhcmRJc1JlYWR5ID0gb3B0aW9ucy5zaGFyZElzUmVhZHlcbiAgICBpZiAob3B0aW9ucy5tYWtlUHJlc2VuY2UpIHRoaXMubWFrZVByZXNlbmNlID0gb3B0aW9ucy5tYWtlUHJlc2VuY2VcblxuICAgIHRoaXMuYnVja2V0ID0gbmV3IExlYWt5QnVja2V0KHtcbiAgICAgIG1heDogdGhpcy5jYWxjdWxhdGVTYWZlUmVxdWVzdHMoKSxcbiAgICAgIHJlZmlsbEFtb3VudDogdGhpcy5jYWxjdWxhdGVTYWZlUmVxdWVzdHMoKSxcbiAgICAgIHJlZmlsbEludGVydmFsOiA2MDAwMCxcbiAgICAgIGxvZ2dlcjogdGhpcy5sb2dnZXIsXG4gICAgfSlcbiAgfVxuXG4gIC8qKiBUaGUgZ2F0ZXdheSBjb25maWd1cmF0aW9uIHdoaWNoIGlzIHVzZWQgdG8gY29ubmVjdCB0byBEaXNjb3JkLiAqL1xuICBnZXQgZ2F0ZXdheUNvbmZpZygpOiBTaGFyZEdhdGV3YXlDb25maWcge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKiBUaGUgdXJsIHRvIGNvbm5lY3QgdG8uIEluaXRpYWxseSB0aGlzIGlzIHRoZSBkaXNjb3JkIGdhdGV3YXkgdXJsLCBhbmQgdGhlbiBpcyBzd2l0Y2hlZCB0byByZXN1bWUgZ2F0ZXdheSB1cmwgb25jZSBhIFJFQURZIGlzIHJlY2VpdmVkLiAqL1xuICBnZXQgY29ubmVjdGlvblVybCgpOiBzdHJpbmcge1xuICAgIC8vIFVzZSB8fCBhbmQgbm90ID8/IGhlcmUuID8/IHdpbGwgY2F1c2UgYSBidWcuXG4gICAgcmV0dXJuIHRoaXMucmVzdW1lR2F0ZXdheVVybCB8fCB0aGlzLmdhdGV3YXlDb25maWcudXJsXG4gIH1cblxuICAvKiogQ2FsY3VsYXRlIHRoZSBhbW91bnQgb2YgcmVxdWVzdHMgd2hpY2ggY2FuIHNhZmVseSBiZSBtYWRlIHBlciByYXRlIGxpbWl0IGludGVydmFsLCBiZWZvcmUgdGhlIGdhdGV3YXkgZ2V0cyBkaXNjb25uZWN0ZWQgZHVlIHRvIGFuIGV4Y2VlZGVkIHJhdGUgbGltaXQuICovXG4gIGNhbGN1bGF0ZVNhZmVSZXF1ZXN0cygpOiBudW1iZXIge1xuICAgIC8vICogMiBhZGRzIGV4dHJhIHNhZmV0eSBsYXllciBmb3IgZGlzY29yZHMgT1AgMSByZXF1ZXN0cyB0aGF0IHdlIG5lZWQgdG8gcmVzcG9uZCB0b1xuICAgIGNvbnN0IHNhZmVSZXF1ZXN0cyA9IHRoaXMubWF4UmVxdWVzdHNQZXJSYXRlTGltaXRUaWNrIC0gTWF0aC5jZWlsKHRoaXMucmF0ZUxpbWl0UmVzZXRJbnRlcnZhbCAvIHRoaXMuaGVhcnQuaW50ZXJ2YWwpICogMlxuXG4gICAgcmV0dXJuIHNhZmVSZXF1ZXN0cyA8IDAgPyAwIDogc2FmZVJlcXVlc3RzXG4gIH1cblxuICBhc3luYyBjaGVja09mZmxpbmUoaGlnaFByaW9yaXR5OiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHJldHVyblxuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgICAvLyBIaWdoZXIgcHJpb3JpdHkgcmVxdWVzdHMgZ2V0IGFkZGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGFycmF5LlxuICAgICAgaWYgKGhpZ2hQcmlvcml0eSkgdGhpcy5vZmZsaW5lU2VuZFF1ZXVlLnVuc2hpZnQocmVzb2x2ZSlcbiAgICAgIGVsc2UgdGhpcy5vZmZsaW5lU2VuZFF1ZXVlLnB1c2gocmVzb2x2ZSlcbiAgICB9KVxuICB9XG5cbiAgLyoqIENsb3NlIHRoZSBzb2NrZXQgY29ubmVjdGlvbiB0byBkaXNjb3JkIGlmIHByZXNlbnQuICovXG4gIGNsb3NlKGNvZGU6IG51bWJlciwgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zb2NrZXQ/LnJlYWR5U3RhdGUgIT09IE5vZGVXZWJTb2NrZXQuT1BFTikgcmV0dXJuXG5cbiAgICB0aGlzLnNvY2tldD8uY2xvc2UoY29kZSwgcmVhc29uKVxuICB9XG5cbiAgLyoqIENvbm5lY3QgdGhlIHNoYXJkIHdpdGggdGhlIGdhdGV3YXkgYW5kIHN0YXJ0IGhlYXJ0YmVhdGluZy4gVGhpcyB3aWxsIG5vdCBpZGVudGlmeSB0aGUgc2hhcmQgdG8gdGhlIGdhdGV3YXkuICovXG4gIGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTxEaXNjb3JkZW5vU2hhcmQ+IHtcbiAgICAvLyBPbmx5IHNldCB0aGUgc2hhcmQgdG8gYENvbm5lY3RpbmdgIHN0YXRlLFxuICAgIC8vIGlmIHRoZSBjb25uZWN0aW9uIHJlcXVlc3QgZG9lcyBub3QgY29tZSBmcm9tIGFuIGlkZW50aWZ5IG9yIHJlc3VtZSBhY3Rpb24uXG4gICAgaWYgKCFbU2hhcmRTdGF0ZS5JZGVudGlmeWluZywgU2hhcmRTdGF0ZS5SZXN1bWluZ10uaW5jbHVkZXModGhpcy5zdGF0ZSkpIHtcbiAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLkNvbm5lY3RpbmdcbiAgICB9XG5cbiAgICB0aGlzLmV2ZW50cy5jb25uZWN0aW5nPy4odGhpcylcblxuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwodGhpcy5jb25uZWN0aW9uVXJsKVxuICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KCd2JywgdGhpcy5nYXRld2F5Q29uZmlnLnZlcnNpb24udG9TdHJpbmcoKSlcbiAgICB1cmwuc2VhcmNoUGFyYW1zLnNldCgnZW5jb2RpbmcnLCAnanNvbicpXG5cbiAgICAvLyBTZXQgdGhlIGNvbXByZXNzIHVybCBwYXJhbSBhbmQgaW5pdGlhbGl6ZSB0aGUgZGVjb21wcmVzc2lvbiBjb250ZXh0c1xuICAgIGlmICh0aGlzLmdhdGV3YXlDb25maWcudHJhbnNwb3J0Q29tcHJlc3Npb24pIHtcbiAgICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KCdjb21wcmVzcycsIHRoaXMuZ2F0ZXdheUNvbmZpZy50cmFuc3BvcnRDb21wcmVzc2lvbilcblxuICAgICAgaWYgKHRoaXMuZ2F0ZXdheUNvbmZpZy50cmFuc3BvcnRDb21wcmVzc2lvbiA9PT0gVHJhbnNwb3J0Q29tcHJlc3Npb24uemxpYikge1xuICAgICAgICB0aGlzLmluZmxhdGVCdWZmZXIgPSBudWxsXG4gICAgICAgIHRoaXMuaW5mbGF0ZSA9IGNyZWF0ZUluZmxhdGUoe1xuICAgICAgICAgIGZpbmlzaEZsdXNoOiB6bGliQ29uc3RhbnRzLlpfU1lOQ19GTFVTSCxcbiAgICAgICAgICBjaHVua1NpemU6IDY0ICogMTAyNCxcbiAgICAgICAgfSlcblxuICAgICAgICB0aGlzLmluZmxhdGUub24oJ2Vycm9yJywgKGUpID0+IHtcbiAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcignVGhlIHdhcyBhbiBlcnJvciBpbiBkZWNvbXByZXNzaW5nIGEgWkxpYiBjb21wcmVzc2VkIHBheWxvYWQnLCBlKVxuICAgICAgICB9KVxuXG4gICAgICAgIHRoaXMuaW5mbGF0ZS5vbignZGF0YScsIChkYXRhKSA9PiB7XG4gICAgICAgICAgaWYgKCEoZGF0YSBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSByZXR1cm5cblxuICAgICAgICAgIGlmICh0aGlzLmluZmxhdGVCdWZmZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld0J1ZmZlciA9IG5ldyBVaW50OEFycmF5KHRoaXMuaW5mbGF0ZUJ1ZmZlci5ieXRlTGVuZ3RoICsgZGF0YS5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgbmV3QnVmZmVyLnNldCh0aGlzLmluZmxhdGVCdWZmZXIpXG4gICAgICAgICAgICBuZXdCdWZmZXIuc2V0KGRhdGEsIHRoaXMuaW5mbGF0ZUJ1ZmZlci5ieXRlTGVuZ3RoKVxuICAgICAgICAgICAgdGhpcy5pbmZsYXRlQnVmZmVyID0gbmV3QnVmZmVyXG5cbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuaW5mbGF0ZUJ1ZmZlciA9IGRhdGFcbiAgICAgICAgfSlcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuZ2F0ZXdheUNvbmZpZy50cmFuc3BvcnRDb21wcmVzc2lvbiA9PT0gVHJhbnNwb3J0Q29tcHJlc3Npb24uenN0ZCkge1xuICAgICAgICBjb25zdCBmenN0ZCA9IGF3YWl0IGdldEZaU3RkKCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLndhcm4oJ1tTaGFyZF0gXCJmenN0ZFwiIGlzIG5vdCBpbnN0YWxsZWQuIERpc2FibGVkIHRyYW5zcG9ydCBjb21wcmVzc2lvbi4nKVxuICAgICAgICAgIHVybC5zZWFyY2hQYXJhbXMuZGVsZXRlKCdjb21wcmVzcycpXG5cbiAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChmenN0ZCkge1xuICAgICAgICAgIHRoaXMuenN0ZERlY29tcHJlc3MgPSBuZXcgZnpzdGQuRGVjb21wcmVzcygoZGF0YSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZGVjb2RlZERhdGEgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShkYXRhKVxuICAgICAgICAgICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2UoZGVjb2RlZERhdGEpXG4gICAgICAgICAgICB0aGlzLmRlY29tcHJlc3Npb25Qcm9taXNlc1F1ZXVlLnNoaWZ0KCk/LihwYXJzZWREYXRhKVxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5nYXRld2F5Q29uZmlnLmNvbXByZXNzICYmIHRoaXMuZ2F0ZXdheUNvbmZpZy50cmFuc3BvcnRDb21wcmVzc2lvbikge1xuICAgICAgdGhpcy5sb2dnZXIud2FybignW1NoYXJkXSBQYXlsb2FkIGNvbXByZXNzaW9uIGhhcyBiZWVuIGRpc2FibGVkIHNpbmNlIHRyYW5zcG9ydCBjb21wcmVzc2lvbiBpcyBlbmFibGVkIGFzIHdlbGwuJylcbiAgICAgIHRoaXMuZ2F0ZXdheUNvbmZpZy5jb21wcmVzcyA9IGZhbHNlXG4gICAgfVxuXG4gICAgLy8gV2UgY2hlY2sgZm9yIGJ1aWx0LWluIFdlYlNvY2tldCBpbXBsZW1lbnRhdGlvbnMgaW4gQnVuIG9yIERlbm8sIE5vZGVKUyB2MjIgaGFzIGFuIGltcGxlbWVudGF0aW9uIHRvbyBidXQgaXQgc2VlbXMgdG8gYmUgbGVzcyBvcHRpbWl6ZWQgc28gZm9yIG5vdyBpdCBpcyBiZXR0ZXIgdG8gdXNlIHRoZSB3cyBucG0gcGFja2FnZVxuICAgIGNvbnN0IHNob3VsZFVzZUJ1aWx0aW4gPSBSZWZsZWN0LmhhcyhnbG9iYWxUaGlzLCAnV2ViU29ja2V0JykgJiYgKFJlZmxlY3QuaGFzKGdsb2JhbFRoaXMsICdCdW4nKSB8fCBSZWZsZWN0LmhhcyhnbG9iYWxUaGlzLCAnRGVubycpKVxuXG4gICAgLy8gQHRzLWV4cGVjdC1lcnJvciBOb2RlV2ViU29ja2V0IGRvZXNuJ3Qgc3VwcG9ydCBcImRpc3BhdGNoRXZlbnRcIiwgYW5kIHdoaWxlIHdlIGRvbid0IHVzZSBpdCwgaXQgaXMgcmVxdWlyZWQgb24gdGhlIFwiV2ViU29ja2V0XCIgdHlwZVxuICAgIGNvbnN0IHNvY2tldDogV2ViU29ja2V0ID0gc2hvdWxkVXNlQnVpbHRpbiA/IG5ldyBXZWJTb2NrZXQodXJsKSA6IG5ldyBOb2RlV2ViU29ja2V0KHVybClcbiAgICB0aGlzLnNvY2tldCA9IHNvY2tldFxuXG4gICAgLy8gQnkgZGVmYXVsdCBXZWJTb2NrZXQgd2lsbCBnaXZlIHVzIGEgQmxvYiwgdGhpcyBjaGFuZ2VzIGl0IHNvIHRoYXQgaXQgZ2l2ZXMgdXMgYW4gQXJyYXlCdWZmZXJcbiAgICBzb2NrZXQuYmluYXJ5VHlwZSA9ICdhcnJheWJ1ZmZlcidcblxuICAgIHNvY2tldC5vbmVycm9yID0gKGV2ZW50KSA9PiB0aGlzLmhhbmRsZUVycm9yKGV2ZW50KVxuICAgIHNvY2tldC5vbmNsb3NlID0gKGNsb3NlRXZlbnQpID0+IHRoaXMuaGFuZGxlQ2xvc2UoY2xvc2VFdmVudClcbiAgICBzb2NrZXQub25tZXNzYWdlID0gKG1lc3NhZ2VFdmVudCkgPT4gdGhpcy5oYW5kbGVNZXNzYWdlKG1lc3NhZ2VFdmVudClcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgc29ja2V0Lm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgLy8gT25seSBzZXQgdGhlIHNoYXJkIHRvIGBVbmlkZW50aWZpZWRgIHN0YXRlIGlmIHRoZSBjb25uZWN0aW9uIHJlcXVlc3QgZG9lcyBub3QgY29tZSBmcm9tIGFuIGlkZW50aWZ5IG9yIHJlc3VtZSBhY3Rpb24uXG4gICAgICAgIGlmICghW1NoYXJkU3RhdGUuSWRlbnRpZnlpbmcsIFNoYXJkU3RhdGUuUmVzdW1pbmddLmluY2x1ZGVzKHRoaXMuc3RhdGUpKSB7XG4gICAgICAgICAgdGhpcy5zdGF0ZSA9IFNoYXJkU3RhdGUuVW5pZGVudGlmaWVkXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50cy5jb25uZWN0ZWQ/Lih0aGlzKVxuXG4gICAgICAgIHJlc29sdmUodGhpcylcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqIElkZW50aWZ5IHRoZSBzaGFyZCB0byB0aGUgZ2F0ZXdheS4gSWYgbm90IGNvbm5lY3RlZCwgdGhpcyB3aWxsIGFsc28gY29ubmVjdCB0aGUgc2hhcmQgdG8gdGhlIGdhdGV3YXkuICovXG4gIGFzeW5jIGlkZW50aWZ5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIEEgbmV3IGlkZW50aWZ5IGhhcyBiZWVuIHJlcXVlc3RlZCBldmVuIHRob3VnaCB0aGVyZSBpcyBhbHJlYWR5IGEgY29ubmVjdGlvbiBvcGVuLlxuICAgIC8vIFRoZXJlZm9yZSB3ZSBuZWVkIHRvIGNsb3NlIHRoZSBvbGQgY29ubmVjdGlvbiBhbmQgaGVhcnRiZWF0aW5nIGJlZm9yZSBjcmVhdGluZyBhIG5ldyBvbmUuXG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIElkZW50aWZ5aW5nIG9wZW4gU2hhcmQgIyR7dGhpcy5pZH0sIGNsb3NpbmcgdGhlIGNvbm5lY3Rpb25gKVxuICAgICAgdGhpcy5jbG9zZShTaGFyZFNvY2tldENsb3NlQ29kZXMuUmVJZGVudGlmeWluZywgJ1JlLWlkZW50aWZ5aW5nIGNsb3N1cmUgb2Ygb2xkIGNvbm5lY3Rpb24uJylcbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlID0gU2hhcmRTdGF0ZS5JZGVudGlmeWluZ1xuICAgIHRoaXMuZXZlbnRzLmlkZW50aWZ5aW5nPy4odGhpcylcblxuICAgIC8vIEl0IGlzIHBvc3NpYmxlIHRoYXQgdGhlIHNoYXJkIGlzIGluIEhlYXJ0YmVhdGluZyBzdGF0ZSBidXQgbm90IGlkZW50aWZpZWQsXG4gICAgLy8gc28gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhbHJlYWR5IGEgZ2F0ZXdheSBjb25uZWN0aW9uIGV4aXN0aW5nLlxuICAgIC8vIElmIG5vdCB3ZSBuZWVkIHRvIGNyZWF0ZSBvbmUgYmVmb3JlIHdlIGlkZW50aWZ5LlxuICAgIGlmICghdGhpcy5pc09wZW4oKSkge1xuICAgICAgYXdhaXQgdGhpcy5jb25uZWN0KClcbiAgICB9XG5cbiAgICB0aGlzLnNlbmQoXG4gICAgICB7XG4gICAgICAgIG9wOiBHYXRld2F5T3Bjb2Rlcy5JZGVudGlmeSxcbiAgICAgICAgZDoge1xuICAgICAgICAgIHRva2VuOiBgQm90ICR7dGhpcy5nYXRld2F5Q29uZmlnLnRva2VufWAsXG4gICAgICAgICAgY29tcHJlc3M6IHRoaXMuZ2F0ZXdheUNvbmZpZy5jb21wcmVzcyxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB0aGlzLmdhdGV3YXlDb25maWcucHJvcGVydGllcyxcbiAgICAgICAgICBpbnRlbnRzOiB0aGlzLmdhdGV3YXlDb25maWcuaW50ZW50cyxcbiAgICAgICAgICBzaGFyZDogW3RoaXMuaWQsIHRoaXMuZ2F0ZXdheUNvbmZpZy50b3RhbFNoYXJkc10sXG4gICAgICAgICAgcHJlc2VuY2U6IGF3YWl0IHRoaXMubWFrZVByZXNlbmNlKCksXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdHJ1ZSxcbiAgICApXG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHRoaXMucmVzb2x2ZXMuc2V0KCdSRUFEWScsICgpID0+IHtcbiAgICAgICAgdGhpcy5ldmVudHMuaWRlbnRpZmllZD8uKHRoaXMpXG4gICAgICAgIC8vIFRlbGxzIHRoZSBtYW5hZ2VyIHRoYXQgdGhpcyBzaGFyZCBpcyByZWFkeVxuICAgICAgICB0aGlzLnNoYXJkSXNSZWFkeSgpXG4gICAgICAgIHJlc29sdmUoKVxuICAgICAgfSlcbiAgICAgIC8vIFdoZW4gaWRlbnRpZnlpbmcgdG9vIGZhc3QsIERpc2NvcmQgc2VuZHMgYW4gaW52YWxpZCBzZXNzaW9uIHBheWxvYWQuXG4gICAgICAvLyBUaGlzIGNhbiBzYWZlbHkgYmUgaWdub3JlZCB0aG91Z2ggYW5kIHRoZSBzaGFyZCBzdGFydHMgYSBuZXcgaWRlbnRpZnkgYWN0aW9uLlxuICAgICAgdGhpcy5yZXNvbHZlcy5zZXQoJ0lOVkFMSURfU0VTU0lPTicsICgpID0+IHtcbiAgICAgICAgdGhpcy5yZXNvbHZlcy5kZWxldGUoJ1JFQURZJylcbiAgICAgICAgcmVzb2x2ZSgpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICAvKiogQ2hlY2sgd2hldGhlciB0aGUgY29ubmVjdGlvbiB0byBEaXNjb3JkIGlzIGN1cnJlbnRseSBvcGVuLiAqL1xuICBpc09wZW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc29ja2V0Py5yZWFkeVN0YXRlID09PSBOb2RlV2ViU29ja2V0Lk9QRU5cbiAgfVxuXG4gIC8qKiBBdHRlbXB0IHRvIHJlc3VtZSB0aGUgcHJldmlvdXMgc2hhcmRzIHNlc3Npb24gd2l0aCB0aGUgZ2F0ZXdheS4gKi9cbiAgYXN5bmMgcmVzdW1lKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFJlc3VtaW5nIFNoYXJkICMke3RoaXMuaWR9YClcblxuICAgIC8vIEl0IGhhcyBiZWVuIHJlcXVlc3RlZCB0byByZXN1bWUgdGhlIFNoYXJkcyBzZXNzaW9uLlxuICAgIC8vIEl0J3MgcG9zc2libGUgdGhhdCB0aGUgc2hhcmQgaXMgc3RpbGwgY29ubmVjdGVkIHdpdGggRGlzY29yZCdzIGdhdGV3YXkgdGhlcmVmb3JlIHdlIG5lZWQgdG8gZm9yY2VmdWxseSBjbG9zZSBpdC5cbiAgICBpZiAodGhpcy5pc09wZW4oKSkge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtTaGFyZF0gUmVzdW1pbmcgb3BlbiBTaGFyZCAjJHt0aGlzLmlkfSwgY2xvc2luZyB0aGUgY29ubmVjdGlvbmApXG4gICAgICB0aGlzLmNsb3NlKFNoYXJkU29ja2V0Q2xvc2VDb2Rlcy5SZXN1bWVDbG9zaW5nT2xkQ29ubmVjdGlvbiwgJ1JlY29ubmVjdGluZyB0aGUgc2hhcmQsIGNsb3Npbmcgb2xkIGNvbm5lY3Rpb24uJylcbiAgICB9XG5cbiAgICAvLyBTaGFyZCBoYXMgbmV2ZXIgaWRlbnRpZmllZCwgc28gd2UgY2Fubm90IHJlc3VtZS5cbiAgICBpZiAoIXRoaXMuc2Vzc2lvbklkKSB7XG4gICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW1NoYXJkXSBUcnlpbmcgdG8gcmVzdW1lIFNoYXJkICMke3RoaXMuaWR9IHdpdGhvdXQgdGhlIHNlc3Npb24gaWQuIElkZW50aWZ5aW5nIHRoZSBzaGFyZCBpbnN0ZWFkLmApXG5cbiAgICAgIGF3YWl0IHRoaXMuaWRlbnRpZnkoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZSA9IFNoYXJkU3RhdGUuUmVzdW1pbmdcblxuICAgIC8vIEJlZm9yZSB3ZSBjYW4gcmVzdW1lLCB3ZSBuZWVkIHRvIGNyZWF0ZSBhIG5ldyBjb25uZWN0aW9uIHdpdGggRGlzY29yZCdzIGdhdGV3YXkuXG4gICAgYXdhaXQgdGhpcy5jb25uZWN0KClcblxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFJlc3VtaW5nIFNoYXJkICMke3RoaXMuaWR9IGNvbm5lY3RlZC4gU2Vzc2lvbiBpZDogJHt0aGlzLnNlc3Npb25JZH0gfCBTZXF1ZW5jZTogJHt0aGlzLnByZXZpb3VzU2VxdWVuY2VOdW1iZXJ9YClcblxuICAgIHRoaXMuc2VuZChcbiAgICAgIHtcbiAgICAgICAgb3A6IEdhdGV3YXlPcGNvZGVzLlJlc3VtZSxcbiAgICAgICAgZDoge1xuICAgICAgICAgIHRva2VuOiBgQm90ICR7dGhpcy5nYXRld2F5Q29uZmlnLnRva2VufWAsXG4gICAgICAgICAgc2Vzc2lvbl9pZDogdGhpcy5zZXNzaW9uSWQsXG4gICAgICAgICAgc2VxOiB0aGlzLnByZXZpb3VzU2VxdWVuY2VOdW1iZXIgPz8gMCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB0cnVlLFxuICAgIClcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgdGhpcy5yZXNvbHZlcy5zZXQoJ1JFU1VNRUQnLCAoKSA9PiByZXNvbHZlKCkpXG5cbiAgICAgIC8vIElmIGl0IGlzIGF0dGVtcHRlZCB0byByZXN1bWUgd2l0aCBhbiBpbnZhbGlkIHNlc3Npb24gaWQsIERpc2NvcmQgc2VuZHMgYW4gaW52YWxpZCBzZXNzaW9uIHBheWxvYWRcbiAgICAgIC8vIE5vdCBlcnJvcmluZyBoZXJlIHNpbmNlIGl0IGlzIGVhc3kgdGhhdCB0aGlzIGhhcHBlbnMsIGFsc28gaXQgd291bGQgYmUgbm90IGNhdGNoYWJsZVxuICAgICAgdGhpcy5yZXNvbHZlcy5zZXQoJ0lOVkFMSURfU0VTU0lPTicsICgpID0+IHtcbiAgICAgICAgdGhpcy5yZXNvbHZlcy5kZWxldGUoJ1JFU1VNRUQnKVxuICAgICAgICByZXNvbHZlKClcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kIGEgbWVzc2FnZSB0byBEaXNjb3JkLlxuICAgKiBAcGFyYW0gaGlnaFByaW9yaXR5IC0gV2hldGhlciB0aGlzIG1lc3NhZ2Ugc2hvdWxkIGJlIHNlbmQgYXNhcC5cbiAgICovXG4gIGFzeW5jIHNlbmQobWVzc2FnZTogU2hhcmRTb2NrZXRSZXF1ZXN0LCBoaWdoUHJpb3JpdHk6IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIEJlZm9yZSBhY3F1aXJpbmcgYSB0b2tlbiBmcm9tIHRoZSBidWNrZXQsIGNoZWNrIHdoZXRoZXIgdGhlIHNoYXJkIGlzIGN1cnJlbnRseSBvZmZsaW5lIG9yIG5vdC5cbiAgICAvLyBFbHNlIGJ1Y2tldCBhbmQgdG9rZW4gd2FpdCB0aW1lIGp1c3QgZ2V0IHdhc3RlZC5cbiAgICBhd2FpdCB0aGlzLmNoZWNrT2ZmbGluZShoaWdoUHJpb3JpdHkpXG5cbiAgICBhd2FpdCB0aGlzLmJ1Y2tldC5hY3F1aXJlKGhpZ2hQcmlvcml0eSlcblxuICAgIC8vIEl0J3MgcG9zc2libGUsIHRoYXQgdGhlIHNoYXJkIHdlbnQgb2ZmbGluZSBhZnRlciBhIHRva2VuIGhhcyBiZWVuIGFjcXVpcmVkIGZyb20gdGhlIGJ1Y2tldC5cbiAgICBhd2FpdCB0aGlzLmNoZWNrT2ZmbGluZShoaWdoUHJpb3JpdHkpXG5cbiAgICB0aGlzLnNvY2tldD8uc2VuZChKU09OLnN0cmluZ2lmeShtZXNzYWdlKSlcbiAgfVxuXG4gIC8qKiBTaHV0ZG93biB0aGUgdGhpcy4gRm9yY2VmdWxseSBkaXNjb25uZWN0IHRoZSBzaGFyZCBmcm9tIERpc2NvcmQuIFRoZSBzaGFyZCBtYXkgbm90IGF0dGVtcHQgdG8gcmVjb25uZWN0IHdpdGggRGlzY29yZC4gKi9cbiAgYXN5bmMgc2h1dGRvd24oKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jbG9zZShTaGFyZFNvY2tldENsb3NlQ29kZXMuU2h1dGRvd24sICdTaGFyZCBzaHV0dGluZyBkb3duLicpXG4gICAgdGhpcy5zdGF0ZSA9IFNoYXJkU3RhdGUuT2ZmbGluZVxuICB9XG5cbiAgLyoqIEhhbmRsZSBhIGdhdGV3YXkgY29ubmVjdGlvbiBlcnJvciAqL1xuICBoYW5kbGVFcnJvcihlcnJvcjogRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmxvZ2dlci5lcnJvcihgW1NoYXJkXSBUaGVyZSB3YXMgYW4gZXJyb3IgY29ubmVjdGluZyBTaGFyZCAjJHt0aGlzLmlkfS5gLCBlcnJvcilcbiAgfVxuXG4gIC8qKiBIYW5kbGUgYSBnYXRld2F5IGNvbm5lY3Rpb24gY2xvc2UuICovXG4gIGFzeW5jIGhhbmRsZUNsb3NlKGNsb3NlOiBDbG9zZUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zb2NrZXQgPSB1bmRlZmluZWRcbiAgICB0aGlzLnN0b3BIZWFydGJlYXRpbmcoKVxuXG4gICAgLy8gQ2xlYXIgdGhlIHpsaWIvenN0ZCBkYXRhXG4gICAgdGhpcy5pbmZsYXRlID0gdW5kZWZpbmVkXG4gICAgdGhpcy56c3RkRGVjb21wcmVzcyA9IHVuZGVmaW5lZFxuICAgIHRoaXMuaW5mbGF0ZUJ1ZmZlciA9IG51bGxcbiAgICB0aGlzLmRlY29tcHJlc3Npb25Qcm9taXNlc1F1ZXVlID0gW11cblxuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFNoYXJkICMke3RoaXMuaWR9IGNsb3NlZCB3aXRoIGNvZGUgJHtjbG9zZS5jb2RlfSR7Y2xvc2UucmVhc29uID8gYCwgYW5kIHJlYXNvbjogJHtjbG9zZS5yZWFzb259YCA6ICcnfS5gKVxuXG4gICAgc3dpdGNoIChjbG9zZS5jb2RlKSB7XG4gICAgICBjYXNlIFNoYXJkU29ja2V0Q2xvc2VDb2Rlcy5UZXN0aW5nRmluaXNoZWQ6IHtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNoYXJkU3RhdGUuT2ZmbGluZVxuICAgICAgICB0aGlzLmV2ZW50cy5kaXNjb25uZWN0ZWQ/Lih0aGlzKVxuXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuICAgICAgLy8gT24gdGhlc2UgY29kZXMgYSBtYW51YWwgc3RhcnQgd2lsbCBiZSBkb25lLlxuICAgICAgY2FzZSBTaGFyZFNvY2tldENsb3NlQ29kZXMuU2h1dGRvd246XG4gICAgICBjYXNlIFNoYXJkU29ja2V0Q2xvc2VDb2Rlcy5SZUlkZW50aWZ5aW5nOlxuICAgICAgY2FzZSBTaGFyZFNvY2tldENsb3NlQ29kZXMuUmVzaGFyZGVkOlxuICAgICAgY2FzZSBTaGFyZFNvY2tldENsb3NlQ29kZXMuUmVzdW1lQ2xvc2luZ09sZENvbm5lY3Rpb246XG4gICAgICBjYXNlIFNoYXJkU29ja2V0Q2xvc2VDb2Rlcy5ab21iaWVkQ29ubmVjdGlvbjoge1xuICAgICAgICB0aGlzLnN0YXRlID0gU2hhcmRTdGF0ZS5EaXNjb25uZWN0ZWRcbiAgICAgICAgdGhpcy5ldmVudHMuZGlzY29ubmVjdGVkPy4odGhpcylcblxuICAgICAgICByZXR1cm5cbiAgICAgIH1cbiAgICAgIC8vIFdoZW4gdGhlc2UgY29kZXMgYXJlIHJlY2VpdmVkIHNvbWV0aGluZyB3ZW50IHJlYWxseSB3cm9uZy5cbiAgICAgIC8vIE9uIHRob3NlIHdlIGNhbm5vdCBzdGFydCBhIHJlY29ubmVjdCBhdHRlbXB0LlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkF1dGhlbnRpY2F0aW9uRmFpbGVkOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRTaGFyZDpcbiAgICAgIGNhc2UgR2F0ZXdheUNsb3NlRXZlbnRDb2Rlcy5TaGFyZGluZ1JlcXVpcmVkOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRBcGlWZXJzaW9uOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRJbnRlbnRzOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkRpc2FsbG93ZWRJbnRlbnRzOiB7XG4gICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLk9mZmxpbmVcbiAgICAgICAgdGhpcy5ldmVudHMuZGlzY29ubmVjdGVkPy4odGhpcylcblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoY2xvc2UucmVhc29uIHx8ICdEaXNjb3JkIGdhdmUgbm8gcmVhc29uISBHRyEgWW91IGJyb2tlIERpc2NvcmQhJylcbiAgICAgIH1cbiAgICAgIC8vIEdhdGV3YXkgY29ubmVjdGlvbiBjbG9zZXMgd2hpY2ggcmVxdWlyZSBhIG5ldyBpZGVudGlmeS5cbiAgICAgIGNhc2UgR2F0ZXdheUNsb3NlRXZlbnRDb2Rlcy5Ob3RBdXRoZW50aWNhdGVkOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLkludmFsaWRTZXE6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuU2Vzc2lvblRpbWVkT3V0OiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFNoYXJkICMke3RoaXMuaWR9IGNsb3NlZCByZXF1aXJpbmcgcmUtaWRlbnRpZnkuYClcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNoYXJkU3RhdGUuSWRlbnRpZnlpbmdcbiAgICAgICAgdGhpcy5ldmVudHMuZGlzY29ubmVjdGVkPy4odGhpcylcblxuICAgICAgICBhd2FpdCB0aGlzLmlkZW50aWZ5KClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgICAvLyBHYXRld2F5IGNvbm5lY3Rpb24gY2xvc2VzIG9uIHdoaWNoIGEgcmVzdW1lIGlzIGFsbG93ZWQuXG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuVW5rbm93bkVycm9yOlxuICAgICAgY2FzZSBHYXRld2F5Q2xvc2VFdmVudENvZGVzLlVua25vd25PcGNvZGU6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuRGVjb2RlRXJyb3I6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuUmF0ZUxpbWl0ZWQ6XG4gICAgICBjYXNlIEdhdGV3YXlDbG9zZUV2ZW50Q29kZXMuQWxyZWFkeUF1dGhlbnRpY2F0ZWQ6XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmluZm8oYFtTaGFyZF0gU2hhcmQgIyR7dGhpcy5pZH0gY2xvc2VkIHdpdGggY29kZSAke2Nsb3NlLmNvZGV9LiBBdHRlbXB0aW5nIHRvIHJlc3VtZS4uLmApXG4gICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gZ2V0IGludG8gYW4gaW5maW5pdGUgbG9vcCB3aGVyZSB3ZSByZXN1bWUgZm9yZXZlciwgc28gaWYgd2Ugd2VyZSBhbHJlYWR5IHJlc3VtaW5nIHdlIGlkZW50aWZ5IGluc3RlYWRcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHRoaXMuc3RhdGUgPT09IFNoYXJkU3RhdGUuUmVzdW1pbmcgPyBTaGFyZFN0YXRlLklkZW50aWZ5aW5nIDogU2hhcmRTdGF0ZS5SZXN1bWluZ1xuICAgICAgICB0aGlzLmV2ZW50cy5kaXNjb25uZWN0ZWQ/Lih0aGlzKVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlID09PSBTaGFyZFN0YXRlLlJlc3VtaW5nKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5yZXN1bWUoKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IHRoaXMuaWRlbnRpZnkoKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIEhhbmRsZSBhbiBpbmNvbWluZyBnYXRld2F5IG1lc3NhZ2UuICovXG4gIGFzeW5jIGhhbmRsZU1lc3NhZ2UobWVzc2FnZTogTWVzc2FnZUV2ZW50KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gVGhlIHdzIG5wbSBwYWNrYWdlIHdpbGwgdXNlIGEgQnVmZmVyLCB3aGlsZSB0aGUgZ2xvYmFsIGJ1aWx0LWluIHdpbGwgdXNlIEFycmF5QnVmZmVyXG4gICAgY29uc3QgaXNDb21wcmVzc2VkID0gbWVzc2FnZS5kYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIgfHwgbWVzc2FnZS5kYXRhIGluc3RhbmNlb2YgQnVmZmVyXG5cbiAgICBjb25zdCBkYXRhID0gaXNDb21wcmVzc2VkID8gYXdhaXQgdGhpcy5kZWNvbXByZXNzUGFja2V0KG1lc3NhZ2UuZGF0YSkgOiAoSlNPTi5wYXJzZShtZXNzYWdlLmRhdGEpIGFzIERpc2NvcmRHYXRld2F5UGF5bG9hZClcblxuICAgIC8vIENoZWNrIGlmIHRoZSBkZWNvbXByZXNzaW9uIHdhcyBub3Qgc3VjY2Vzc2Z1bFxuICAgIGlmICghZGF0YSkgcmV0dXJuXG5cbiAgICBhd2FpdCB0aGlzLmhhbmRsZURpc2NvcmRQYWNrZXQoZGF0YSlcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvbXByZXNzIGEgemxpYi96c3RkIGNvbXByZXNzZWQgcGFja2V0XG4gICAqXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBhc3luYyBkZWNvbXByZXNzUGFja2V0KGRhdGE6IEFycmF5QnVmZmVyIHwgQnVmZmVyKTogUHJvbWlzZTxEaXNjb3JkR2F0ZXdheVBheWxvYWQgfCBudWxsPiB7XG4gICAgLy8gQSBidWZmZXIgaXMgYSBVaW50OEFycmF5IHVuZGVyIHRoZSBob29kLiBBbiBBcnJheUJ1ZmZlciBpcyBnZW5lcmljLCBzbyB3ZSBuZWVkIHRvIGNyZWF0ZSB0aGUgVWludDhBcnJheSB0aGF0IHVzZXMgdGhlIHdob2xlIEFycmF5QnVmZmVyXG4gICAgY29uc3QgY29tcHJlc3NlZERhdGE6IFVpbnQ4QXJyYXkgPSBkYXRhIGluc3RhbmNlb2YgQnVmZmVyID8gZGF0YSA6IG5ldyBVaW50OEFycmF5KGRhdGEpXG5cbiAgICBpZiAodGhpcy5nYXRld2F5Q29uZmlnLnRyYW5zcG9ydENvbXByZXNzaW9uID09PSBUcmFuc3BvcnRDb21wcmVzc2lvbi56bGliKSB7XG4gICAgICBpZiAoIXRoaXMuaW5mbGF0ZSkge1xuICAgICAgICB0aGlzLmxvZ2dlci5mYXRhbCgnW1NoYXJkXSB6bGliLXN0cmVhbSB0cmFuc3BvcnQgY29tcHJlc3Npb24gd2FzIGVuYWJsZWQgYnV0IG5vIGluc3RhbmNlIG9mIEluZmxhdGUgd2FzIGZvdW5kLicpXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG5cbiAgICAgIC8vIEFsaWFzLCB1c2VkIHRvIGF2b2lkIHNvbWUgbnVsbCBjaGVja3MgaW4gdGhlIFByb21pc2UgY29uc3RydWN0b3JcbiAgICAgIGNvbnN0IGluZmxhdGUgPSB0aGlzLmluZmxhdGVcblxuICAgICAgY29uc3Qgd3JpdGVQcm9taXNlID0gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICBpbmZsYXRlLndyaXRlKGNvbXByZXNzZWREYXRhLCAnYmluYXJ5JywgKGVycm9yKSA9PiAoZXJyb3IgPyByZWplY3QoZXJyb3IpIDogcmVzb2x2ZSgpKSlcbiAgICAgIH0pXG5cbiAgICAgIGlmICghZW5kc1dpdGhNYXJrZXIoY29tcHJlc3NlZERhdGEsIFpMSUJfU1lOQ19GTFVTSCkpIHJldHVybiBudWxsXG5cbiAgICAgIGF3YWl0IHdyaXRlUHJvbWlzZVxuXG4gICAgICBpZiAoIXRoaXMuaW5mbGF0ZUJ1ZmZlcikge1xuICAgICAgICB0aGlzLmxvZ2dlci53YXJuKCdbU2hhcmRdIFRoZSBaTGliIGluZmxhdGUgYnVmZmVyIHdhcyBjbGVhcmVkIGF0IGFuIHVuZXhwZWN0ZWQgbW9tZW50LicpXG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlY29kZWREYXRhID0gdGhpcy50ZXh0RGVjb2Rlci5kZWNvZGUodGhpcy5pbmZsYXRlQnVmZmVyKVxuICAgICAgdGhpcy5pbmZsYXRlQnVmZmVyID0gbnVsbFxuXG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShkZWNvZGVkRGF0YSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5nYXRld2F5Q29uZmlnLnRyYW5zcG9ydENvbXByZXNzaW9uID09PSBUcmFuc3BvcnRDb21wcmVzc2lvbi56c3RkKSB7XG4gICAgICBpZiAoIXRoaXMuenN0ZERlY29tcHJlc3MpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIuZmF0YWwoJ1tTaGFyZF0genN0ZC1zdHJlYW0gdHJhbnNwb3J0IGNvbXByZXNzaW9uIHdhcyBlbmFibGVkIGJ1dCBubyBpbnN0YW5jZSBvZiBEZWNvbXByZXNzIHdhcyBmb3VuZC4nKVxuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuXG4gICAgICB0aGlzLnpzdGREZWNvbXByZXNzLnB1c2goY29tcHJlc3NlZERhdGEpXG5cbiAgICAgIGNvbnN0IGRlY29tcHJlc3Npb25Qcm9taXNlID0gbmV3IFByb21pc2U8RGlzY29yZEdhdGV3YXlQYXlsb2FkPigocikgPT4gdGhpcy5kZWNvbXByZXNzaW9uUHJvbWlzZXNRdWV1ZS5wdXNoKHIpKVxuICAgICAgcmV0dXJuIGF3YWl0IGRlY29tcHJlc3Npb25Qcm9taXNlXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZ2F0ZXdheUNvbmZpZy5jb21wcmVzcykge1xuICAgICAgY29uc3QgZGVjb21wcmVzc2VkID0gaW5mbGF0ZVN5bmMoY29tcHJlc3NlZERhdGEpXG4gICAgICBjb25zdCBkZWNvZGVkRGF0YSA9IHRoaXMudGV4dERlY29kZXIuZGVjb2RlKGRlY29tcHJlc3NlZClcblxuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZGVjb2RlZERhdGEpXG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKiBIYW5kbGVzIGEgaW5jb21pbmcgZ2F0ZXdheSBwYWNrZXQuICovXG4gIGFzeW5jIGhhbmRsZURpc2NvcmRQYWNrZXQocGFja2V0OiBEaXNjb3JkR2F0ZXdheVBheWxvYWQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyBFZGdlIGNhc2Ugc3RhcnQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9kaXNjb3JkZW5vL2Rpc2NvcmRlbm8vaXNzdWVzLzIzMTFcbiAgICB0aGlzLmhlYXJ0Lmxhc3RBY2sgPSBEYXRlLm5vdygpXG4gICAgdGhpcy5oZWFydC5hY2tub3dsZWRnZWQgPSB0cnVlXG4gICAgLy8gRWRnZSBjYXNlIGVuZCFcblxuICAgIHN3aXRjaCAocGFja2V0Lm9wKSB7XG4gICAgICBjYXNlIEdhdGV3YXlPcGNvZGVzLkhlYXJ0YmVhdDoge1xuICAgICAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHJldHVyblxuXG4gICAgICAgIHRoaXMuaGVhcnQubGFzdEJlYXQgPSBEYXRlLm5vdygpXG4gICAgICAgIC8vIERpc2NvcmQgcmFuZG9tbHkgc2VuZHMgdGhpcyByZXF1aXJpbmcgYW4gaW1tZWRpYXRlIGhlYXJ0YmVhdCBiYWNrLlxuICAgICAgICAvLyBVc2luZyBhIGRpcmVjdCBzb2NrZXQuc2VuZCBjYWxsIGhlcmUgYmVjYXVzZSBoZWFydGJlYXQgcmVxdWVzdHMgYXJlIHJlc2VydmVkIGJ5IHVzLlxuICAgICAgICB0aGlzLnNvY2tldD8uc2VuZChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgICBvcDogR2F0ZXdheU9wY29kZXMuSGVhcnRiZWF0LFxuICAgICAgICAgICAgZDogdGhpcy5wcmV2aW91c1NlcXVlbmNlTnVtYmVyLFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICAgIHRoaXMuZXZlbnRzLmhlYXJ0YmVhdD8uKHRoaXMpXG5cbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgR2F0ZXdheU9wY29kZXMuSGVsbG86IHtcbiAgICAgICAgY29uc3QgaW50ZXJ2YWwgPSAocGFja2V0LmQgYXMgRGlzY29yZEhlbGxvKS5oZWFydGJlYXRfaW50ZXJ2YWxcbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtTaGFyZF0gU2hhcmQgIyR7dGhpcy5pZH0gcmVjZWl2ZWQgSGVsbG9gKVxuICAgICAgICB0aGlzLnN0YXJ0SGVhcnRiZWF0aW5nKGludGVydmFsKVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBTaGFyZFN0YXRlLlJlc3VtaW5nKSB7XG4gICAgICAgICAgY29uc3QgY3VycmVudFF1ZXVlID0gWy4uLnRoaXMuYnVja2V0LnF1ZXVlXVxuICAgICAgICAgIC8vIEhFTExPIGhhcyBiZWVuIHNlbmQgb24gYSBub24gcmVzdW1lIGFjdGlvbi5cbiAgICAgICAgICAvLyBUaGlzIG1lYW5zIHRoYXQgdGhlIHNoYXJkIHN0YXJ0cyBhIG5ldyBzZXNzaW9uLFxuICAgICAgICAgIC8vIHRoZXJlZm9yZSB0aGUgcmF0ZSBsaW1pdCBpbnRlcnZhbCBoYXMgYmVlbiByZXNldCB0b28uXG4gICAgICAgICAgdGhpcy5idWNrZXQgPSBuZXcgTGVha3lCdWNrZXQoe1xuICAgICAgICAgICAgbWF4OiB0aGlzLmNhbGN1bGF0ZVNhZmVSZXF1ZXN0cygpLFxuICAgICAgICAgICAgcmVmaWxsSW50ZXJ2YWw6IDYwMDAwLFxuICAgICAgICAgICAgcmVmaWxsQW1vdW50OiB0aGlzLmNhbGN1bGF0ZVNhZmVSZXF1ZXN0cygpLFxuICAgICAgICAgICAgbG9nZ2VyOiB0aGlzLmxvZ2dlcixcbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgLy8gUXVldWUgc2hvdWxkIG5vdCBiZSBsb3N0IG9uIGEgcmUtaWRlbnRpZnkuXG4gICAgICAgICAgdGhpcy5idWNrZXQucXVldWUudW5zaGlmdCguLi5jdXJyZW50UXVldWUpXG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50cy5oZWxsbz8uKHRoaXMpXG5cbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgR2F0ZXdheU9wY29kZXMuSGVhcnRiZWF0QUNLOiB7XG4gICAgICAgIC8vIE1hbnVhbGx5IGNhbGN1bGF0aW5nIHRoZSByb3VuZCB0cmlwIHRpbWUgZm9yIHVzZXJzIHdobyBuZWVkIGl0LlxuICAgICAgICBpZiAodGhpcy5oZWFydC5sYXN0QmVhdCkge1xuICAgICAgICAgIHRoaXMuaGVhcnQucnR0ID0gdGhpcy5oZWFydC5sYXN0QWNrIC0gdGhpcy5oZWFydC5sYXN0QmVhdFxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5ldmVudHMuaGVhcnRiZWF0QWNrPy4odGhpcylcblxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgY2FzZSBHYXRld2F5T3Bjb2Rlcy5SZWNvbm5lY3Q6IHtcbiAgICAgICAgdGhpcy5ldmVudHMucmVxdWVzdGVkUmVjb25uZWN0Py4odGhpcylcblxuICAgICAgICBhd2FpdCB0aGlzLnJlc3VtZSgpXG5cbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIGNhc2UgR2F0ZXdheU9wY29kZXMuSW52YWxpZFNlc3Npb246IHtcbiAgICAgICAgY29uc3QgcmVzdW1hYmxlID0gcGFja2V0LmQgYXMgYm9vbGVhblxuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgW1NoYXJkXSBSZWNlaXZlZCBJbnZhbGlkIFNlc3Npb24gZm9yIFNoYXJkICMke3RoaXMuaWR9IHdpdGggcmVzdW1hYmxlIGFzICR7cmVzdW1hYmxlfWApXG5cbiAgICAgICAgdGhpcy5ldmVudHMuaW52YWxpZFNlc3Npb24/Lih0aGlzLCByZXN1bWFibGUpXG5cbiAgICAgICAgLy8gV2UgbmVlZCB0byB3YWl0IGZvciBhIHJhbmRvbSBhbW91bnQgb2YgdGltZSBiZXR3ZWVuIDEgYW5kIDVcbiAgICAgICAgLy8gUmVmZXJlbmNlOiBodHRwczovL2Rpc2NvcmQuY29tL2RldmVsb3BlcnMvZG9jcy90b3BpY3MvZ2F0ZXdheSNyZXN1bWluZ1xuICAgICAgICBhd2FpdCBkZWxheShNYXRoLmZsb29yKChNYXRoLnJhbmRvbSgpICogNCArIDEpICogMTAwMCkpXG5cbiAgICAgICAgdGhpcy5yZXNvbHZlcy5nZXQoJ0lOVkFMSURfU0VTU0lPTicpPy4ocGFja2V0KVxuICAgICAgICB0aGlzLnJlc29sdmVzLmRlbGV0ZSgnSU5WQUxJRF9TRVNTSU9OJylcblxuICAgICAgICAvLyBXaGVuIHJlc3VtYWJsZSBpcyBmYWxzZSB3ZSBuZWVkIHRvIHJlLWlkZW50aWZ5XG4gICAgICAgIGlmICghcmVzdW1hYmxlKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0SWRlbnRpZnkoKVxuXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBzZXNzaW9uIGlzIGludmFsaWQgYnV0IGFwcGFyZW50bHkgaXQgaXMgcmVzdW1hYmxlXG4gICAgICAgIGF3YWl0IHRoaXMucmVzdW1lKClcblxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIHN3aXRjaCAocGFja2V0LnQpIHtcbiAgICAgIGNhc2UgJ1JFU1VNRUQnOlxuICAgICAgICB0aGlzLnN0YXRlID0gU2hhcmRTdGF0ZS5Db25uZWN0ZWRcbiAgICAgICAgdGhpcy5ldmVudHMucmVzdW1lZD8uKHRoaXMpXG5cbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtTaGFyZF0gU2hhcmQgIyR7dGhpcy5pZH0gcmVjZWl2ZWQgUkVTVU1FRGApXG5cbiAgICAgICAgLy8gQ29udGludWUgdGhlIHJlcXVlc3RzIHdoaWNoIGhhdmUgYmVlbiBxdWV1ZWQgc2luY2UgdGhlIHNoYXJkIHdlbnQgb2ZmbGluZS5cbiAgICAgICAgdGhpcy5vZmZsaW5lU2VuZFF1ZXVlLmZvckVhY2goKHJlc29sdmUpID0+IHJlc29sdmUoKSlcbiAgICAgICAgLy8gU2V0dGluZyB0aGUgbGVuZ3RoIHRvIDAgd2lsbCBkZWxldGUgdGhlIGVsZW1lbnRzIGluIGl0XG4gICAgICAgIHRoaXMub2ZmbGluZVNlbmRRdWV1ZS5sZW5ndGggPSAwXG5cbiAgICAgICAgdGhpcy5yZXNvbHZlcy5nZXQoJ1JFU1VNRUQnKT8uKHBhY2tldClcbiAgICAgICAgdGhpcy5yZXNvbHZlcy5kZWxldGUoJ1JFU1VNRUQnKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSAnUkVBRFknOiB7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBwYWNrZXQuZCBhcyBEaXNjb3JkUmVhZHlcblxuICAgICAgICAvLyBJbXBvcnRhbnQgZm9yIGZ1dHVyZSByZXN1bWVzLlxuICAgICAgICB0aGlzLnJlc3VtZUdhdGV3YXlVcmwgPSBwYXlsb2FkLnJlc3VtZV9nYXRld2F5X3VybFxuICAgICAgICB0aGlzLnNlc3Npb25JZCA9IHBheWxvYWQuc2Vzc2lvbl9pZFxuXG4gICAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLkNvbm5lY3RlZFxuXG4gICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFNoYXJkICMke3RoaXMuaWR9IHJlY2VpdmVkIFJFQURZYClcblxuICAgICAgICAvLyBDb250aW51ZSB0aGUgcmVxdWVzdHMgd2hpY2ggaGF2ZSBiZWVuIHF1ZXVlZCBzaW5jZSB0aGUgc2hhcmQgd2VudCBvZmZsaW5lLlxuICAgICAgICAvLyBJbXBvcnRhbnQgd2hlbiB0aGlzIGlzIGEgcmUtaWRlbnRpZnlcbiAgICAgICAgdGhpcy5vZmZsaW5lU2VuZFF1ZXVlLmZvckVhY2goKHJlc29sdmUpID0+IHJlc29sdmUoKSlcbiAgICAgICAgLy8gU2V0dGluZyB0aGUgbGVuZ3RoIHRvIDAgd2lsbCBkZWxldGUgdGhlIGVsZW1lbnRzIGluIGl0XG4gICAgICAgIHRoaXMub2ZmbGluZVNlbmRRdWV1ZS5sZW5ndGggPSAwXG5cbiAgICAgICAgdGhpcy5yZXNvbHZlcy5nZXQoJ1JFQURZJyk/LihwYWNrZXQpXG4gICAgICAgIHRoaXMucmVzb2x2ZXMuZGVsZXRlKCdSRUFEWScpXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVXBkYXRlIHRoZSBzZXF1ZW5jZSBudW1iZXIgaWYgaXQgaXMgcHJlc2VudFxuICAgIC8vIGBzYCBjYW4gYmUgZWl0aGVyIGBudWxsYCBvciBhIGBudW1iZXJgLlxuICAgIC8vIEluIG9yZGVyIHRvIHByZXZlbnQgdXBkYXRlIG1pc3NlcyB3aGVuIGBzYCBpcyBgMGAgd2UgY2hlY2sgYWdhaW5zdCBudWxsLlxuICAgIGlmIChwYWNrZXQucyAhPT0gbnVsbCkge1xuICAgICAgdGhpcy5wcmV2aW91c1NlcXVlbmNlTnVtYmVyID0gcGFja2V0LnNcbiAgICB9XG5cbiAgICB0aGlzLmZvcndhcmRUb0JvdChwYWNrZXQpXG4gIH1cblxuICBmb3J3YXJkVG9Cb3QocGFja2V0OiBEaXNjb3JkR2F0ZXdheVBheWxvYWQpOiB2b2lkIHtcbiAgICAvLyBUaGUgbmVjZXNzYXJ5IGhhbmRsaW5nIHJlcXVpcmVkIGZvciB0aGUgU2hhcmRzIGNvbm5lY3Rpb24gaGFzIGJlZW4gZmluaXNoZWQuXG4gICAgLy8gTm93IHRoZSBldmVudCBjYW4gYmUgc2FmZWx5IGZvcndhcmRlZC5cbiAgICB0aGlzLmV2ZW50cy5tZXNzYWdlPy4odGhpcywgY2FtZWxpemUocGFja2V0KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkZSBpbiBvcmRlciB0byBtYWtlIHRoZSBzaGFyZHMgcHJlc2VuY2UuXG4gICAqIGFzeW5jIGluIGNhc2UgZGV2cyBjcmVhdGUgdGhlIHByZXNlbmNlIGJhc2VkIG9uIGVnLiBkYXRhYmFzZSB2YWx1ZXMuXG4gICAqIFBhc3NpbmcgdGhlIHNoYXJkJ3MgaWQgdGhlcmUgdG8gbWFrZSBpdCBlYXNpZXIgZm9yIHRoZSBkZXYgdG8gdXNlIHRoaXMgZnVuY3Rpb24uXG4gICAqL1xuICBhc3luYyBtYWtlUHJlc2VuY2UoKTogUHJvbWlzZTxCb3RTdGF0dXNVcGRhdGUgfCB1bmRlZmluZWQ+IHtcbiAgICByZXR1cm5cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGNvbW11bmljYXRlcyB3aXRoIHRoZSBtYW5hZ2VtZW50IHByb2Nlc3MsIGluIG9yZGVyIHRvIGtub3cgd2hldGhlciBpdHMgZnJlZSB0byBpZGVudGlmeS5cbiAgICogV2hlbiB0aGlzIGZ1bmN0aW9uIHJlc29sdmVzLCB0aGlzIG1lYW5zIHRoYXQgdGhlIHNoYXJkIGlzIGFsbG93ZWQgdG8gc2VuZCBhbiBpZGVudGlmeSBwYXlsb2FkIHRvIGRpc2NvcmQuXG4gICAqL1xuICBhc3luYyByZXF1ZXN0SWRlbnRpZnkoKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBUaGlzIGZ1bmN0aW9uIGNvbW11bmljYXRlcyB3aXRoIHRoZSBtYW5hZ2VtZW50IHByb2Nlc3MsIGluIG9yZGVyIHRvIHRlbGwgaXQgY2FuIGlkZW50aWZ5IHRoZSBuZXh0IHNoYXJkLiAqL1xuICBhc3luYyBzaGFyZElzUmVhZHkoKTogUHJvbWlzZTx2b2lkPiB7fVxuXG4gIC8qKiBTdGFydCBzZW5kaW5nIGhlYXJ0YmVhdCBwYXlsb2FkcyB0byBEaXNjb3JkIGluIHRoZSBwcm92aWRlZCBpbnRlcnZhbC4gKi9cbiAgc3RhcnRIZWFydGJlYXRpbmcoaW50ZXJ2YWw6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFN0YXJ0IGhlYXJ0YmVhdGluZyBvbiBTaGFyZCAjJHt0aGlzLmlkfWApXG5cbiAgICAvLyBJZiBvbGQgaGVhcnRiZWFzdCBleGlzdCBsaWtlIGFmdGVyIHJlc3VtZSwgY2xlYXIgdGhlIG9sZCBvbmVzLlxuICAgIHRoaXMuc3RvcEhlYXJ0YmVhdGluZygpXG5cbiAgICB0aGlzLmhlYXJ0LmludGVydmFsID0gaW50ZXJ2YWxcblxuICAgIC8vIE9ubHkgc2V0IHRoZSBzaGFyZCdzIHN0YXRlIHRvIGBVbmlkZW50aWZpZWRgXG4gICAgLy8gaWYgaGVhcnRiZWF0aW5nIGhhcyBub3QgYmVlbiBzdGFydGVkIGR1ZSB0byBhbiBpZGVudGlmeSBvciByZXN1bWUgYWN0aW9uLlxuICAgIGlmIChbU2hhcmRTdGF0ZS5EaXNjb25uZWN0ZWQsIFNoYXJkU3RhdGUuT2ZmbGluZV0uaW5jbHVkZXModGhpcy5zdGF0ZSkpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFNoYXJkIGlzIGRpc2Nvbm5lY3RlZCBvciBvZmZsaW5lIGJ1dCB0aGUgaGVhcnRiZWF0IHdhcyBzdGFydGVkICMke3RoaXMuaWR9YClcbiAgICAgIHRoaXMuc3RhdGUgPSBTaGFyZFN0YXRlLlVuaWRlbnRpZmllZFxuICAgIH1cblxuICAgIC8vIFRoZSBmaXJzdCBoZWFydGJlYXQgbmVlZHMgdG8gYmUgc2VuZCB3aXRoIGEgcmFuZG9tIGRlbGF5IGJldHdlZW4gYDBgIGFuZCBgaW50ZXJ2YWxgXG4gICAgLy8gVXNpbmcgYSBgc2V0VGltZW91dChfLCBqaXR0ZXIpYCBoZXJlIHRvIGFjY29tcGxpc2ggdGhhdC5cbiAgICAvLyBgTWF0aC5yYW5kb20oKWAgY2FuIGJlIGAwYCBzbyB3ZSB1c2UgYDAuNWAgaWYgdGhpcyBoYXBwZW5zXG4gICAgLy8gUmVmZXJlbmNlOiBodHRwczovL2Rpc2NvcmQuY29tL2RldmVsb3BlcnMvZG9jcy90b3BpY3MvZ2F0ZXdheSNoZWFydGJlYXRpbmdcbiAgICBjb25zdCBqaXR0ZXIgPSBNYXRoLmNlaWwodGhpcy5oZWFydC5pbnRlcnZhbCAqIChNYXRoLnJhbmRvbSgpIHx8IDAuNSkpXG5cbiAgICB0aGlzLmhlYXJ0LnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtTaGFyZF0gQmVnaW5uaW5nIGhlYXJ0YmVhdGluZyBwcm9jZXNzIGZvciBTaGFyZCAjJHt0aGlzLmlkfWApXG5cbiAgICAgIGlmICghdGhpcy5pc09wZW4oKSkgcmV0dXJuXG5cbiAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIEhlYXJ0YmVhdGluZyBvbiBTaGFyZCAjJHt0aGlzLmlkfS4gUHJldmlvdXMgc2VxdWVuY2UgbnVtYmVyOiAke3RoaXMucHJldmlvdXNTZXF1ZW5jZU51bWJlcn1gKVxuXG4gICAgICAvLyBVc2luZyBhIGRpcmVjdCBzb2NrZXQuc2VuZCBjYWxsIGhlcmUgYmVjYXVzZSBoZWFydGJlYXQgcmVxdWVzdHMgYXJlIHJlc2VydmVkIGJ5IHVzLlxuICAgICAgdGhpcy5zb2NrZXQ/LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBvcDogR2F0ZXdheU9wY29kZXMuSGVhcnRiZWF0LFxuICAgICAgICAgIGQ6IHRoaXMucHJldmlvdXNTZXF1ZW5jZU51bWJlcixcbiAgICAgICAgfSksXG4gICAgICApXG5cbiAgICAgIHRoaXMuaGVhcnQubGFzdEJlYXQgPSBEYXRlLm5vdygpXG4gICAgICB0aGlzLmhlYXJ0LmFja25vd2xlZGdlZCA9IGZhbHNlXG5cbiAgICAgIC8vIEFmdGVyIHRoZSByYW5kb20gaGVhcnRiZWF0IGppdHRlciB3ZSBjYW4gc3RhcnQgYSBub3JtYWwgaW50ZXJ2YWwuXG4gICAgICB0aGlzLmhlYXJ0LmludGVydmFsSWQgPSBzZXRJbnRlcnZhbChhc3luYyAoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5pc09wZW4oKSkge1xuICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKGBbU2hhcmRdIFNoYXJkICMke3RoaXMuaWR9IGlzIG5vdCBvcGVuLCBidXQgYXR0ZW1wdGVkIGhlYXJ0YmVhdCwgaWdub3JpbmcuYClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRoZSBTaGFyZCBkaWQgbm90IHJlY2VpdmUgYSBoZWFydGJlYXQgQUNLIGZyb20gRGlzY29yZCBpbiB0aW1lLFxuICAgICAgICAvLyB0aGVyZWZvcmUgd2UgaGF2ZSB0byBhc3N1bWUgdGhhdCB0aGUgY29ubmVjdGlvbiBoYXMgZmFpbGVkIG9yIGdvdCBcInpvbWJpZWRcIi5cbiAgICAgICAgLy8gVGhlIFNoYXJkIG5lZWRzIHRvIHN0YXJ0IGEgcmUtaWRlbnRpZnkgYWN0aW9uIGFjY29yZGluZ2x5LlxuICAgICAgICAvLyBSZWZlcmVuY2U6IGh0dHBzOi8vZGlzY29yZC5jb20vZGV2ZWxvcGVycy9kb2NzL3RvcGljcy9nYXRld2F5I2hlYXJ0YmVhdGluZy1leGFtcGxlLWdhdGV3YXktaGVhcnRiZWF0LWFja1xuICAgICAgICBpZiAoIXRoaXMuaGVhcnQuYWNrbm93bGVkZ2VkKSB7XG4gICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtTaGFyZF0gSGVhcnRiZWF0IG5vdCBhY2tub3dsZWRnZWQgZm9yIFNoYXJkICMke3RoaXMuaWR9LiBBc3N1bWluZyB6b21iaWVkIGNvbm5lY3Rpb24uYClcbiAgICAgICAgICB0aGlzLmNsb3NlKFNoYXJkU29ja2V0Q2xvc2VDb2Rlcy5ab21iaWVkQ29ubmVjdGlvbiwgJ1pvbWJpZWQgY29ubmVjdGlvbiwgZGlkIG5vdCByZWNlaXZlIGFuIGhlYXJ0YmVhdCBBQ0sgaW4gdGltZS4nKVxuXG4gICAgICAgICAgYXdhaXQgdGhpcy5yZXN1bWUoKVxuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYFtTaGFyZF0gSGVhcnRiZWF0aW5nIG9uIFNoYXJkICMke3RoaXMuaWR9LiBQcmV2aW91cyBzZXF1ZW5jZSBudW1iZXI6ICR7dGhpcy5wcmV2aW91c1NlcXVlbmNlTnVtYmVyfWApXG5cbiAgICAgICAgLy8gVXNpbmcgYSBkaXJlY3Qgc29ja2V0LnNlbmQgY2FsbCBoZXJlIGJlY2F1c2UgaGVhcnRiZWF0IHJlcXVlc3RzIGFyZSByZXNlcnZlZCBieSB1cy5cbiAgICAgICAgdGhpcy5zb2NrZXQ/LnNlbmQoXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgb3A6IEdhdGV3YXlPcGNvZGVzLkhlYXJ0YmVhdCxcbiAgICAgICAgICAgIGQ6IHRoaXMucHJldmlvdXNTZXF1ZW5jZU51bWJlcixcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuXG4gICAgICAgIHRoaXMuaGVhcnQubGFzdEJlYXQgPSBEYXRlLm5vdygpXG4gICAgICAgIHRoaXMuaGVhcnQuYWNrbm93bGVkZ2VkID0gZmFsc2VcblxuICAgICAgICB0aGlzLmV2ZW50cy5oZWFydGJlYXQ/Lih0aGlzKVxuICAgICAgfSwgdGhpcy5oZWFydC5pbnRlcnZhbClcbiAgICB9LCBqaXR0ZXIpXG4gIH1cblxuICAvKiogU3RvcCB0aGUgaGVhcnRiZWF0aW5nIHByb2Nlc3Mgd2l0aCBkaXNjb3JkLiAqL1xuICBzdG9wSGVhcnRiZWF0aW5nKCk6IHZvaWQge1xuICAgIC8vIENsZWFyIHRoZSByZWd1bGFyIGhlYXJ0YmVhdCBpbnRlcnZhbC5cbiAgICBjbGVhckludGVydmFsKHRoaXMuaGVhcnQuaW50ZXJ2YWxJZClcbiAgICAvLyBJdCdzIHBvc3NpYmxlIHRoYXQgdGhlIFNoYXJkIGdvdCBjbG9zZWQgYmVmb3JlIHRoZSBmaXJzdCBqaXR0ZXJlZCBoZWFydGJlYXQuXG4gICAgLy8gVG8gZ28gc2FmZSB3ZSBzaG91bGQgY2xlYXIgdGhlIHJlbGF0ZWQgdGltZW91dCB0b28uXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaGVhcnQudGltZW91dElkKVxuICB9XG59XG5cbi8qKiBDaGVjayBpZiB0aGUgYnVmZmVyIGVuZHMgd2l0aCB0aGUgbWFya2VyICovXG5mdW5jdGlvbiBlbmRzV2l0aE1hcmtlcihidWZmZXI6IFVpbnQ4QXJyYXksIG1hcmtlcjogVWludDhBcnJheSkge1xuICBpZiAoYnVmZmVyLmxlbmd0aCA8IG1hcmtlci5sZW5ndGgpIHJldHVybiBmYWxzZVxuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbWFya2VyLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKGJ1ZmZlcltidWZmZXIubGVuZ3RoIC0gbWFya2VyLmxlbmd0aCArIGldICE9PSBtYXJrZXJbaV0pIHJldHVybiBmYWxzZVxuICB9XG5cbiAgcmV0dXJuIHRydWVcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTaGFyZENyZWF0ZU9wdGlvbnMge1xuICAvKiogVGhlIHNoYXJkIGlkICovXG4gIGlkOiBudW1iZXJcbiAgLyoqIFRoZSBjb25uZWN0aW9uIGRldGFpbHMgKi9cbiAgY29ubmVjdGlvbjogU2hhcmRHYXRld2F5Q29uZmlnXG4gIC8qKiBUaGUgZXZlbnQgaGFuZGxlcnMgZm9yIGV2ZW50cyBvbiB0aGUgc2hhcmQuICovXG4gIGV2ZW50czogU2hhcmRFdmVudHNcbiAgLyoqIFRoZSBsb2dnZXIgZm9yIHRoZSBzaGFyZCAqL1xuICBsb2dnZXI/OiBQaWNrPHR5cGVvZiBsb2dnZXIsICdkZWJ1ZycgfCAnaW5mbycgfCAnd2FybicgfCAnZXJyb3InIHwgJ2ZhdGFsJz5cbiAgLyoqIFRoZSBoYW5kbGVyIHRvIHJlcXVlc3QgYSBzcGFjZSB0byBtYWtlIGFuIGlkZW50aWZ5IHJlcXVlc3QuICovXG4gIHJlcXVlc3RJZGVudGlmeT86ICgpID0+IFByb21pc2U8dm9pZD5cbiAgLyoqIFRoZSBoYW5kbGVyIHRvIGFsZXJ0IHRoZSBnYXRld2F5IG1hbmFnZXIgdGhhdCB0aGlzIHNoYXJkIGhhcyByZWNlaXZlZCBhIFJFQURZIGV2ZW50LiAqL1xuICBzaGFyZElzUmVhZHk/OiAoKSA9PiBQcm9taXNlPHZvaWQ+XG4gIC8qKiBGdW5jdGlvbiB0byBjcmVhdGUgdGhlIGJvdCBzdGF0dXMgdG8gc2VuZCBvbiBJZGVudGlmeSByZXF1ZXN0cyAqL1xuICBtYWtlUHJlc2VuY2U/OiAoKSA9PiBQcm9taXNlPEJvdFN0YXR1c1VwZGF0ZSB8IHVuZGVmaW5lZD5cbn1cblxuZXhwb3J0IGRlZmF1bHQgRGlzY29yZGVub1NoYXJkXG4iXSwibmFtZXMiOlsiRGlzY29yZGVub1NoYXJkIiwiWkxJQl9TWU5DX0ZMVVNIIiwiVWludDhBcnJheSIsImZ6c3RkIiwiZ2V0RlpTdGQiLCJjb25zdHJ1Y3RvciIsIm9wdGlvbnMiLCJtYXhSZXF1ZXN0c1BlclJhdGVMaW1pdFRpY2siLCJwcmV2aW91c1NlcXVlbmNlTnVtYmVyIiwicmF0ZUxpbWl0UmVzZXRJbnRlcnZhbCIsInN0YXRlIiwiU2hhcmRTdGF0ZSIsIk9mZmxpbmUiLCJyZXN1bWVHYXRld2F5VXJsIiwiZXZlbnRzIiwib2ZmbGluZVNlbmRRdWV1ZSIsInJlc29sdmVzIiwiTWFwIiwidGV4dERlY29kZXIiLCJUZXh0RGVjb2RlciIsImluZmxhdGVCdWZmZXIiLCJkZWNvbXByZXNzaW9uUHJvbWlzZXNRdWV1ZSIsImlkIiwiY29ubmVjdGlvbiIsImxvZ2dlciIsImhlYXJ0IiwiYWNrbm93bGVkZ2VkIiwiaW50ZXJ2YWwiLCJyZXF1ZXN0SWRlbnRpZnkiLCJzaGFyZElzUmVhZHkiLCJtYWtlUHJlc2VuY2UiLCJidWNrZXQiLCJMZWFreUJ1Y2tldCIsIm1heCIsImNhbGN1bGF0ZVNhZmVSZXF1ZXN0cyIsInJlZmlsbEFtb3VudCIsInJlZmlsbEludGVydmFsIiwiZ2F0ZXdheUNvbmZpZyIsImNvbm5lY3Rpb25VcmwiLCJ1cmwiLCJzYWZlUmVxdWVzdHMiLCJNYXRoIiwiY2VpbCIsImNoZWNrT2ZmbGluZSIsImhpZ2hQcmlvcml0eSIsImlzT3BlbiIsIlByb21pc2UiLCJyZXNvbHZlIiwidW5zaGlmdCIsInB1c2giLCJjbG9zZSIsImNvZGUiLCJyZWFzb24iLCJzb2NrZXQiLCJyZWFkeVN0YXRlIiwiTm9kZVdlYlNvY2tldCIsIk9QRU4iLCJjb25uZWN0IiwiSWRlbnRpZnlpbmciLCJSZXN1bWluZyIsImluY2x1ZGVzIiwiQ29ubmVjdGluZyIsImNvbm5lY3RpbmciLCJVUkwiLCJzZWFyY2hQYXJhbXMiLCJzZXQiLCJ2ZXJzaW9uIiwidG9TdHJpbmciLCJ0cmFuc3BvcnRDb21wcmVzc2lvbiIsIlRyYW5zcG9ydENvbXByZXNzaW9uIiwiemxpYiIsImluZmxhdGUiLCJjcmVhdGVJbmZsYXRlIiwiZmluaXNoRmx1c2giLCJ6bGliQ29uc3RhbnRzIiwiWl9TWU5DX0ZMVVNIIiwiY2h1bmtTaXplIiwib24iLCJlIiwiZXJyb3IiLCJkYXRhIiwibmV3QnVmZmVyIiwiYnl0ZUxlbmd0aCIsInpzdGQiLCJjYXRjaCIsIndhcm4iLCJkZWxldGUiLCJ6c3RkRGVjb21wcmVzcyIsIkRlY29tcHJlc3MiLCJkZWNvZGVkRGF0YSIsImRlY29kZSIsInBhcnNlZERhdGEiLCJKU09OIiwicGFyc2UiLCJzaGlmdCIsImNvbXByZXNzIiwic2hvdWxkVXNlQnVpbHRpbiIsIlJlZmxlY3QiLCJoYXMiLCJnbG9iYWxUaGlzIiwiV2ViU29ja2V0IiwiYmluYXJ5VHlwZSIsIm9uZXJyb3IiLCJldmVudCIsImhhbmRsZUVycm9yIiwib25jbG9zZSIsImNsb3NlRXZlbnQiLCJoYW5kbGVDbG9zZSIsIm9ubWVzc2FnZSIsIm1lc3NhZ2VFdmVudCIsImhhbmRsZU1lc3NhZ2UiLCJvbm9wZW4iLCJVbmlkZW50aWZpZWQiLCJjb25uZWN0ZWQiLCJpZGVudGlmeSIsImRlYnVnIiwiU2hhcmRTb2NrZXRDbG9zZUNvZGVzIiwiUmVJZGVudGlmeWluZyIsImlkZW50aWZ5aW5nIiwic2VuZCIsIm9wIiwiR2F0ZXdheU9wY29kZXMiLCJJZGVudGlmeSIsImQiLCJ0b2tlbiIsInByb3BlcnRpZXMiLCJpbnRlbnRzIiwic2hhcmQiLCJ0b3RhbFNoYXJkcyIsInByZXNlbmNlIiwiaWRlbnRpZmllZCIsInJlc3VtZSIsIlJlc3VtZUNsb3NpbmdPbGRDb25uZWN0aW9uIiwic2Vzc2lvbklkIiwiUmVzdW1lIiwic2Vzc2lvbl9pZCIsInNlcSIsIm1lc3NhZ2UiLCJhY3F1aXJlIiwic3RyaW5naWZ5Iiwic2h1dGRvd24iLCJTaHV0ZG93biIsInVuZGVmaW5lZCIsInN0b3BIZWFydGJlYXRpbmciLCJUZXN0aW5nRmluaXNoZWQiLCJkaXNjb25uZWN0ZWQiLCJSZXNoYXJkZWQiLCJab21iaWVkQ29ubmVjdGlvbiIsIkRpc2Nvbm5lY3RlZCIsIkdhdGV3YXlDbG9zZUV2ZW50Q29kZXMiLCJBdXRoZW50aWNhdGlvbkZhaWxlZCIsIkludmFsaWRTaGFyZCIsIlNoYXJkaW5nUmVxdWlyZWQiLCJJbnZhbGlkQXBpVmVyc2lvbiIsIkludmFsaWRJbnRlbnRzIiwiRGlzYWxsb3dlZEludGVudHMiLCJFcnJvciIsIk5vdEF1dGhlbnRpY2F0ZWQiLCJJbnZhbGlkU2VxIiwiU2Vzc2lvblRpbWVkT3V0IiwiVW5rbm93bkVycm9yIiwiVW5rbm93bk9wY29kZSIsIkRlY29kZUVycm9yIiwiUmF0ZUxpbWl0ZWQiLCJBbHJlYWR5QXV0aGVudGljYXRlZCIsImluZm8iLCJpc0NvbXByZXNzZWQiLCJBcnJheUJ1ZmZlciIsIkJ1ZmZlciIsImRlY29tcHJlc3NQYWNrZXQiLCJoYW5kbGVEaXNjb3JkUGFja2V0IiwiY29tcHJlc3NlZERhdGEiLCJmYXRhbCIsIndyaXRlUHJvbWlzZSIsInJlamVjdCIsIndyaXRlIiwiZW5kc1dpdGhNYXJrZXIiLCJkZWNvbXByZXNzaW9uUHJvbWlzZSIsInIiLCJkZWNvbXByZXNzZWQiLCJpbmZsYXRlU3luYyIsInBhY2tldCIsImxhc3RBY2siLCJEYXRlIiwibm93IiwiSGVhcnRiZWF0IiwibGFzdEJlYXQiLCJoZWFydGJlYXQiLCJIZWxsbyIsImhlYXJ0YmVhdF9pbnRlcnZhbCIsInN0YXJ0SGVhcnRiZWF0aW5nIiwiY3VycmVudFF1ZXVlIiwicXVldWUiLCJoZWxsbyIsIkhlYXJ0YmVhdEFDSyIsInJ0dCIsImhlYXJ0YmVhdEFjayIsIlJlY29ubmVjdCIsInJlcXVlc3RlZFJlY29ubmVjdCIsIkludmFsaWRTZXNzaW9uIiwicmVzdW1hYmxlIiwiaW52YWxpZFNlc3Npb24iLCJkZWxheSIsImZsb29yIiwicmFuZG9tIiwiZ2V0IiwidCIsIkNvbm5lY3RlZCIsInJlc3VtZWQiLCJmb3JFYWNoIiwibGVuZ3RoIiwicGF5bG9hZCIsInJlc3VtZV9nYXRld2F5X3VybCIsInMiLCJmb3J3YXJkVG9Cb3QiLCJjYW1lbGl6ZSIsImppdHRlciIsInRpbWVvdXRJZCIsInNldFRpbWVvdXQiLCJpbnRlcnZhbElkIiwic2V0SW50ZXJ2YWwiLCJjbGVhckludGVydmFsIiwiY2xlYXJUaW1lb3V0IiwiYnVmZmVyIiwibWFya2VyIiwiaSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7SUEyQmFBLGVBQWU7ZUFBZkE7O0lBd3ZCYixPQUE4QjtlQUE5Qjs7OzRCQW54QnVCOzBCQUM4RDt1QkFFOUI7dUJBQ0Y7MkRBRTNCO3dCQVVuQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFUCxNQUFNQyxrQkFBa0IsSUFBSUMsV0FBVztJQUFDO0lBQUs7SUFBSztJQUFNO0NBQUs7QUFFN0QsSUFBSUM7QUFFSix1RUFBdUUsR0FDdkUsZUFBZUM7SUFDYixPQUFRRCxVQUFVLE1BQU0sbUVBQUEsUUFBTztBQUNqQztBQUVPLElBQUEsQUFBTUgsa0JBQU4sTUFBTUE7SUEwQ1hLLFlBQVlDLE9BQTJCLENBQUU7UUFuQ3pDLDBIQUEwSCxRQUMxSEMsOEJBQXNDO1FBQ3RDLDBDQUEwQyxRQUMxQ0MseUJBQXdDO1FBQ3hDLDRFQUE0RSxRQUM1RUMseUJBQWlDO1FBS2pDLHdDQUF3QyxRQUN4Q0MsUUFBUUMsa0JBQVUsQ0FBQ0MsT0FBTztRQUMxQixpRkFBaUYsUUFDakZDLG1CQUEyQjtRQUMzQixzQ0FBc0MsUUFDdENDLFNBQXNCLENBQUM7UUFDdkIsbUdBQW1HLFFBQ25HQyxtQkFBbUMsRUFBRTtRQUNyQyxpRkFBaUYsUUFDakZDLFdBQVcsSUFBSUM7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
|