@cichol/logger 4.4.3 → 4.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,538 @@
1
+ 'use strict';
2
+
3
+ var _Symbol = require('core-js-pure/stable/symbol/index.js');
4
+ var _filterInstanceProperty = require('core-js-pure/stable/instance/filter.js');
5
+ var _mapInstanceProperty = require('core-js-pure/stable/instance/map.js');
6
+ var _trimInstanceProperty = require('core-js-pure/stable/instance/trim.js');
7
+ require('reflect-metadata');
8
+ var http$1 = require('http');
9
+ var stream = require('stream');
10
+ var Promise$1 = require('bluebird');
11
+ var lodash = require('lodash');
12
+ var morgan = require('morgan');
13
+ var winston = require('winston');
14
+ var _findInstanceProperty = require('core-js-pure/stable/instance/find.js');
15
+ var _Reflect$apply = require('core-js-pure/stable/reflect/apply.js');
16
+ var chalk = require('chalk');
17
+ var rTracer = require('cls-rtracer');
18
+ var luxon = require('luxon');
19
+ var _Map = require('core-js-pure/stable/map/index.js');
20
+ var process = require('process');
21
+ var _Symbol$for = require('core-js-pure/stable/symbol/for.js');
22
+ var _startsWithInstanceProperty = require('core-js-pure/stable/instance/starts-with.js');
23
+ var _sliceInstanceProperty = require('core-js-pure/stable/instance/slice.js');
24
+ var path = require('path');
25
+ var highlight = require('cli-highlight');
26
+ var prettyBytes = require('pretty-bytes');
27
+ var prettyMs = require('pretty-ms');
28
+ var cluster = require('cluster');
29
+ require('worker_threads');
30
+
31
+ function _interopNamespaceDefault(e) {
32
+ var n = Object.create(null);
33
+ if (e) {
34
+ Object.keys(e).forEach(function (k) {
35
+ if (k !== 'default') {
36
+ var d = Object.getOwnPropertyDescriptor(e, k);
37
+ Object.defineProperty(n, k, d.get ? d : {
38
+ enumerable: true,
39
+ get: function () { return e[k]; }
40
+ });
41
+ }
42
+ });
43
+ }
44
+ n.default = e;
45
+ return Object.freeze(n);
46
+ }
47
+
48
+ var winston__namespace = /*#__PURE__*/_interopNamespaceDefault(winston);
49
+
50
+ const LoggingLevel = {
51
+ // Critical levels. (It will crash the process)
52
+ Fatal: 0,
53
+ Error: 1,
54
+ // Warning levels. (It just report warning information, not crash the process)
55
+ Warning: 2,
56
+ // Regular level and aliases.
57
+ Notice: 3,
58
+ Info: 3,
59
+ // Maybe sensitive levels. (In general, does not useful)
60
+ Http: 4,
61
+ Query: 4,
62
+ // Loud levels.
63
+ Verbose: 5,
64
+ Debug: 5
65
+ };
66
+
67
+ // Constants.
68
+ const colorizerMap = new _Map();
69
+
70
+ // Helpers.
71
+ function createScheme(options) {
72
+ const nextIndex = colorizerMap.size;
73
+ const colorizer = chalk.bgHex(options.background).hex(options.foreground);
74
+ colorizerMap.set(nextIndex, colorizer);
75
+ return nextIndex;
76
+ }
77
+
78
+ // Color definitions.
79
+ const ColorValue = {
80
+ // Basic colors.
81
+ White: '#FFFFFF',
82
+ Gray: '#808080',
83
+ Black: '#000000',
84
+ // Specialized colors.
85
+ Critical: '#D63031',
86
+ Warning: '#FDCB6E',
87
+ Regular: '#0984E3',
88
+ Http: '#6AB04C',
89
+ Query: '#399AF3'
90
+ };
91
+ const ColorScheme = {
92
+ Critical: createScheme({
93
+ background: ColorValue.Critical,
94
+ foreground: ColorValue.Black
95
+ }),
96
+ Warning: createScheme({
97
+ background: ColorValue.Warning,
98
+ foreground: ColorValue.Black
99
+ }),
100
+ Regular: createScheme({
101
+ background: ColorValue.Regular,
102
+ foreground: ColorValue.White
103
+ }),
104
+ Http: createScheme({
105
+ background: ColorValue.Http,
106
+ foreground: ColorValue.Black
107
+ }),
108
+ Query: createScheme({
109
+ background: ColorValue.Query,
110
+ foreground: ColorValue.Black
111
+ }),
112
+ Loud: createScheme({
113
+ background: ColorValue.Black,
114
+ foreground: ColorValue.Gray
115
+ })
116
+ };
117
+ function getChalkOf(colorSet) {
118
+ return colorizerMap.get(colorSet) ?? chalk;
119
+ }
120
+
121
+ // Node.js built-in APIs.
122
+
123
+ // Constants.
124
+ const {
125
+ isTTY
126
+ } = process.stdout;
127
+ const isNotOnCLI = !isTTY;
128
+ function decorateLabel(label, scheme) {
129
+ if (isNotOnCLI) return label;
130
+ const chalk = getChalkOf(scheme);
131
+ const decoratedLabel = chalk.bold(` ${label} `);
132
+ return decoratedLabel;
133
+ }
134
+
135
+ // Type definitions.
136
+
137
+ // Constants.
138
+ const rootPath = process.cwd();
139
+ const conjunction = ` ${chalk.blue('──')} `;
140
+ const splat = _Symbol$for('splat');
141
+
142
+ // Handler metadata.
143
+ const name$8 = 'error';
144
+ const level$8 = LoggingLevel.Error;
145
+ const label$8 = decorateLabel('ERROR', ColorScheme.Critical);
146
+ function mapLocationOfErrorThrown(filename) {
147
+ let target = path.relative(rootPath, filename);
148
+ if (_startsWithInstanceProperty(target).call(target, 'node_modules')) {
149
+ target = chalk.gray(target).replace(/node_modules[\\/]([^\\/]+)(.*)/, (matches, moduleName, trailing) => `node_modules${path.sep}${chalk.bold.underline(moduleName)}${chalk.gray(trailing)}`);
150
+ } else {
151
+ target = `${chalk.gray(path.dirname(target) + path.sep)}${chalk.bold.underline(path.basename(target))}`;
152
+ }
153
+ return target;
154
+ }
155
+ function handle$1(data) {
156
+ var _context, _context2, _context3;
157
+ const {
158
+ [splat]: [error] = []
159
+ } = data;
160
+ if (!(error instanceof Error)) {
161
+ return undefined;
162
+ }
163
+ const {
164
+ name,
165
+ message,
166
+ stack: rawStack = ''
167
+ } = error;
168
+ const stack = _mapInstanceProperty(_context = _mapInstanceProperty(_context2 = _mapInstanceProperty(_context3 = _sliceInstanceProperty(rawStack).call(rawStack, name.length + message.length + 3).split('\n')).call(_context3, line => line.replace(/^\s+at /g, ''))).call(_context2, line => path.isAbsolute(line) ? `<anonymous>${conjunction}${mapLocationOfErrorThrown(line)}` : line)).call(_context, line => line.replace(/^(.+) \((.+)\)$/, (matches, contextName, rawLocation) => {
169
+ let location;
170
+ if (rawLocation === '<anonymous>') {
171
+ location = chalk.gray(rawLocation);
172
+ } else {
173
+ const [filename, line, column] = rawLocation.split(':');
174
+ if (path.isAbsolute(filename)) {
175
+ const target = mapLocationOfErrorThrown(path.relative(rootPath, filename));
176
+ const trailing = chalk.gray(`:${line}:${column}`);
177
+ location = target + trailing;
178
+ } else {
179
+ location = chalk.gray(`https://github.com/${chalk.bold.underline('nodejs')}/node/blob/${process.version}/lib/${filename}#L${line}`);
180
+ }
181
+ }
182
+ return `${contextName}${conjunction}${location}`;
183
+ })).join('\n');
184
+ const label = decorateLabel(name, ColorScheme.Critical);
185
+ const payload = `${message}\n\n${stack}\n`;
186
+ return {
187
+ label,
188
+ payload
189
+ };
190
+ }
191
+
192
+ var ErrorHandler = /*#__PURE__*/Object.freeze({
193
+ __proto__: null,
194
+ default: handle$1,
195
+ label: label$8,
196
+ level: level$8,
197
+ name: name$8
198
+ });
199
+
200
+ // Local helpers.
201
+
202
+ // Handler metadata.
203
+ const name$7 = 'fatal';
204
+ const level$7 = LoggingLevel.Fatal;
205
+ const label$7 = decorateLabel('FATAL', ColorScheme.Critical);
206
+
207
+ var FatalHandler = /*#__PURE__*/Object.freeze({
208
+ __proto__: null,
209
+ default: handle$1,
210
+ label: label$7,
211
+ level: level$7,
212
+ name: name$7
213
+ });
214
+
215
+ // Local helpers.
216
+
217
+ // Handler metadata.
218
+ const name$6 = 'warning';
219
+ const level$6 = LoggingLevel.Warning;
220
+ const label$6 = decorateLabel('WARNING', ColorScheme.Warning);
221
+ var warning = null;
222
+
223
+ var WarningHandler = /*#__PURE__*/Object.freeze({
224
+ __proto__: null,
225
+ default: warning,
226
+ label: label$6,
227
+ level: level$6,
228
+ name: name$6
229
+ });
230
+
231
+ // Local helpers.
232
+
233
+ // Handler metadata.
234
+ const name$5 = 'notice';
235
+ const level$5 = LoggingLevel.Notice;
236
+ const label$5 = decorateLabel('NOTICE', ColorScheme.Regular);
237
+ var notice = null;
238
+
239
+ var NoticeHandler = /*#__PURE__*/Object.freeze({
240
+ __proto__: null,
241
+ default: notice,
242
+ label: label$5,
243
+ level: level$5,
244
+ name: name$5
245
+ });
246
+
247
+ // Local helpers.
248
+
249
+ // Handler metadata.
250
+ const name$4 = 'info';
251
+ const level$4 = LoggingLevel.Info;
252
+ const label$4 = decorateLabel('INFO', ColorScheme.Regular);
253
+ var info = null;
254
+
255
+ var InfoHandler = /*#__PURE__*/Object.freeze({
256
+ __proto__: null,
257
+ default: info,
258
+ label: label$4,
259
+ level: level$4,
260
+ name: name$4
261
+ });
262
+
263
+ // Local helpers.
264
+
265
+ // Handler metadata.
266
+ const name$3 = 'http';
267
+ const level$3 = LoggingLevel.Http;
268
+ const label$3 = decorateLabel('HTTP', ColorScheme.Http);
269
+ var http = null;
270
+
271
+ var HttpHandler = /*#__PURE__*/Object.freeze({
272
+ __proto__: null,
273
+ default: http,
274
+ label: label$3,
275
+ level: level$3,
276
+ name: name$3
277
+ });
278
+
279
+ // Highlight.js
280
+
281
+ // Type definitions.
282
+
283
+ // Handler metadata.
284
+ const name$2 = 'query';
285
+ const level$2 = LoggingLevel.Query;
286
+ const label$2 = decorateLabel('QUERY', ColorScheme.Query);
287
+ function handle(data) {
288
+ const payload = highlight(data.message, {
289
+ language: 'sql'
290
+ });
291
+ return {
292
+ label: label$2,
293
+ payload
294
+ };
295
+ }
296
+
297
+ var QueryHandler = /*#__PURE__*/Object.freeze({
298
+ __proto__: null,
299
+ default: handle,
300
+ label: label$2,
301
+ level: level$2,
302
+ name: name$2
303
+ });
304
+
305
+ // Local helpers.
306
+
307
+ // Handler metadata.
308
+ const name$1 = 'verbose';
309
+ const level$1 = LoggingLevel.Verbose;
310
+ const label$1 = decorateLabel('VERBOSE', ColorScheme.Loud);
311
+ var verbose = null;
312
+
313
+ var VerboseHandler = /*#__PURE__*/Object.freeze({
314
+ __proto__: null,
315
+ default: verbose,
316
+ label: label$1,
317
+ level: level$1,
318
+ name: name$1
319
+ });
320
+
321
+ // Local helpers.
322
+
323
+ // Handler metadata.
324
+ const name = 'debug';
325
+ const level = LoggingLevel.Debug;
326
+ const label = decorateLabel('DEBUG', ColorScheme.Loud);
327
+ var debug = null;
328
+
329
+ var DebugHandler = /*#__PURE__*/Object.freeze({
330
+ __proto__: null,
331
+ default: debug,
332
+ label: label,
333
+ level: level,
334
+ name: name
335
+ });
336
+
337
+ // Handler implementations.
338
+ const handlers = [FatalHandler, ErrorHandler, WarningHandler, NoticeHandler, InfoHandler, HttpHandler, QueryHandler, VerboseHandler, DebugHandler];
339
+
340
+ var formatForCLI = winston.format.printf(data => {
341
+ const timestamp = chalk.gray(luxon.DateTime.now().toISO({
342
+ includeOffset: true
343
+ }));
344
+ const handler = _findInstanceProperty(handlers).call(handlers, ({
345
+ name
346
+ }) => name === data.level);
347
+ const fallback = {
348
+ label: handler?.label,
349
+ payload: data.message
350
+ };
351
+ const performHandle = handler?.default ?? (() => fallback);
352
+
353
+ // Execute handler and then, get decorated payload.
354
+ const {
355
+ label,
356
+ payload
357
+ } = _Reflect$apply(performHandle, undefined, [data]) ?? fallback;
358
+ let extraFingerprint;
359
+ if (handler?.level === LoggingLevel.Http) {
360
+ extraFingerprint = data.transactionId ? `(Transaction-ID = ${data.transactionId})` : `(Request-ID = ${rTracer.id()})`;
361
+ }
362
+ return `${label} ${timestamp}${extraFingerprint ? ` ${extraFingerprint}` : ''}\n${payload}`;
363
+ });
364
+
365
+ // Node.js built-in APIs.
366
+
367
+ // Type definitions.
368
+ const ExecutionMode = {
369
+ DevelopmentMode: 'development',
370
+ ProductionMode: 'production'
371
+ };
372
+ const ClusteringMode = {
373
+ MasterProcess: 0,
374
+ WorkerProcess: 1
375
+ };
376
+ // Exportings.
377
+ const executionMode = process.env.NODE_ENV ?? ExecutionMode.DevelopmentMode;
378
+ cluster.isPrimary ?? cluster.isMaster ? ClusteringMode.MasterProcess : ClusteringMode.WorkerProcess;
379
+
380
+ // Node.js built-in APIs.
381
+
382
+ // Type definitions.
383
+
384
+ // Helpers.
385
+ function decorateStatusCode(statusCode) {
386
+ const groupOfCode = Math.floor(Number(statusCode) / 100) * 100;
387
+ const baseMessage = `${statusCode} ${http$1.STATUS_CODES[statusCode]}`;
388
+ switch (groupOfCode) {
389
+ case 200:
390
+ {
391
+ return chalk.green(baseMessage);
392
+ }
393
+ case 300:
394
+ {
395
+ return chalk.magenta(baseMessage);
396
+ }
397
+ case 400:
398
+ case 500:
399
+ {
400
+ return chalk.red(baseMessage);
401
+ }
402
+ default:
403
+ {
404
+ return chalk.gray(baseMessage);
405
+ }
406
+ }
407
+ }
408
+ function formatForMorgan(tokens, request, response) {
409
+ function _(token, ...subArgs) {
410
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
411
+ return tokens[token](request, response, ...subArgs);
412
+ }
413
+
414
+ // Raw values.
415
+ const method = _('method');
416
+ const URL = _('url');
417
+ const httpVersion = `HTTP/${_('http-version')}`;
418
+ const statusCode = Number(_('status'));
419
+ const contentLength = Number(_('res', 'content-length') ?? -1);
420
+ const responseTime = Number(_('response-time') ?? -1);
421
+
422
+ // Decorated values.
423
+ const $method = chalk.bold(method);
424
+ const $version = chalk.rgb(98, 177, 255)(httpVersion);
425
+ const $statusCode = decorateStatusCode(statusCode);
426
+ const $contentLength = contentLength >= 0 ? prettyBytes(contentLength) : '? B';
427
+ const $responseTime = responseTime >= 0 ? prettyMs(responseTime) : '';
428
+
429
+ // Additional information.
430
+ const metadata = `(${$contentLength}, ${$responseTime})`;
431
+ return [`→ ${$method} ${URL} ${$version}`, `← ${$version} ${$statusCode} ${metadata}`].join('\n');
432
+ }
433
+ var formatForMorgan$1 = executionMode === ExecutionMode.DevelopmentMode ? formatForMorgan : morgan.combined;
434
+
435
+ var _context, _context2;
436
+
437
+ // Type definitions.
438
+
439
+ // Transports.
440
+ const {
441
+ Console: ConsoleTransport
442
+ } = winston__namespace.transports;
443
+
444
+ // Keys in order to access private properties.
445
+ const KeyOfInstance = _Symbol('@cichol/logger::classes/logger::Instance');
446
+ const KeyOfPassport = _Symbol('@cichol/logger::classes/logger::Passport');
447
+ class Logger {
448
+ #logger = winston__namespace.createLogger({
449
+ levels: _filterInstanceProperty(_context = _mapInstanceProperty(_context2 = lodash(handlers)).call(_context2, ({
450
+ name,
451
+ level
452
+ }) => [name, level])).call(_context, ([, level]) => typeof level === 'number').fromPairs().value(),
453
+ level: executionMode === ExecutionMode.ProductionMode ? 'http' : 'verbose',
454
+ transports: [new ConsoleTransport({
455
+ format: formatForCLI
456
+ })],
457
+ exitOnError: false
458
+ });
459
+ #morgan = morgan(formatForMorgan$1, {
460
+ stream: new stream.PassThrough({
461
+ objectMode: true
462
+ }).on('data', data => {
463
+ this.log('http', _trimInstanceProperty(data).call(data));
464
+ })
465
+ });
466
+ constructor(passport) {
467
+ if (passport !== KeyOfPassport) {
468
+ throw new ReferenceError('Logger class cannot be constructed in directly');
469
+ }
470
+ }
471
+ static get instance() {
472
+ if (this !== Logger) {
473
+ throw new ReferenceError('Logger class is not inheritable');
474
+ }
475
+ if (Reflect.hasOwnMetadata(KeyOfInstance, Logger)) {
476
+ return Reflect.getOwnMetadata(KeyOfInstance, Logger);
477
+ }
478
+ const instance = new Logger(KeyOfPassport);
479
+ try {
480
+ return instance;
481
+ } finally {
482
+ Reflect.defineMetadata(KeyOfInstance, instance, Logger);
483
+ }
484
+ }
485
+
486
+ /**
487
+ * Logging message with specific level.
488
+ *
489
+ * @param level
490
+ * @param message
491
+ * @param args Additional metadata.
492
+ */
493
+
494
+ /**
495
+ * Logging HTTP I/O.
496
+ *
497
+ * @param request Node.js built-in `IncomingMessage` instance from `http` module.
498
+ * @param response Node.js built-in `ServerResponse` instance from `http` module.
499
+ */
500
+
501
+ /**
502
+ * Logging errors in detail.
503
+ *
504
+ * @param error
505
+ */
506
+
507
+ log(...args) {
508
+ const logger = this.#logger;
509
+ const morgan = this.#morgan;
510
+ switch (true) {
511
+ case args.length >= 2 && args[0] instanceof http$1.IncomingMessage && args[1] instanceof http$1.ServerResponse:
512
+ {
513
+ const [request, response] = args;
514
+ return Promise$1.fromCallback(callback => morgan(request, response, callback));
515
+ }
516
+ case args.length >= 1 && args[0] instanceof Error:
517
+ {
518
+ const [error, ...data] = args;
519
+
520
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
521
+ logger.log('error', error.message, error, ...data);
522
+ return undefined;
523
+ }
524
+ default:
525
+ {
526
+ const [level, message, ...data] = args;
527
+
528
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
529
+ logger.log(level, message, ...data);
530
+ return undefined;
531
+ }
532
+ }
533
+ }
534
+ }
535
+ var logger = Logger.instance;
536
+
537
+ module.exports = logger;
538
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguY2pzIiwic291cmNlcyI6WyIuLi9zb3VyY2VzL2hlbHBlcnMvbG9nZ2luZy1sZXZlbC50cyIsIi4uL3NvdXJjZXMvaGVscGVycy9jb2xvci1zY2hlbWUudHMiLCIuLi9zb3VyY2VzL2hlbHBlcnMvbGFiZWwtZGVjb3JhdG9yLnRzIiwiLi4vc291cmNlcy9oYW5kbGVycy9lcnJvci50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvZmF0YWwudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL3dhcm5pbmcudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL25vdGljZS50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvaW5mby50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvaHR0cC50cyIsIi4uL3NvdXJjZXMvaGFuZGxlcnMvcXVlcnkudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL3ZlcmJvc2UudHMiLCIuLi9zb3VyY2VzL2hhbmRsZXJzL2RlYnVnLnRzIiwiLi4vc291cmNlcy9oYW5kbGVycy9pbmRleC50cyIsIi4uL3NvdXJjZXMvZm9ybWF0dGVycy9jb21tYW5kLWxpbmUudHMiLCIuLi9zb3VyY2VzL2hlbHBlcnMvY29uc3RhbnRzLnRzIiwiLi4vc291cmNlcy9mb3JtYXR0ZXJzL21vcmdhbi50cyIsIi4uL3NvdXJjZXMvY2xhc3Nlcy9sb2dnZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgTG9nZ2luZ0xldmVsID0ge1xuXHQvLyBDcml0aWNhbCBsZXZlbHMuIChJdCB3aWxsIGNyYXNoIHRoZSBwcm9jZXNzKVxuXHRGYXRhbDogMCxcblx0RXJyb3I6IDEsXG5cblx0Ly8gV2FybmluZyBsZXZlbHMuIChJdCBqdXN0IHJlcG9ydCB3YXJuaW5nIGluZm9ybWF0aW9uLCBub3QgY3Jhc2ggdGhlIHByb2Nlc3MpXG5cdFdhcm5pbmc6IDIsXG5cblx0Ly8gUmVndWxhciBsZXZlbCBhbmQgYWxpYXNlcy5cblx0Tm90aWNlOiAzLFxuXHRJbmZvOiAzLFxuXG5cdC8vIE1heWJlIHNlbnNpdGl2ZSBsZXZlbHMuIChJbiBnZW5lcmFsLCBkb2VzIG5vdCB1c2VmdWwpXG5cdEh0dHA6IDQsXG5cdFF1ZXJ5OiA0LFxuXG5cdC8vIExvdWQgbGV2ZWxzLlxuXHRWZXJib3NlOiA1LFxuXHREZWJ1ZzogNSxcbn0gYXMgY29uc3RcblxudHlwZSBMb2dnaW5nTGV2ZWwgPSB0eXBlb2YgTG9nZ2luZ0xldmVsW2tleW9mIHR5cGVvZiBMb2dnaW5nTGV2ZWxdXG5cbmV4cG9ydCBkZWZhdWx0IExvZ2dpbmdMZXZlbFxuIiwiLy8gVGhpcmQtcGFydHkgbW9kdWxlcy5cbmltcG9ydCBjaGFsaywgeyB0eXBlIENoYWxrSW5zdGFuY2UgfSBmcm9tICdjaGFsaydcblxuLy8gQ29uc3RhbnRzLlxuY29uc3QgY29sb3JpemVyTWFwID0gbmV3IE1hcDxudW1iZXIsIENoYWxrSW5zdGFuY2U+KClcblxuLy8gSGVscGVycy5cbmZ1bmN0aW9uIGNyZWF0ZVNjaGVtZShvcHRpb25zOiB7IGJhY2tncm91bmQ6IENvbG9yVmFsdWUsIGZvcmVncm91bmQ6IENvbG9yVmFsdWUgfSk6IG51bWJlciB7XG5cdGNvbnN0IG5leHRJbmRleCA9IGNvbG9yaXplck1hcC5zaXplXG5cdGNvbnN0IGNvbG9yaXplciA9IGNoYWxrLmJnSGV4KG9wdGlvbnMuYmFja2dyb3VuZCkuaGV4KG9wdGlvbnMuZm9yZWdyb3VuZClcblxuXHRjb2xvcml6ZXJNYXAuc2V0KG5leHRJbmRleCwgY29sb3JpemVyKVxuXG5cdHJldHVybiBuZXh0SW5kZXhcbn1cblxuLy8gQ29sb3IgZGVmaW5pdGlvbnMuXG5jb25zdCBDb2xvclZhbHVlID0ge1xuXHQvLyBCYXNpYyBjb2xvcnMuXG5cdFdoaXRlOiAnI0ZGRkZGRicsXG5cdEdyYXk6ICcjODA4MDgwJyxcblx0QmxhY2s6ICcjMDAwMDAwJyxcblxuXHQvLyBTcGVjaWFsaXplZCBjb2xvcnMuXG5cdENyaXRpY2FsOiAnI0Q2MzAzMScsXG5cdFdhcm5pbmc6ICcjRkRDQjZFJyxcblx0UmVndWxhcjogJyMwOTg0RTMnLFxuXHRIdHRwOiAnIzZBQjA0QycsXG5cdFF1ZXJ5OiAnIzM5OUFGMycsXG59IGFzIGNvbnN0XG5cbnR5cGUgQ29sb3JWYWx1ZSA9IHR5cGVvZiBDb2xvclZhbHVlW2tleW9mIHR5cGVvZiBDb2xvclZhbHVlXVxuXG5jb25zdCBDb2xvclNjaGVtZSA9IHtcblx0Q3JpdGljYWw6IGNyZWF0ZVNjaGVtZSh7XG5cdFx0YmFja2dyb3VuZDogQ29sb3JWYWx1ZS5Dcml0aWNhbCxcblx0XHRmb3JlZ3JvdW5kOiBDb2xvclZhbHVlLkJsYWNrLFxuXHR9KSxcblxuXHRXYXJuaW5nOiBjcmVhdGVTY2hlbWUoe1xuXHRcdGJhY2tncm91bmQ6IENvbG9yVmFsdWUuV2FybmluZyxcblx0XHRmb3JlZ3JvdW5kOiBDb2xvclZhbHVlLkJsYWNrLFxuXHR9KSxcblxuXHRSZWd1bGFyOiBjcmVhdGVTY2hlbWUoe1xuXHRcdGJhY2tncm91bmQ6IENvbG9yVmFsdWUuUmVndWxhcixcblx0XHRmb3JlZ3JvdW5kOiBDb2xvclZhbHVlLldoaXRlLFxuXHR9KSxcblxuXHRIdHRwOiBjcmVhdGVTY2hlbWUoe1xuXHRcdGJhY2tncm91bmQ6IENvbG9yVmFsdWUuSHR0cCxcblx0XHRmb3JlZ3JvdW5kOiBDb2xvclZhbHVlLkJsYWNrLFxuXHR9KSxcblxuXHRRdWVyeTogY3JlYXRlU2NoZW1lKHtcblx0XHRiYWNrZ3JvdW5kOiBDb2xvclZhbHVlLlF1ZXJ5LFxuXHRcdGZvcmVncm91bmQ6IENvbG9yVmFsdWUuQmxhY2ssXG5cdH0pLFxuXG5cdExvdWQ6IGNyZWF0ZVNjaGVtZSh7XG5cdFx0YmFja2dyb3VuZDogQ29sb3JWYWx1ZS5CbGFjayxcblx0XHRmb3JlZ3JvdW5kOiBDb2xvclZhbHVlLkdyYXksXG5cdH0pLFxufSBhcyBjb25zdFxuXG50eXBlIENvbG9yU2NoZW1lID0gdHlwZW9mIENvbG9yU2NoZW1lW2tleW9mIHR5cGVvZiBDb2xvclNjaGVtZV1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYWxrT2YoY29sb3JTZXQ6IENvbG9yU2NoZW1lKTogQ2hhbGtJbnN0YW5jZSB7XG5cdHJldHVybiBjb2xvcml6ZXJNYXAuZ2V0KGNvbG9yU2V0KSA/PyBjaGFsa1xufVxuXG5leHBvcnQgZGVmYXVsdCBDb2xvclNjaGVtZVxuIiwiLy8gTm9kZS5qcyBidWlsdC1pbiBBUElzLlxuaW1wb3J0IHByb2Nlc3MgZnJvbSAncHJvY2VzcydcblxuLy8gTG9jYWwgaGVscGVycy5cbmltcG9ydCBDb2xvclNjaGVtZSwgeyBnZXRDaGFsa09mIH0gZnJvbSAnLi9jb2xvci1zY2hlbWUnXG5cbi8vIENvbnN0YW50cy5cbmNvbnN0IHsgaXNUVFkgfSA9IHByb2Nlc3Muc3Rkb3V0XG5jb25zdCBpc05vdE9uQ0xJID0gIWlzVFRZXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGRlY29yYXRlTGFiZWw8VCBleHRlbmRzIHN0cmluZz4obGFiZWw6IFQsIHNjaGVtZTogQ29sb3JTY2hlbWUpOiBUIHtcblx0aWYgKGlzTm90T25DTEkpIHJldHVybiBsYWJlbFxuXG5cdGNvbnN0IGNoYWxrID0gZ2V0Q2hhbGtPZihzY2hlbWUpXG5cdGNvbnN0IGRlY29yYXRlZExhYmVsID0gY2hhbGsuYm9sZChgICR7bGFiZWx9IGApXG5cblx0cmV0dXJuIGRlY29yYXRlZExhYmVsIGFzIFRcbn1cbiIsIi8vIE5vZGUuanMgYnVpbHQtaW4gQVBJcy5cbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXG5pbXBvcnQgcHJvY2VzcywgeyB2ZXJzaW9uIH0gZnJvbSAncHJvY2VzcydcblxuLy8gVGhpcmQtcGFydHkgbW9kdWxlcy5cbmltcG9ydCBjaGFsayBmcm9tICdjaGFsaydcblxuLy8gTG9jYWwgaGVscGVycy5cbmltcG9ydCBMb2dnaW5nTGV2ZWwgZnJvbSAnLi4vaGVscGVycy9sb2dnaW5nLWxldmVsJ1xuaW1wb3J0IENvbG9yU2NoZW1lIGZyb20gJy4uL2hlbHBlcnMvY29sb3Itc2NoZW1lJ1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InXG5cbi8vIFR5cGUgZGVmaW5pdGlvbnMuXG50eXBlIExvZ2dpbmdEYXRhID0geyBsZXZlbDogc3RyaW5nLCBtZXNzYWdlOiBzdHJpbmcgfSAmIFJlY29yZDxQcm9wZXJ0eUtleSwgYW55PlxudHlwZSBIYW5kbGVkRGF0YSA9IHsgbGFiZWw6IHN0cmluZywgcGF5bG9hZDogc3RyaW5nIH1cblxuLy8gQ29uc3RhbnRzLlxuY29uc3Qgcm9vdFBhdGggPSBwcm9jZXNzLmN3ZCgpXG5jb25zdCBjb25qdW5jdGlvbiA9IGAgJHtjaGFsay5ibHVlKCfilIDilIAnKX0gYFxuY29uc3Qgc3BsYXQ6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2wuZm9yKCdzcGxhdCcpXG5cbi8vIEhhbmRsZXIgbWV0YWRhdGEuXG5leHBvcnQgY29uc3QgbmFtZSA9ICdlcnJvcidcbmV4cG9ydCBjb25zdCBsZXZlbCA9IExvZ2dpbmdMZXZlbC5FcnJvclxuZXhwb3J0IGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbCgnRVJST1InLCBDb2xvclNjaGVtZS5Dcml0aWNhbClcblxuZnVuY3Rpb24gbWFwTG9jYXRpb25PZkVycm9yVGhyb3duKGZpbGVuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRsZXQgdGFyZ2V0ID0gcGF0aC5yZWxhdGl2ZShyb290UGF0aCwgZmlsZW5hbWUpXG5cblx0aWYgKHRhcmdldC5zdGFydHNXaXRoKCdub2RlX21vZHVsZXMnKSkge1xuXHRcdHRhcmdldCA9IGNoYWxrLmdyYXkodGFyZ2V0KS5yZXBsYWNlKFxuXHRcdFx0L25vZGVfbW9kdWxlc1tcXFxcL10oW15cXFxcL10rKSguKikvLFxuXHRcdFx0KG1hdGNoZXMsIG1vZHVsZU5hbWU6IHN0cmluZywgdHJhaWxpbmc6IHN0cmluZykgPT4gYG5vZGVfbW9kdWxlcyR7cGF0aC5zZXB9JHtjaGFsay5ib2xkLnVuZGVybGluZShtb2R1bGVOYW1lKX0ke2NoYWxrLmdyYXkodHJhaWxpbmcpfWAsXG5cdFx0KVxuXHR9IGVsc2Uge1xuXHRcdHRhcmdldCA9IGAke2NoYWxrLmdyYXkocGF0aC5kaXJuYW1lKHRhcmdldCkgKyBwYXRoLnNlcCl9JHtjaGFsay5ib2xkLnVuZGVybGluZShwYXRoLmJhc2VuYW1lKHRhcmdldCkpfWBcblx0fVxuXG5cdHJldHVybiB0YXJnZXRcbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaGFuZGxlKGRhdGE6IExvZ2dpbmdEYXRhKTogSGFuZGxlZERhdGEgfCB1bmRlZmluZWQge1xuXHRjb25zdCB7IFtzcGxhdF06IFsgZXJyb3IgXSA9IFtdIH0gPSBkYXRhIGFzIGFueVxuXG5cdGlmICghKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZFxuXHR9XG5cblx0Y29uc3QgeyBuYW1lLCBtZXNzYWdlLCBzdGFjazogcmF3U3RhY2sgPSAnJyB9ID0gZXJyb3JcblxuXHRjb25zdCBzdGFjayA9IHJhd1N0YWNrXG5cdFx0LnNsaWNlKG5hbWUubGVuZ3RoICsgbWVzc2FnZS5sZW5ndGggKyAzKVxuXHRcdC5zcGxpdCgnXFxuJylcblx0XHQubWFwKGxpbmUgPT4gbGluZS5yZXBsYWNlKC9eXFxzK2F0IC9nLCAnJykpXG5cdFx0Lm1hcChsaW5lID0+IChwYXRoLmlzQWJzb2x1dGUobGluZSkgPyBgPGFub255bW91cz4ke2Nvbmp1bmN0aW9ufSR7bWFwTG9jYXRpb25PZkVycm9yVGhyb3duKGxpbmUpfWAgOiBsaW5lKSlcblx0XHQubWFwKGxpbmUgPT4gbGluZS5yZXBsYWNlKC9eKC4rKSBcXCgoLispXFwpJC8sIChtYXRjaGVzLCBjb250ZXh0TmFtZTogc3RyaW5nLCByYXdMb2NhdGlvbjogc3RyaW5nKSA9PiB7XG5cdFx0XHRsZXQgbG9jYXRpb25cblxuXHRcdFx0aWYgKHJhd0xvY2F0aW9uID09PSAnPGFub255bW91cz4nKSB7XG5cdFx0XHRcdGxvY2F0aW9uID0gY2hhbGsuZ3JheShyYXdMb2NhdGlvbilcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnN0IFsgZmlsZW5hbWUsIGxpbmUsIGNvbHVtbiBdID0gcmF3TG9jYXRpb24uc3BsaXQoJzonKVxuXG5cdFx0XHRcdGlmIChwYXRoLmlzQWJzb2x1dGUoZmlsZW5hbWUpKSB7XG5cdFx0XHRcdFx0Y29uc3QgdGFyZ2V0ID0gbWFwTG9jYXRpb25PZkVycm9yVGhyb3duKHBhdGgucmVsYXRpdmUocm9vdFBhdGgsIGZpbGVuYW1lKSlcblx0XHRcdFx0XHRjb25zdCB0cmFpbGluZyA9IGNoYWxrLmdyYXkoYDoke2xpbmV9OiR7Y29sdW1ufWApXG5cblx0XHRcdFx0XHRsb2NhdGlvbiA9IHRhcmdldCArIHRyYWlsaW5nXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bG9jYXRpb24gPSBjaGFsay5ncmF5KGBodHRwczovL2dpdGh1Yi5jb20vJHtjaGFsay5ib2xkLnVuZGVybGluZSgnbm9kZWpzJyl9L25vZGUvYmxvYi8ke3ZlcnNpb259L2xpYi8ke2ZpbGVuYW1lfSNMJHtsaW5lfWApXG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGAke2NvbnRleHROYW1lfSR7Y29uanVuY3Rpb259JHtsb2NhdGlvbn1gXG5cdFx0fSkpXG5cdFx0LmpvaW4oJ1xcbicpXG5cblx0Y29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKG5hbWUsIENvbG9yU2NoZW1lLkNyaXRpY2FsKVxuXHRjb25zdCBwYXlsb2FkID0gYCR7bWVzc2FnZX1cXG5cXG4ke3N0YWNrfVxcbmBcblxuXHRyZXR1cm4geyBsYWJlbCwgcGF5bG9hZCB9XG59XG4iLCIvLyBMb2NhbCBoZWxwZXJzLlxuaW1wb3J0IExvZ2dpbmdMZXZlbCBmcm9tICcuLi9oZWxwZXJzL2xvZ2dpbmctbGV2ZWwnXG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnXG5pbXBvcnQgZGVjb3JhdGVMYWJlbCBmcm9tICcuLi9oZWxwZXJzL2xhYmVsLWRlY29yYXRvcidcblxuLy8gSGFuZGxlciBtZXRhZGF0YS5cbmV4cG9ydCBjb25zdCBuYW1lID0gJ2ZhdGFsJ1xuZXhwb3J0IGNvbnN0IGxldmVsID0gTG9nZ2luZ0xldmVsLkZhdGFsXG5leHBvcnQgY29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKCdGQVRBTCcsIENvbG9yU2NoZW1lLkNyaXRpY2FsKVxuXG5leHBvcnQgeyBkZWZhdWx0IH0gZnJvbSAnLi9lcnJvcidcbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCdcbmltcG9ydCBDb2xvclNjaGVtZSBmcm9tICcuLi9oZWxwZXJzL2NvbG9yLXNjaGVtZSdcbmltcG9ydCBkZWNvcmF0ZUxhYmVsIGZyb20gJy4uL2hlbHBlcnMvbGFiZWwtZGVjb3JhdG9yJ1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnd2FybmluZydcbmV4cG9ydCBjb25zdCBsZXZlbCA9IExvZ2dpbmdMZXZlbC5XYXJuaW5nXG5leHBvcnQgY29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKCdXQVJOSU5HJywgQ29sb3JTY2hlbWUuV2FybmluZylcblxuZXhwb3J0IGRlZmF1bHQgbnVsbFxuIiwiLy8gTG9jYWwgaGVscGVycy5cbmltcG9ydCBMb2dnaW5nTGV2ZWwgZnJvbSAnLi4vaGVscGVycy9sb2dnaW5nLWxldmVsJ1xuaW1wb3J0IENvbG9yU2NoZW1lIGZyb20gJy4uL2hlbHBlcnMvY29sb3Itc2NoZW1lJ1xuaW1wb3J0IGRlY29yYXRlTGFiZWwgZnJvbSAnLi4vaGVscGVycy9sYWJlbC1kZWNvcmF0b3InXG5cbi8vIEhhbmRsZXIgbWV0YWRhdGEuXG5leHBvcnQgY29uc3QgbmFtZSA9ICdub3RpY2UnXG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuTm90aWNlXG5leHBvcnQgY29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKCdOT1RJQ0UnLCBDb2xvclNjaGVtZS5SZWd1bGFyKVxuXG5leHBvcnQgZGVmYXVsdCBudWxsXG4iLCIvLyBMb2NhbCBoZWxwZXJzLlxuaW1wb3J0IExvZ2dpbmdMZXZlbCBmcm9tICcuLi9oZWxwZXJzL2xvZ2dpbmctbGV2ZWwnXG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnXG5pbXBvcnQgZGVjb3JhdGVMYWJlbCBmcm9tICcuLi9oZWxwZXJzL2xhYmVsLWRlY29yYXRvcidcblxuLy8gSGFuZGxlciBtZXRhZGF0YS5cbmV4cG9ydCBjb25zdCBuYW1lID0gJ2luZm8nXG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuSW5mb1xuZXhwb3J0IGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbCgnSU5GTycsIENvbG9yU2NoZW1lLlJlZ3VsYXIpXG5cbmV4cG9ydCBkZWZhdWx0IG51bGxcbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCdcbmltcG9ydCBDb2xvclNjaGVtZSBmcm9tICcuLi9oZWxwZXJzL2NvbG9yLXNjaGVtZSdcbmltcG9ydCBkZWNvcmF0ZUxhYmVsIGZyb20gJy4uL2hlbHBlcnMvbGFiZWwtZGVjb3JhdG9yJ1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnaHR0cCdcbmV4cG9ydCBjb25zdCBsZXZlbCA9IExvZ2dpbmdMZXZlbC5IdHRwXG5leHBvcnQgY29uc3QgbGFiZWwgPSBkZWNvcmF0ZUxhYmVsKCdIVFRQJywgQ29sb3JTY2hlbWUuSHR0cClcblxuZXhwb3J0IGRlZmF1bHQgbnVsbFxuIiwiLy8gSGlnaGxpZ2h0LmpzXG5pbXBvcnQgaGlnaGxpZ2h0IGZyb20gJ2NsaS1oaWdobGlnaHQnXG5cbi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCdcbmltcG9ydCBDb2xvclNjaGVtZSBmcm9tICcuLi9oZWxwZXJzL2NvbG9yLXNjaGVtZSdcbmltcG9ydCBkZWNvcmF0ZUxhYmVsIGZyb20gJy4uL2hlbHBlcnMvbGFiZWwtZGVjb3JhdG9yJ1xuXG4vLyBUeXBlIGRlZmluaXRpb25zLlxudHlwZSBMb2dnaW5nRGF0YSA9IHsgbGV2ZWw6IHN0cmluZywgbWVzc2FnZTogc3RyaW5nIH0gJiBSZWNvcmQ8UHJvcGVydHlLZXksIGFueT5cbnR5cGUgSGFuZGxlZERhdGEgPSB7IGxhYmVsOiBzdHJpbmcsIHBheWxvYWQ6IHN0cmluZyB9XG5cbi8vIEhhbmRsZXIgbWV0YWRhdGEuXG5leHBvcnQgY29uc3QgbmFtZSA9ICdxdWVyeSdcbmV4cG9ydCBjb25zdCBsZXZlbCA9IExvZ2dpbmdMZXZlbC5RdWVyeVxuZXhwb3J0IGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbCgnUVVFUlknLCBDb2xvclNjaGVtZS5RdWVyeSlcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gaGFuZGxlKGRhdGE6IExvZ2dpbmdEYXRhKTogSGFuZGxlZERhdGEgfCB1bmRlZmluZWQge1xuXHRjb25zdCBwYXlsb2FkID0gaGlnaGxpZ2h0KGRhdGEubWVzc2FnZSwgeyBsYW5ndWFnZTogJ3NxbCcgfSlcblxuXHRyZXR1cm4geyBsYWJlbCwgcGF5bG9hZCB9XG59XG4iLCIvLyBMb2NhbCBoZWxwZXJzLlxuaW1wb3J0IExvZ2dpbmdMZXZlbCBmcm9tICcuLi9oZWxwZXJzL2xvZ2dpbmctbGV2ZWwnXG5pbXBvcnQgQ29sb3JTY2hlbWUgZnJvbSAnLi4vaGVscGVycy9jb2xvci1zY2hlbWUnXG5pbXBvcnQgZGVjb3JhdGVMYWJlbCBmcm9tICcuLi9oZWxwZXJzL2xhYmVsLWRlY29yYXRvcidcblxuLy8gSGFuZGxlciBtZXRhZGF0YS5cbmV4cG9ydCBjb25zdCBuYW1lID0gJ3ZlcmJvc2UnXG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuVmVyYm9zZVxuZXhwb3J0IGNvbnN0IGxhYmVsID0gZGVjb3JhdGVMYWJlbCgnVkVSQk9TRScsIENvbG9yU2NoZW1lLkxvdWQpXG5cbmV4cG9ydCBkZWZhdWx0IG51bGxcbiIsIi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCdcbmltcG9ydCBDb2xvclNjaGVtZSBmcm9tICcuLi9oZWxwZXJzL2NvbG9yLXNjaGVtZSdcbmltcG9ydCBkZWNvcmF0ZUxhYmVsIGZyb20gJy4uL2hlbHBlcnMvbGFiZWwtZGVjb3JhdG9yJ1xuXG4vLyBIYW5kbGVyIG1ldGFkYXRhLlxuZXhwb3J0IGNvbnN0IG5hbWUgPSAnZGVidWcnXG5leHBvcnQgY29uc3QgbGV2ZWwgPSBMb2dnaW5nTGV2ZWwuRGVidWdcbmV4cG9ydCBjb25zdCBsYWJlbCA9IGRlY29yYXRlTGFiZWwoJ0RFQlVHJywgQ29sb3JTY2hlbWUuTG91ZClcblxuZXhwb3J0IGRlZmF1bHQgbnVsbFxuIiwiLy8gSGFuZGxlciBpbXBsZW1lbnRhdGlvbnMuXG5pbXBvcnQgKiBhcyBGYXRhbEhhbmRsZXIgZnJvbSAnLi9mYXRhbCdcbmltcG9ydCAqIGFzIEVycm9ySGFuZGxlciBmcm9tICcuL2Vycm9yJ1xuaW1wb3J0ICogYXMgV2FybmluZ0hhbmRsZXIgZnJvbSAnLi93YXJuaW5nJ1xuaW1wb3J0ICogYXMgTm90aWNlSGFuZGxlciBmcm9tICcuL25vdGljZSdcbmltcG9ydCAqIGFzIEluZm9IYW5kbGVyIGZyb20gJy4vaW5mbydcbmltcG9ydCAqIGFzIEh0dHBIYW5kbGVyIGZyb20gJy4vaHR0cCdcbmltcG9ydCAqIGFzIFF1ZXJ5SGFuZGxlciBmcm9tICcuL3F1ZXJ5J1xuaW1wb3J0ICogYXMgVmVyYm9zZUhhbmRsZXIgZnJvbSAnLi92ZXJib3NlJ1xuaW1wb3J0ICogYXMgRGVidWdIYW5kbGVyIGZyb20gJy4vZGVidWcnXG5cbmNvbnN0IGhhbmRsZXJzID0gW1xuXHRGYXRhbEhhbmRsZXIsXG5cdEVycm9ySGFuZGxlcixcblx0V2FybmluZ0hhbmRsZXIsXG5cdE5vdGljZUhhbmRsZXIsXG5cdEluZm9IYW5kbGVyLFxuXHRIdHRwSGFuZGxlcixcblx0UXVlcnlIYW5kbGVyLFxuXHRWZXJib3NlSGFuZGxlcixcblx0RGVidWdIYW5kbGVyLFxuXVxuXG5leHBvcnQgdHlwZSBMb2dnaW5nTGV2ZWxOYW1lID0gKHR5cGVvZiBoYW5kbGVycyBleHRlbmRzIChpbmZlciBUKVtdID8gVCA6IG5ldmVyKVsnbmFtZSddXG5leHBvcnQgZGVmYXVsdCBoYW5kbGVyc1xuIiwiLy8gVGhpcmQtcGFydHkgbW9kdWxlcy5cbmltcG9ydCBjaGFsayBmcm9tICdjaGFsaydcbmltcG9ydCByVHJhY2VyIGZyb20gJ2Nscy1ydHJhY2VyJ1xuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICdsdXhvbidcbmltcG9ydCB7IGZvcm1hdCB9IGZyb20gJ3dpbnN0b24nXG5cbi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgTG9nZ2luZ0xldmVsIGZyb20gJy4uL2hlbHBlcnMvbG9nZ2luZy1sZXZlbCdcblxuLy8gSGFuZGxlciBpbXBsZW1lbnRhdGlvbnMuXG5pbXBvcnQgaGFuZGxlcnMgZnJvbSAnLi4vaGFuZGxlcnMnXG5cbmV4cG9ydCBkZWZhdWx0IGZvcm1hdC5wcmludGYoZGF0YSA9PiB7XG5cdGNvbnN0IHRpbWVzdGFtcCA9IGNoYWxrLmdyYXkoRGF0ZVRpbWUubm93KCkudG9JU08oeyBpbmNsdWRlT2Zmc2V0OiB0cnVlIH0pKVxuXHRjb25zdCBoYW5kbGVyID0gaGFuZGxlcnMuZmluZCgoeyBuYW1lIH0pID0+IG5hbWUgPT09IGRhdGEubGV2ZWwpXG5cdGNvbnN0IGZhbGxiYWNrID0geyBsYWJlbDogaGFuZGxlcj8ubGFiZWwsIHBheWxvYWQ6IGRhdGEubWVzc2FnZSB9XG5cdGNvbnN0IHBlcmZvcm1IYW5kbGUgPSBoYW5kbGVyPy5kZWZhdWx0ID8/ICgoKTogdHlwZW9mIGZhbGxiYWNrID0+IGZhbGxiYWNrKVxuXG5cdC8vIEV4ZWN1dGUgaGFuZGxlciBhbmQgdGhlbiwgZ2V0IGRlY29yYXRlZCBwYXlsb2FkLlxuXHRjb25zdCB7IGxhYmVsLCBwYXlsb2FkIH0gPSBSZWZsZWN0LmFwcGx5KHBlcmZvcm1IYW5kbGUsIHVuZGVmaW5lZCwgWyBkYXRhIF0pID8/IGZhbGxiYWNrXG5cblx0bGV0IGV4dHJhRmluZ2VycHJpbnQ6IHN0cmluZyB8IHVuZGVmaW5lZFxuXG5cdGlmIChoYW5kbGVyPy5sZXZlbCA9PT0gTG9nZ2luZ0xldmVsLkh0dHApIHtcblx0XHRleHRyYUZpbmdlcnByaW50ID0gZGF0YS50cmFuc2FjdGlvbklkXG5cdFx0XHQ/IGAoVHJhbnNhY3Rpb24tSUQgPSAke2RhdGEudHJhbnNhY3Rpb25JZCBhcyBzdHJpbmd9KWBcblx0XHRcdDogYChSZXF1ZXN0LUlEID0gJHtyVHJhY2VyLmlkKCkgYXMgc3RyaW5nfSlgXG5cdH1cblxuXHRyZXR1cm4gYCR7bGFiZWwgYXMgc3RyaW5nfSAke3RpbWVzdGFtcH0ke2V4dHJhRmluZ2VycHJpbnQgPyBgICR7ZXh0cmFGaW5nZXJwcmludH1gIDogJyd9XFxuJHtwYXlsb2FkIGFzIHN0cmluZ31gXG59KVxuIiwiLy8gTm9kZS5qcyBidWlsdC1pbiBBUElzLlxuaW1wb3J0IGNsdXN0ZXIgZnJvbSAnY2x1c3RlcidcbmltcG9ydCB7IGVudiBhcyBlbnZpcm9ubWVudHMgfSBmcm9tICdwcm9jZXNzJ1xuaW1wb3J0IHsgaXNNYWluVGhyZWFkIH0gZnJvbSAnd29ya2VyX3RocmVhZHMnXG5cbi8vIFR5cGUgZGVmaW5pdGlvbnMuXG5leHBvcnQgY29uc3QgRXhlY3V0aW9uTW9kZSA9IHtcblx0RGV2ZWxvcG1lbnRNb2RlOiAnZGV2ZWxvcG1lbnQnLFxuXHRQcm9kdWN0aW9uTW9kZTogJ3Byb2R1Y3Rpb24nLFxufSBhcyBjb25zdFxuXG5leHBvcnQgY29uc3QgQ2x1c3RlcmluZ01vZGUgPSB7XG5cdE1hc3RlclByb2Nlc3M6IDAsXG5cdFdvcmtlclByb2Nlc3M6IDEsXG59IGFzIGNvbnN0XG5cbmV4cG9ydCBjb25zdCBUaHJlYWRpbmdNb2RlID0ge1xuXHRNYWluVGhyZWFkOiAwLFxuXHRXb3JrZXJUaHJlYWQ6IDEsXG59IGFzIGNvbnN0XG5cbmV4cG9ydCB0eXBlIEV4ZWN1dGlvbk1vZGUgPSB0eXBlb2YgRXhlY3V0aW9uTW9kZVtrZXlvZiB0eXBlb2YgRXhlY3V0aW9uTW9kZV1cbmV4cG9ydCB0eXBlIENsdXN0ZXJpbmdNb2RlID0gdHlwZW9mIENsdXN0ZXJpbmdNb2RlW2tleW9mIHR5cGVvZiBDbHVzdGVyaW5nTW9kZV1cbmV4cG9ydCB0eXBlIFRocmVhZGluZ01vZGUgPSB0eXBlb2YgVGhyZWFkaW5nTW9kZVtrZXlvZiB0eXBlb2YgVGhyZWFkaW5nTW9kZV1cblxuLy8gRXhwb3J0aW5ncy5cbmV4cG9ydCBjb25zdCBleGVjdXRpb25Nb2RlID0gZW52aXJvbm1lbnRzLk5PREVfRU5WIGFzIEV4ZWN1dGlvbk1vZGUgPz8gRXhlY3V0aW9uTW9kZS5EZXZlbG9wbWVudE1vZGVcblxuZXhwb3J0IGNvbnN0IGNsdXN0ZXJpbmdNb2RlOiBDbHVzdGVyaW5nTW9kZSA9IGNsdXN0ZXIuaXNQcmltYXJ5ID8/IGNsdXN0ZXIuaXNNYXN0ZXJcblx0PyBDbHVzdGVyaW5nTW9kZS5NYXN0ZXJQcm9jZXNzXG5cdDogQ2x1c3RlcmluZ01vZGUuV29ya2VyUHJvY2Vzc1xuXG5leHBvcnQgY29uc3QgdGhyZWFkaW5nTW9kZTogVGhyZWFkaW5nTW9kZSA9IGlzTWFpblRocmVhZFxuXHQ/IFRocmVhZGluZ01vZGUuTWFpblRocmVhZFxuXHQ6IFRocmVhZGluZ01vZGUuV29ya2VyVGhyZWFkXG4iLCIvLyBOb2RlLmpzIGJ1aWx0LWluIEFQSXMuXG5pbXBvcnQge1xuXHRTVEFUVVNfQ09ERVMsXG5cdEluY29taW5nTWVzc2FnZSBhcyBIdHRwUmVxdWVzdCxcblx0U2VydmVyUmVzcG9uc2UgYXMgSHR0cFJlc3BvbnNlLFxufSBmcm9tICdodHRwJ1xuXG4vLyBUaGlyZC1wYXJ0eSBtb2R1bGVzLlxuaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJ1xuaW1wb3J0IG1vcmdhbiBmcm9tICdtb3JnYW4nXG5pbXBvcnQgcHJldHR5Qnl0ZXMgZnJvbSAncHJldHR5LWJ5dGVzJ1xuaW1wb3J0IHByZXR0eU1zIGZyb20gJ3ByZXR0eS1tcydcblxuLy8gTG9jYWwgaGVscGVycy5cbmltcG9ydCB7IEV4ZWN1dGlvbk1vZGUsIGV4ZWN1dGlvbk1vZGUgfSBmcm9tICcuLi9oZWxwZXJzL2NvbnN0YW50cydcblxuLy8gVHlwZSBkZWZpbml0aW9ucy5cbmRlY2xhcmUgbW9kdWxlICdtb3JnYW4nIHtcblx0Y29uc3QgY29tYmluZWQ6IG1vcmdhbi5Gb3JtYXRGblxufVxuXG5pbnRlcmZhY2UgVG9rZW5JbmRleGVyIHtcblx0W3Rva2VuTmFtZTogc3RyaW5nXTogKFxuXHRcdHJlcXVlc3Q6IEh0dHBSZXF1ZXN0LFxuXHRcdHJlc3BvbnNlOiBIdHRwUmVzcG9uc2UsXG5cdFx0Li4uYXJnczogYW55W11cblx0KSA9PiBzdHJpbmcgfCB1bmRlZmluZWRcbn1cblxuLy8gSGVscGVycy5cbmZ1bmN0aW9uIGRlY29yYXRlU3RhdHVzQ29kZShzdGF0dXNDb2RlOiBrZXlvZiB0eXBlb2YgU1RBVFVTX0NPREVTKTogc3RyaW5nIHtcblx0Y29uc3QgZ3JvdXBPZkNvZGUgPSBNYXRoLmZsb29yKE51bWJlcihzdGF0dXNDb2RlKSAvIDEwMCkgKiAxMDBcblx0Y29uc3QgYmFzZU1lc3NhZ2UgPSBgJHtzdGF0dXNDb2RlfSAke1NUQVRVU19DT0RFU1tzdGF0dXNDb2RlXSBhcyBzdHJpbmd9YFxuXG5cdHN3aXRjaCAoZ3JvdXBPZkNvZGUpIHtcblx0Y2FzZSAyMDA6IHtcblx0XHRyZXR1cm4gY2hhbGsuZ3JlZW4oYmFzZU1lc3NhZ2UpXG5cdH1cblxuXHRjYXNlIDMwMDoge1xuXHRcdHJldHVybiBjaGFsay5tYWdlbnRhKGJhc2VNZXNzYWdlKVxuXHR9XG5cdGNhc2UgNDAwOlxuXHRjYXNlIDUwMDoge1xuXHRcdHJldHVybiBjaGFsay5yZWQoYmFzZU1lc3NhZ2UpXG5cdH1cblxuXHRkZWZhdWx0OiB7XG5cdFx0cmV0dXJuIGNoYWxrLmdyYXkoYmFzZU1lc3NhZ2UpXG5cdH1cblx0fVxufVxuXG5mdW5jdGlvbiBmb3JtYXRGb3JNb3JnYW4odG9rZW5zOiBhbnksIHJlcXVlc3Q6IEh0dHBSZXF1ZXN0LCByZXNwb25zZTogSHR0cFJlc3BvbnNlKTogc3RyaW5nIHtcblx0ZnVuY3Rpb24gXyh0b2tlbjogc3RyaW5nLCAuLi5zdWJBcmdzOiBhbnlbXSk6IHN0cmluZyB8IHZvaWQge1xuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWFyZ3VtZW50XG5cdFx0cmV0dXJuICh0b2tlbnMgYXMgVG9rZW5JbmRleGVyKVt0b2tlbl0ocmVxdWVzdCwgcmVzcG9uc2UsIC4uLnN1YkFyZ3MpXG5cdH1cblxuXHQvLyBSYXcgdmFsdWVzLlxuXHRjb25zdCBtZXRob2QgPSBfKCdtZXRob2QnKVxuXHRjb25zdCBVUkwgPSBfKCd1cmwnKVxuXHRjb25zdCBodHRwVmVyc2lvbiA9IGBIVFRQLyR7XygnaHR0cC12ZXJzaW9uJykgYXMgc3RyaW5nfWBcblx0Y29uc3Qgc3RhdHVzQ29kZSA9IE51bWJlcihfKCdzdGF0dXMnKSlcblx0Y29uc3QgY29udGVudExlbmd0aCA9IE51bWJlcihfKCdyZXMnLCAnY29udGVudC1sZW5ndGgnKSA/PyAtMSlcblx0Y29uc3QgcmVzcG9uc2VUaW1lID0gTnVtYmVyKF8oJ3Jlc3BvbnNlLXRpbWUnKSA/PyAtMSlcblxuXHQvLyBEZWNvcmF0ZWQgdmFsdWVzLlxuXHRjb25zdCAkbWV0aG9kID0gY2hhbGsuYm9sZChtZXRob2QpXG5cdGNvbnN0ICR2ZXJzaW9uID0gY2hhbGsucmdiKDk4LCAxNzcsIDI1NSkoaHR0cFZlcnNpb24pXG5cdGNvbnN0ICRzdGF0dXNDb2RlID0gZGVjb3JhdGVTdGF0dXNDb2RlKHN0YXR1c0NvZGUpXG5cdGNvbnN0ICRjb250ZW50TGVuZ3RoID0gY29udGVudExlbmd0aCA+PSAwID8gcHJldHR5Qnl0ZXMoY29udGVudExlbmd0aCkgOiAnPyBCJ1xuXHRjb25zdCAkcmVzcG9uc2VUaW1lID0gcmVzcG9uc2VUaW1lID49IDAgPyBwcmV0dHlNcyhyZXNwb25zZVRpbWUpIDogJydcblxuXHQvLyBBZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuXHRjb25zdCBtZXRhZGF0YSA9IGAoJHskY29udGVudExlbmd0aH0sICR7JHJlc3BvbnNlVGltZX0pYFxuXG5cdHJldHVybiBbXG5cdFx0YOKGkiAkeyRtZXRob2R9ICR7VVJMIGFzIHN0cmluZ30gJHskdmVyc2lvbn1gLFxuXHRcdGDihpAgJHskdmVyc2lvbn0gJHskc3RhdHVzQ29kZX0gJHttZXRhZGF0YX1gLFxuXHRdLmpvaW4oJ1xcbicpXG59XG5cbmV4cG9ydCBkZWZhdWx0IGV4ZWN1dGlvbk1vZGUgPT09IEV4ZWN1dGlvbk1vZGUuRGV2ZWxvcG1lbnRNb2RlID8gZm9ybWF0Rm9yTW9yZ2FuIDogbW9yZ2FuLmNvbWJpbmVkXG4iLCJpbXBvcnQgJ3JlZmxlY3QtbWV0YWRhdGEnXG5cbi8vIE5vZGUuanMgYnVpbHQtaW4gQVBJcy5cbmltcG9ydCB7IEluY29taW5nTWVzc2FnZSBhcyBIdHRwUmVxdWVzdCwgU2VydmVyUmVzcG9uc2UgYXMgSHR0cFJlc3BvbnNlIH0gZnJvbSAnaHR0cCdcbmltcG9ydCB7IFBhc3NUaHJvdWdoIH0gZnJvbSAnc3RyZWFtJ1xuXG4vLyBUaGlyZC1wYXJ0eSBtb2R1bGVzLlxuaW1wb3J0IFByb21pc2UgZnJvbSAnYmx1ZWJpcmQnXG5pbXBvcnQgbG9kYXNoIGZyb20gJ2xvZGFzaCdcbmltcG9ydCBtb3JnYW4gZnJvbSAnbW9yZ2FuJ1xuaW1wb3J0IHR5cGUgeyBsZXZlbCBhcyBMb2dnaW5nTGV2ZWwgfSBmcm9tICd3aW5zdG9uJ1xuaW1wb3J0ICogYXMgd2luc3RvbiBmcm9tICd3aW5zdG9uJ1xuaW1wb3J0IHsgTG9nZ2VyIGFzIEJhc2VMb2dnZXIgfSBmcm9tICd3aW5zdG9uJ1xuXG4vLyBGb3JtYXR0ZXJzLlxuaW1wb3J0IGZvcm1hdEZvckNMSSBmcm9tICcuLi9mb3JtYXR0ZXJzL2NvbW1hbmQtbGluZSdcbmltcG9ydCBmb3JtYXRGb3JNb3JnYW4gZnJvbSAnLi4vZm9ybWF0dGVycy9tb3JnYW4nXG5cbi8vIExvY2FsIGhlbHBlcnMuXG5pbXBvcnQgeyBFeGVjdXRpb25Nb2RlLCBleGVjdXRpb25Nb2RlIH0gZnJvbSAnLi4vaGVscGVycy9jb25zdGFudHMnXG5cbi8vIEhhbmRsZXIgaW1wbGVtZW50YXRpb25zLlxuaW1wb3J0IHR5cGUgeyBMb2dnaW5nTGV2ZWxOYW1lIH0gZnJvbSAnLi4vaGFuZGxlcnMnXG5pbXBvcnQgaGFuZGxlcnMgZnJvbSAnLi4vaGFuZGxlcnMnXG5cbi8vIFR5cGUgZGVmaW5pdGlvbnMuXG50eXBlIE1vcmdhbiA9IChyZXE6IEh0dHBSZXF1ZXN0LCByZXM6IEh0dHBSZXNwb25zZSwgbmV4dDogKGVycm9yPzogRXJyb3IpID0+IHZvaWQpID0+IHZvaWRcblxuLy8gVHJhbnNwb3J0cy5cbmNvbnN0IHsgQ29uc29sZTogQ29uc29sZVRyYW5zcG9ydCB9ID0gd2luc3Rvbi50cmFuc3BvcnRzXG5cbi8vIEtleXMgaW4gb3JkZXIgdG8gYWNjZXNzIHByaXZhdGUgcHJvcGVydGllcy5cbmNvbnN0IEtleU9mSW5zdGFuY2U6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2woJ0BjaWNob2wvbG9nZ2VyOjpjbGFzc2VzL2xvZ2dlcjo6SW5zdGFuY2UnKVxuY29uc3QgS2V5T2ZQYXNzcG9ydDogdW5pcXVlIHN5bWJvbCA9IFN5bWJvbCgnQGNpY2hvbC9sb2dnZXI6OmNsYXNzZXMvbG9nZ2VyOjpQYXNzcG9ydCcpXG5cbmNsYXNzIExvZ2dlciB7XG5cdCNsb2dnZXI6IEJhc2VMb2dnZXIgPSB3aW5zdG9uLmNyZWF0ZUxvZ2dlcih7XG5cdFx0bGV2ZWxzOiBsb2Rhc2goaGFuZGxlcnMpXG5cdFx0XHQubWFwKCh7IG5hbWUsIGxldmVsIH0pID0+IFsgbmFtZSwgbGV2ZWwgXSlcblx0XHRcdC5maWx0ZXIoKFsgLCBsZXZlbCBdKSA9PiB0eXBlb2YgbGV2ZWwgPT09ICdudW1iZXInKVxuXHRcdFx0LmZyb21QYWlycygpXG5cdFx0XHQudmFsdWUoKSxcblxuXHRcdGxldmVsOiAoZXhlY3V0aW9uTW9kZSA9PT0gRXhlY3V0aW9uTW9kZS5Qcm9kdWN0aW9uTW9kZSA/ICdodHRwJyA6ICd2ZXJib3NlJykgYXMgdHlwZW9mIExvZ2dpbmdMZXZlbCxcblxuXHRcdHRyYW5zcG9ydHM6IFtcblx0XHRcdG5ldyBDb25zb2xlVHJhbnNwb3J0KHsgZm9ybWF0OiBmb3JtYXRGb3JDTEkgfSksXG5cdFx0XSxcblxuXHRcdGV4aXRPbkVycm9yOiBmYWxzZSxcblx0fSlcblxuXHQjbW9yZ2FuOiBNb3JnYW4gPSBtb3JnYW4oZm9ybWF0Rm9yTW9yZ2FuLCB7XG5cdFx0c3RyZWFtOiBuZXcgUGFzc1Rocm91Z2goeyBvYmplY3RNb2RlOiB0cnVlIH0pLm9uKCdkYXRhJywgKGRhdGE6IHN0cmluZykgPT4ge1xuXHRcdFx0dGhpcy5sb2coJ2h0dHAnLCBkYXRhLnRyaW0oKSlcblx0XHR9KSxcblx0fSkgYXMgTW9yZ2FuXG5cblx0cHJpdmF0ZSBjb25zdHJ1Y3RvcihwYXNzcG9ydDogdHlwZW9mIEtleU9mUGFzc3BvcnQpIHtcblx0XHRpZiAocGFzc3BvcnQgIT09IEtleU9mUGFzc3BvcnQpIHtcblx0XHRcdHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcignTG9nZ2VyIGNsYXNzIGNhbm5vdCBiZSBjb25zdHJ1Y3RlZCBpbiBkaXJlY3RseScpXG5cdFx0fVxuXHR9XG5cblx0cHVibGljIHN0YXRpYyBnZXQgaW5zdGFuY2UoKTogTG9nZ2VyIHtcblx0XHRpZiAodGhpcyAhPT0gTG9nZ2VyKSB7XG5cdFx0XHR0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoJ0xvZ2dlciBjbGFzcyBpcyBub3QgaW5oZXJpdGFibGUnKVxuXHRcdH1cblxuXHRcdGlmIChSZWZsZWN0Lmhhc093bk1ldGFkYXRhKEtleU9mSW5zdGFuY2UsIExvZ2dlcikpIHtcblx0XHRcdHJldHVybiBSZWZsZWN0LmdldE93bk1ldGFkYXRhKEtleU9mSW5zdGFuY2UsIExvZ2dlcilcblx0XHR9XG5cblx0XHRjb25zdCBpbnN0YW5jZSA9IG5ldyBMb2dnZXIoS2V5T2ZQYXNzcG9ydClcblxuXHRcdHRyeSB7XG5cdFx0XHRyZXR1cm4gaW5zdGFuY2Vcblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0UmVmbGVjdC5kZWZpbmVNZXRhZGF0YShLZXlPZkluc3RhbmNlLCBpbnN0YW5jZSwgTG9nZ2VyKVxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBMb2dnaW5nIG1lc3NhZ2Ugd2l0aCBzcGVjaWZpYyBsZXZlbC5cblx0ICpcblx0ICogQHBhcmFtIGxldmVsXG5cdCAqIEBwYXJhbSBtZXNzYWdlXG5cdCAqIEBwYXJhbSBhcmdzIEFkZGl0aW9uYWwgbWV0YWRhdGEuXG5cdCAqL1xuXHRwdWJsaWMgbG9nKGxldmVsOiBMb2dnaW5nTGV2ZWxOYW1lLCBtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKTogdm9pZFxuXG5cdC8qKlxuXHQgKiBMb2dnaW5nIEhUVFAgSS9PLlxuXHQgKlxuXHQgKiBAcGFyYW0gcmVxdWVzdCBOb2RlLmpzIGJ1aWx0LWluIGBJbmNvbWluZ01lc3NhZ2VgIGluc3RhbmNlIGZyb20gYGh0dHBgIG1vZHVsZS5cblx0ICogQHBhcmFtIHJlc3BvbnNlIE5vZGUuanMgYnVpbHQtaW4gYFNlcnZlclJlc3BvbnNlYCBpbnN0YW5jZSBmcm9tIGBodHRwYCBtb2R1bGUuXG5cdCAqL1xuXHRwdWJsaWMgbG9nKHJlcXVlc3Q6IEh0dHBSZXF1ZXN0LCByZXNwb25zZTogSHR0cFJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPlxuXG5cdC8qKlxuXHQgKiBMb2dnaW5nIGVycm9ycyBpbiBkZXRhaWwuXG5cdCAqXG5cdCAqIEBwYXJhbSBlcnJvclxuXHQgKi9cblx0cHVibGljIGxvZyhlcnJvcjogRXJyb3IpOiB2b2lkXG5cblx0cHVibGljIGxvZyguLi5hcmdzOiBhbnlbXSk6IHZvaWQgfCBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBsb2dnZXIgPSB0aGlzLiNsb2dnZXJcblx0XHRjb25zdCBtb3JnYW4gPSB0aGlzLiNtb3JnYW5cblxuXHRcdHN3aXRjaCAodHJ1ZSkge1xuXHRcdGNhc2UgKGFyZ3MubGVuZ3RoID49IDIgJiYgYXJnc1swXSBpbnN0YW5jZW9mIEh0dHBSZXF1ZXN0ICYmIGFyZ3NbMV0gaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UpOiB7XG5cdFx0XHRjb25zdCBbIHJlcXVlc3QsIHJlc3BvbnNlIF0gPSBhcmdzIGFzIFsgSHR0cFJlcXVlc3QsIEh0dHBSZXNwb25zZSBdXG5cblx0XHRcdHJldHVybiBQcm9taXNlLmZyb21DYWxsYmFjazx2b2lkPihjYWxsYmFjayA9PiBtb3JnYW4ocmVxdWVzdCwgcmVzcG9uc2UsIGNhbGxiYWNrKSlcblx0XHR9XG5cblx0XHRjYXNlIChhcmdzLmxlbmd0aCA+PSAxICYmIGFyZ3NbMF0gaW5zdGFuY2VvZiBFcnJvcik6IHtcblx0XHRcdGNvbnN0IFsgZXJyb3IsIC4uLmRhdGEgXSA9IGFyZ3MgYXMgWyBFcnJvciwgLi4uYW55W10gXVxuXG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hcmd1bWVudFxuXHRcdFx0bG9nZ2VyLmxvZygnZXJyb3InLCBlcnJvci5tZXNzYWdlLCBlcnJvciwgLi4uZGF0YSlcblxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZFxuXHRcdH1cblxuXHRcdGRlZmF1bHQ6IHtcblx0XHRcdGNvbnN0IFsgbGV2ZWwsIG1lc3NhZ2UsIC4uLmRhdGEgXSA9IGFyZ3MgYXMgWyB0eXBlb2YgTG9nZ2luZ0xldmVsLCBzdHJpbmcsIC4uLmFueVtdIF1cblxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXJndW1lbnRcblx0XHRcdGxvZ2dlci5sb2cobGV2ZWwsIG1lc3NhZ2UsIC4uLmRhdGEpXG5cblx0XHRcdHJldHVybiB1bmRlZmluZWRcblx0XHR9XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBkZWZhdWx0IExvZ2dlci5pbnN0YW5jZVxuIl0sIm5hbWVzIjpbIkxvZ2dpbmdMZXZlbCIsIkZhdGFsIiwiRXJyb3IiLCJXYXJuaW5nIiwiTm90aWNlIiwiSW5mbyIsIkh0dHAiLCJRdWVyeSIsIlZlcmJvc2UiLCJEZWJ1ZyIsImNvbG9yaXplck1hcCIsIl9NYXAiLCJjcmVhdGVTY2hlbWUiLCJvcHRpb25zIiwibmV4dEluZGV4Iiwic2l6ZSIsImNvbG9yaXplciIsImNoYWxrIiwiYmdIZXgiLCJiYWNrZ3JvdW5kIiwiaGV4IiwiZm9yZWdyb3VuZCIsInNldCIsIkNvbG9yVmFsdWUiLCJXaGl0ZSIsIkdyYXkiLCJCbGFjayIsIkNyaXRpY2FsIiwiUmVndWxhciIsIkNvbG9yU2NoZW1lIiwiTG91ZCIsImdldENoYWxrT2YiLCJjb2xvclNldCIsImdldCIsImlzVFRZIiwicHJvY2VzcyIsInN0ZG91dCIsImlzTm90T25DTEkiLCJkZWNvcmF0ZUxhYmVsIiwibGFiZWwiLCJzY2hlbWUiLCJkZWNvcmF0ZWRMYWJlbCIsImJvbGQiLCJyb290UGF0aCIsImN3ZCIsImNvbmp1bmN0aW9uIiwiYmx1ZSIsInNwbGF0IiwiX1N5bWJvbCRmb3IiLCJuYW1lIiwibGV2ZWwiLCJtYXBMb2NhdGlvbk9mRXJyb3JUaHJvd24iLCJmaWxlbmFtZSIsInRhcmdldCIsInBhdGgiLCJyZWxhdGl2ZSIsIl9zdGFydHNXaXRoSW5zdGFuY2VQcm9wZXJ0eSIsImNhbGwiLCJncmF5IiwicmVwbGFjZSIsIm1hdGNoZXMiLCJtb2R1bGVOYW1lIiwidHJhaWxpbmciLCJzZXAiLCJ1bmRlcmxpbmUiLCJkaXJuYW1lIiwiYmFzZW5hbWUiLCJoYW5kbGUiLCJkYXRhIiwiX2NvbnRleHQiLCJfY29udGV4dDIiLCJfY29udGV4dDMiLCJlcnJvciIsInVuZGVmaW5lZCIsIm1lc3NhZ2UiLCJzdGFjayIsInJhd1N0YWNrIiwiX21hcEluc3RhbmNlUHJvcGVydHkiLCJfc2xpY2VJbnN0YW5jZVByb3BlcnR5IiwibGVuZ3RoIiwic3BsaXQiLCJsaW5lIiwiaXNBYnNvbHV0ZSIsImNvbnRleHROYW1lIiwicmF3TG9jYXRpb24iLCJsb2NhdGlvbiIsImNvbHVtbiIsInZlcnNpb24iLCJqb2luIiwicGF5bG9hZCIsImhpZ2hsaWdodCIsImxhbmd1YWdlIiwiaGFuZGxlcnMiLCJGYXRhbEhhbmRsZXIiLCJFcnJvckhhbmRsZXIiLCJXYXJuaW5nSGFuZGxlciIsIk5vdGljZUhhbmRsZXIiLCJJbmZvSGFuZGxlciIsIkh0dHBIYW5kbGVyIiwiUXVlcnlIYW5kbGVyIiwiVmVyYm9zZUhhbmRsZXIiLCJEZWJ1Z0hhbmRsZXIiLCJmb3JtYXQiLCJwcmludGYiLCJ0aW1lc3RhbXAiLCJEYXRlVGltZSIsIm5vdyIsInRvSVNPIiwiaW5jbHVkZU9mZnNldCIsImhhbmRsZXIiLCJfZmluZEluc3RhbmNlUHJvcGVydHkiLCJmYWxsYmFjayIsInBlcmZvcm1IYW5kbGUiLCJkZWZhdWx0IiwiX1JlZmxlY3QkYXBwbHkiLCJleHRyYUZpbmdlcnByaW50IiwidHJhbnNhY3Rpb25JZCIsInJUcmFjZXIiLCJpZCIsIkV4ZWN1dGlvbk1vZGUiLCJEZXZlbG9wbWVudE1vZGUiLCJQcm9kdWN0aW9uTW9kZSIsIkNsdXN0ZXJpbmdNb2RlIiwiTWFzdGVyUHJvY2VzcyIsIldvcmtlclByb2Nlc3MiLCJleGVjdXRpb25Nb2RlIiwiZW52aXJvbm1lbnRzIiwiTk9ERV9FTlYiLCJjbHVzdGVyIiwiaXNQcmltYXJ5IiwiaXNNYXN0ZXIiLCJkZWNvcmF0ZVN0YXR1c0NvZGUiLCJzdGF0dXNDb2RlIiwiZ3JvdXBPZkNvZGUiLCJNYXRoIiwiZmxvb3IiLCJOdW1iZXIiLCJiYXNlTWVzc2FnZSIsIlNUQVRVU19DT0RFUyIsImdyZWVuIiwibWFnZW50YSIsInJlZCIsImZvcm1hdEZvck1vcmdhbiIsInRva2VucyIsInJlcXVlc3QiLCJyZXNwb25zZSIsIl8iLCJ0b2tlbiIsInN1YkFyZ3MiLCJtZXRob2QiLCJVUkwiLCJodHRwVmVyc2lvbiIsImNvbnRlbnRMZW5ndGgiLCJyZXNwb25zZVRpbWUiLCIkbWV0aG9kIiwiJHZlcnNpb24iLCJyZ2IiLCIkc3RhdHVzQ29kZSIsIiRjb250ZW50TGVuZ3RoIiwicHJldHR5Qnl0ZXMiLCIkcmVzcG9uc2VUaW1lIiwicHJldHR5TXMiLCJtZXRhZGF0YSIsIm1vcmdhbiIsImNvbWJpbmVkIiwiQ29uc29sZSIsIkNvbnNvbGVUcmFuc3BvcnQiLCJ3aW5zdG9uIiwidHJhbnNwb3J0cyIsIktleU9mSW5zdGFuY2UiLCJfU3ltYm9sIiwiS2V5T2ZQYXNzcG9ydCIsIkxvZ2dlciIsImNyZWF0ZUxvZ2dlciIsImxldmVscyIsIl9maWx0ZXJJbnN0YW5jZVByb3BlcnR5IiwibG9kYXNoIiwiZnJvbVBhaXJzIiwidmFsdWUiLCJmb3JtYXRGb3JDTEkiLCJleGl0T25FcnJvciIsInN0cmVhbSIsIlBhc3NUaHJvdWdoIiwib2JqZWN0TW9kZSIsIm9uIiwibG9nIiwiX3RyaW1JbnN0YW5jZVByb3BlcnR5IiwiY29uc3RydWN0b3IiLCJwYXNzcG9ydCIsIlJlZmVyZW5jZUVycm9yIiwiaW5zdGFuY2UiLCJSZWZsZWN0IiwiaGFzT3duTWV0YWRhdGEiLCJnZXRPd25NZXRhZGF0YSIsImRlZmluZU1ldGFkYXRhIiwiYXJncyIsImxvZ2dlciIsIkh0dHBSZXF1ZXN0IiwiSHR0cFJlc3BvbnNlIiwiUHJvbWlzZSIsImZyb21DYWxsYmFjayIsImNhbGxiYWNrIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsTUFBTUEsWUFBWSxHQUFHO0FBQ3BCO0FBQ0FDLEVBQUFBLEtBQUssRUFBRSxDQUFDO0FBQ1JDLEVBQUFBLEtBQUssRUFBRSxDQUFDO0FBRVI7QUFDQUMsRUFBQUEsT0FBTyxFQUFFLENBQUM7QUFFVjtBQUNBQyxFQUFBQSxNQUFNLEVBQUUsQ0FBQztBQUNUQyxFQUFBQSxJQUFJLEVBQUUsQ0FBQztBQUVQO0FBQ0FDLEVBQUFBLElBQUksRUFBRSxDQUFDO0FBQ1BDLEVBQUFBLEtBQUssRUFBRSxDQUFDO0FB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