@rfprodz/client-util-eliza 1.2.21 → 1.2.23

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.
Files changed (26) hide show
  1. package/esm2022/lib/eliza.module.mjs +20 -0
  2. package/esm2022/lib/services/eliza/eliza.service.mjs +442 -0
  3. package/{fesm2020 → fesm2022}/rfprodz-client-util-eliza.mjs +7 -7
  4. package/{fesm2020 → fesm2022}/rfprodz-client-util-eliza.mjs.map +1 -1
  5. package/package.json +6 -12
  6. package/esm2020/lib/eliza.module.mjs +0 -19
  7. package/esm2020/lib/services/eliza/eliza.service.mjs +0 -441
  8. package/fesm2015/rfprodz-client-util-eliza.mjs +0 -1571
  9. package/fesm2015/rfprodz-client-util-eliza.mjs.map +0 -1
  10. /package/{esm2020 → esm2022}/index.mjs +0 -0
  11. /package/{esm2020 → esm2022}/lib/config/data.config.mjs +0 -0
  12. /package/{esm2020 → esm2022}/lib/config/eliza.config.mjs +0 -0
  13. /package/{esm2020 → esm2022}/lib/config/finals.config.mjs +0 -0
  14. /package/{esm2020 → esm2022}/lib/config/index.mjs +0 -0
  15. /package/{esm2020 → esm2022}/lib/config/initials.config.mjs +0 -0
  16. /package/{esm2020 → esm2022}/lib/config/keywords.config.mjs +0 -0
  17. /package/{esm2020 → esm2022}/lib/config/post-transforms.config.mjs +0 -0
  18. /package/{esm2020 → esm2022}/lib/config/posts.config.mjs +0 -0
  19. /package/{esm2020 → esm2022}/lib/config/pres.config.mjs +0 -0
  20. /package/{esm2020 → esm2022}/lib/config/quits.config.mjs +0 -0
  21. /package/{esm2020 → esm2022}/lib/config/synonyms.config.mjs +0 -0
  22. /package/{esm2020 → esm2022}/lib/interfaces/chat.interface.mjs +0 -0
  23. /package/{esm2020 → esm2022}/lib/interfaces/eliza.interface.mjs +0 -0
  24. /package/{esm2020 → esm2022}/lib/interfaces/index.mjs +0 -0
  25. /package/{esm2020 → esm2022}/lib/services/index.mjs +0 -0
  26. /package/{esm2020 → esm2022}/rfprodz-client-util-eliza.mjs +0 -0
@@ -1,441 +0,0 @@
1
- /**
2
- * elizabot.js v.1.1 - ELIZA JS library (N.Landsteiner 2005)
3
- * Eliza is a mock Rogerian psychotherapist.
4
- * Original program by Joseph Weizenbaum in MAD-SLIP for "Project MAC" at MIT.
5
- * cf: Weizenbaum, Joseph "ELIZA - A Computer Program For the Study of Natural Language Communication Between Man and Machine"
6
- * in: Communications of the ACM; Volume 9 , Issue 1 (January 1966): p 36-45.
7
- * JavaScript implementation by Norbert Landsteiner 2005; <http://www.masserk.at>
8
- *
9
- * `ElizaBot' is also a general chatbot engine that can be supplied with any rule set.
10
- * (for required data structures cf. "elizadata.js" and/or see the documentation.)
11
- * data is parsed and transformed for internal use at the creation time of the first instance of the `ElizaBot' constructor.
12
- *
13
- * JavaScript source: https://github.com/natelewis/eliza-as-promised
14
- */
15
- import { Inject, Injectable } from '@angular/core';
16
- import { BehaviorSubject } from 'rxjs';
17
- import { ELIZA_DATA } from '../../config/data.config';
18
- import { elizaInitialConfig } from '../../config/eliza.config';
19
- import { elizaFinalDefault } from '../../config/finals.config';
20
- import { elizaInitialDefault } from '../../config/initials.config';
21
- import * as i0 from "@angular/core";
22
- export class AppElizaService {
23
- constructor(elizaData) {
24
- this.elizaData = elizaData;
25
- /**
26
- * Eliza configuration.
27
- */
28
- this.configSubject = new BehaviorSubject({ ...elizaInitialConfig });
29
- /**
30
- * Publicly readable Eliza configuration.
31
- */
32
- this.config$ = this.configSubject.asObservable();
33
- this.mem = [];
34
- this.lastChoice = [];
35
- this.postExp = new RegExp('');
36
- this.preExp = new RegExp('');
37
- this.pres = {};
38
- this.posts = {};
39
- /**
40
- * Conversation messages.
41
- */
42
- this.messagesSubject = new BehaviorSubject([]);
43
- /**
44
- * Publicly readable conversation messages.
45
- */
46
- this.messages$ = this.messagesSubject.asObservable();
47
- this.setup(elizaData);
48
- }
49
- /**
50
- * Adds next chat message.
51
- * @param message chat message
52
- */
53
- nextMessage(message) {
54
- this.messagesSubject.next([...this.messagesSubject.value, message]);
55
- }
56
- /**
57
- * Modifies Eliza configuration.
58
- * @param config Eliza config
59
- */
60
- nextConfig(config) {
61
- this.configSubject.next({ ...this.configSubject.value, ...config });
62
- }
63
- /**
64
- * Sets up Eliza.
65
- * @param data Eliza data
66
- * @param reinitialize indicates that Eliza should be initialized again, even if it's data has already been initialized
67
- */
68
- setup(data, reinitialize = false) {
69
- if (typeof this.data === 'undefined' || reinitialize) {
70
- this.init(data);
71
- }
72
- this.reset();
73
- }
74
- /**
75
- * Resets Eliza.
76
- */
77
- reset() {
78
- const data = this.data;
79
- if (typeof data === 'undefined') {
80
- throw new Error('Initialize Eliza first.');
81
- }
82
- this.mem = [];
83
- this.lastChoice = [];
84
- for (let k = 0; k < data.keywords.length; k += 1) {
85
- this.lastChoice[k] = [];
86
- const rules = data.keywords[k].rules;
87
- for (let i = 0; i < rules.length; i += 1) {
88
- this.lastChoice[k][i] = -1;
89
- }
90
- }
91
- this.messagesSubject.next([{ bot: true, text: this.getInitial(data) }]);
92
- }
93
- // eslint-disable-next-line max-lines-per-function, complexity -- TODO refactor
94
- init(data) {
95
- this.data = { ...data };
96
- // Parse data and convert it from canonical form to internal use.
97
- // Produce a list of synonyms.
98
- const synPatterns = {};
99
- for (const item in this.data.synonyms) {
100
- if (item) {
101
- synPatterns[item] = `(${item}|${this.data.synonyms[item].join('|')})`;
102
- }
103
- }
104
- // Check keywords.
105
- if (data.keywords.length === 0) {
106
- throw Error('Eliza does not have any configured keywords.');
107
- }
108
- // First, convert rules to regexps.
109
- // Expand synonyms and insert asterisk expressions for backtracking.
110
- const sre = /@(\S+)/;
111
- const are = /(\S)\s*\*\s*(\S)/;
112
- const are1 = /^\s*\*\s*(\S)/;
113
- const are2 = /(\S)\s*\*\s*$/;
114
- const are3 = /^\s*\*\s*$/;
115
- const wsre = /\s+/g;
116
- for (let i = 0; i < this.data.keywords.length; i += 1) {
117
- const rules = this.data.keywords[i].rules;
118
- for (let j = 0; j < rules.length; j += 1) {
119
- const rule = rules[j];
120
- // Check mem flag and store it as decomp's element 2.
121
- if (rule.pattern.charAt(0) === '$') {
122
- let ofs = 1;
123
- while (rule.pattern.charAt(ofs) === ' ') {
124
- ofs += 1;
125
- }
126
- rule.pattern = rule.pattern.substring(ofs);
127
- rule.memory = true;
128
- }
129
- else {
130
- rule.memory = false;
131
- }
132
- let match = rule.pattern.match(sre);
133
- while (match !== null) {
134
- const sp = synPatterns[match[1]] ? synPatterns[match[1]] : match[1];
135
- rule.pattern = rule.pattern.substring(0, match.index ?? 0) + sp + rule.pattern.substring((match.index ?? 0) + match[0].length);
136
- match = rule.pattern.match(sre);
137
- }
138
- // Expand asterisk expressions.
139
- if (are3.test(rule.pattern)) {
140
- rule.pattern = '\\s*(.*)\\s*';
141
- }
142
- else {
143
- match = rule.pattern.match(are);
144
- if (match !== null) {
145
- let leftPart = '';
146
- let rightPart = rule.pattern;
147
- while (match !== null) {
148
- leftPart += rightPart.substring(0, (match.index ?? 0) + 1);
149
- if (match[1] !== ')') {
150
- leftPart += '\\b';
151
- }
152
- leftPart += '\\s*(.*)\\s*';
153
- if (match[2] !== '(' && match[2] !== '\\') {
154
- leftPart += '\\b';
155
- }
156
- leftPart += match[2];
157
- rightPart = rightPart.substring((match.index ?? 0) + match[0].length);
158
- match = rightPart.match(are);
159
- }
160
- rule.pattern = leftPart + rightPart;
161
- }
162
- match = rule.pattern.match(are1);
163
- if (match !== null) {
164
- let leftPart = '\\s*(.*)\\s*';
165
- if (match[1] !== ')' && match[1] !== '\\') {
166
- leftPart += '\\b';
167
- }
168
- rule.pattern = leftPart + rule.pattern.substring((match.index ?? 0) - 1 + match[0].length);
169
- }
170
- match = rule.pattern.match(are2);
171
- if (match !== null) {
172
- let leftPart = rule.pattern.substring(0, (match.index ?? 0) + 1);
173
- if (match[1] !== '(') {
174
- leftPart += '\\b';
175
- }
176
- rule.pattern = leftPart + '\\s*(.*)\\s*';
177
- }
178
- }
179
- // Expand whitespaces.
180
- rule.pattern = rule.pattern.replace(wsre, '\\s+');
181
- wsre.lastIndex = 0;
182
- }
183
- }
184
- // Sort keywords by rank (highest first).
185
- this.data.keywords.sort(this.sortKeywords);
186
- // Compose regexps and refs for pres and posts.
187
- this.composeRegExpsAndPresAndPosts(this.data);
188
- }
189
- /**
190
- * Composes regexps and refs for pres and posts.
191
- * @param data Eliza data
192
- */
193
- composeRegExpsAndPresAndPosts(data) {
194
- this.pres = {};
195
- this.posts = {};
196
- if (data.pres.length === 0) {
197
- throw Error('Eliza does not have any configured pre expressions.');
198
- }
199
- else {
200
- const a = [];
201
- for (let i = 0; i < data.pres.length; i += 2) {
202
- a.push(data.pres[i]);
203
- this.pres[data.pres[i]] = data.pres[i + 1];
204
- }
205
- this.preExp = new RegExp('\\b(' + a.join('|') + ')\\b');
206
- }
207
- if (data.posts.length === 0) {
208
- throw Error('Eliza does not have any configured post expressions.');
209
- }
210
- else {
211
- const a = [];
212
- for (let i = 0; i < data.posts.length; i += 2) {
213
- a.push(data.posts[i]);
214
- this.posts[data.posts[i]] = data.posts[i + 1];
215
- }
216
- this.postExp = new RegExp('\\b(' + a.join('|') + ')\\b');
217
- }
218
- }
219
- // eslint-disable-next-line max-lines-per-function, complexity -- TODO refactor
220
- execRule(data, k, sentence) {
221
- const config = this.configSubject.value;
222
- const rules = data.keywords[k].rules;
223
- const paramRegExp = /\(([0-9]+)\)/;
224
- for (let i = 0; i < rules.length; i += 1) {
225
- const match = sentence.match(rules[i].pattern);
226
- if (match !== null) {
227
- const options = rules[i].options;
228
- const memory = rules[i].memory;
229
- let optionIndex = config.noRandom ? 0 : Math.floor(Math.random() * options.length);
230
- if ((config.noRandom && this.lastChoice[k][i] > optionIndex) || this.lastChoice[k][i] === optionIndex) {
231
- this.lastChoice[k][i] += 1;
232
- optionIndex = this.lastChoice[k][i];
233
- if (optionIndex >= options.length) {
234
- optionIndex = 0;
235
- this.lastChoice[k][i] = -1;
236
- }
237
- }
238
- else {
239
- this.lastChoice[k][i] = optionIndex;
240
- }
241
- let reply = options[optionIndex];
242
- if (config.debug) {
243
- const debugLog = `match:\nkey: ${data.keywords[k].key}\nrank: ${data.keywords[k].rank}\ndecomp: ${rules[i].pattern}\nreasmb: ${reply}\nmemory: ${memory}`;
244
- // eslint-disable-next-line no-console -- debug output
245
- console.warn('debugLog', debugLog);
246
- }
247
- if (reply.search('^goto ') === 0) {
248
- const key = reply.substring(5);
249
- const ki = this.getRuleIndexByKey(data, key);
250
- if (ki >= 0) {
251
- return this.execRule(data, ki, sentence);
252
- }
253
- }
254
- // Substitute positional params.
255
- let paramRegExpMatch = reply.match(paramRegExp);
256
- if (paramRegExpMatch) {
257
- let leftPart = '';
258
- let rightPart = reply;
259
- while (paramRegExpMatch !== null) {
260
- let param = match[parseInt(paramRegExpMatch[1], 10)];
261
- // Postprocess param.
262
- let postExpMatch = param.match(this.postExp);
263
- if (postExpMatch !== null) {
264
- let leftPart2 = '';
265
- let rightPart2 = param;
266
- while (postExpMatch !== null) {
267
- leftPart2 += rightPart2.substring(0, postExpMatch.index ?? 0) + this.posts[postExpMatch[1]];
268
- rightPart2 = rightPart2.substring((postExpMatch.index ?? 0) + postExpMatch[0].length);
269
- postExpMatch = rightPart2.match(this.postExp);
270
- }
271
- param = leftPart2 + rightPart2;
272
- }
273
- leftPart += rightPart.substring(0, paramRegExpMatch.index) + param;
274
- rightPart = rightPart.substring((paramRegExpMatch.index ?? 0) + paramRegExpMatch[0].length);
275
- paramRegExpMatch = rightPart.match(paramRegExp);
276
- }
277
- reply = leftPart + rightPart;
278
- }
279
- const transformedReply = this.postTransform(data, reply);
280
- if (memory) {
281
- this.memSave(transformedReply);
282
- }
283
- else {
284
- return transformedReply;
285
- }
286
- }
287
- }
288
- return '';
289
- }
290
- // eslint-disable-next-line complexity -- TODO refactor
291
- transformUserQuery(data, input) {
292
- let reply = '';
293
- // Unify text string and split text in part sentences and loop through them.
294
- const parts = this.splitUserQueryIntoParts(input);
295
- for (let i = 0; i < parts.length; i += 1) {
296
- let part = parts[i];
297
- if (part !== '') {
298
- // Check for quit expressions.
299
- for (let q = 0; q < data.quits.length; q += 1) {
300
- if (data.quits[q] === part) {
301
- return { reply: this.getFinal(data), final: true };
302
- }
303
- }
304
- let match = part.match(this.preExp);
305
- if (match !== null) {
306
- let leftPart = '';
307
- let rightPart = part;
308
- while (match !== null) {
309
- leftPart += rightPart.substring(0, match.index ?? 0) + this.pres[match[1]];
310
- rightPart = rightPart.substring((match.index ?? 0) + match[0].length);
311
- match = rightPart.match(this.preExp);
312
- }
313
- part = leftPart + rightPart;
314
- }
315
- // Loop trough keywords.
316
- for (let k = 0; k < data.keywords.length; k += 1) {
317
- if (part.search(new RegExp('\\b' + data.keywords[k].key + '\\b', 'i')) >= 0) {
318
- reply = this.execRule(data, k, part);
319
- }
320
- if (reply !== '') {
321
- return { reply, final: false };
322
- }
323
- }
324
- }
325
- }
326
- // Nothing matched, try mem.
327
- reply = this.memGet();
328
- // If nothing in mem, try xnone.
329
- if (reply === '') {
330
- const k = this.getRuleIndexByKey(data, 'xnone');
331
- reply = k >= 0 ? this.execRule(data, k, ' ') : reply;
332
- }
333
- return { reply: reply !== '' ? reply : 'I am at a loss for words.', final: false };
334
- }
335
- /**
336
- * Unify text string, split text into partial sentences to be able to loop through them.
337
- * @param input user query
338
- * @returns split user query
339
- */
340
- splitUserQueryIntoParts(input) {
341
- const parts = input
342
- .toLowerCase()
343
- .replace(/@#\$%\^&\*\(\)_\+=~`\{\[\}\]\|:;<>\/\\\t/g, ' ')
344
- .replace(/\s+-+\s+/g, '.')
345
- .replace(/\s*[,.?!;]+\s*/g, '.')
346
- .replace(/\s*\bbut\b\s*/g, '.')
347
- .replace(/\s{2,}/g, ' ')
348
- .split('.');
349
- return parts;
350
- }
351
- sortKeywords(a, b) {
352
- if (a.rank > b.rank) {
353
- return -1;
354
- }
355
- else if (a.rank < b.rank) {
356
- return 1;
357
- }
358
- else if (a.index > b.index) {
359
- return 1;
360
- }
361
- else if (a.index < b.index) {
362
- return -1;
363
- }
364
- return 0;
365
- }
366
- postTransform(data, input) {
367
- // final cleanings
368
- let result = input.replace(/\s{2,}/g, ' ').replace(/\s+\./g, '.');
369
- if (data.postTransforms.length > 0) {
370
- for (let i = 0; i < data.postTransforms.length; i += 1) {
371
- const postTransform = data.postTransforms[i];
372
- result = result.replace(postTransform.searchValue, postTransform.replaceValue);
373
- data.postTransforms[i].searchValue.lastIndex = 0;
374
- }
375
- }
376
- if (this.configSubject.value.capitalizeFirstLetter) {
377
- const match = result.match(/^([a-z])/);
378
- if (match) {
379
- result = match[0].toUpperCase() + result.substring(1);
380
- }
381
- }
382
- return result;
383
- }
384
- getRuleIndexByKey(data, key) {
385
- for (let k = 0; k < data.keywords.length; k += 1) {
386
- if (data.keywords[k].key === key) {
387
- return k;
388
- }
389
- }
390
- return -1;
391
- }
392
- memSave(input) {
393
- this.mem.push(input);
394
- if (this.mem.length > this.configSubject.value.memSize) {
395
- this.mem.shift();
396
- }
397
- }
398
- memGet() {
399
- if (this.mem.length > 0) {
400
- if (this.configSubject.value.noRandom) {
401
- return this.mem.shift() ?? '';
402
- }
403
- const n = Math.floor(Math.random() * this.mem.length);
404
- const reply = this.mem[n];
405
- for (let i = n + 1; i < this.mem.length; i += 1) {
406
- this.mem[i - 1] = this.mem[i];
407
- }
408
- this.mem.length -= 1;
409
- return reply;
410
- }
411
- return '';
412
- }
413
- getFinal(data) {
414
- return data.finals.length === 0 ? elizaFinalDefault : data.finals[Math.floor(Math.random() * data.finals.length)];
415
- }
416
- getInitial(data) {
417
- return data.initials.length === 0 ? elizaInitialDefault : data.initials[Math.floor(Math.random() * data.initials.length)];
418
- }
419
- getResponse(statement) {
420
- const data = this.data;
421
- if (typeof data === 'undefined') {
422
- throw new Error('Initialize Eliza first.');
423
- }
424
- return new Promise(resolve => {
425
- const elizaReply = this.transformUserQuery(data, statement);
426
- resolve(elizaReply);
427
- });
428
- }
429
- }
430
- /** @nocollapse */ AppElizaService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: AppElizaService, deps: [{ token: ELIZA_DATA }], target: i0.ɵɵFactoryTarget.Injectable });
431
- /** @nocollapse */ AppElizaService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: AppElizaService, providedIn: 'root' });
432
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: AppElizaService, decorators: [{
433
- type: Injectable,
434
- args: [{
435
- providedIn: 'root',
436
- }]
437
- }], ctorParameters: function () { return [{ type: undefined, decorators: [{
438
- type: Inject,
439
- args: [ELIZA_DATA]
440
- }] }]; } });
441
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxpemEuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvY2xpZW50LXV0aWwtZWxpemEvc3JjL2xpYi9zZXJ2aWNlcy9lbGl6YS9lbGl6YS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFFSCxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXZDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMvRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQzs7QUFPbkUsTUFBTSxPQUFPLGVBQWU7SUFtQzFCLFlBQWdELFNBQXFCO1FBQXJCLGNBQVMsR0FBVCxTQUFTLENBQVk7UUFsQ3JFOztXQUVHO1FBQ2Msa0JBQWEsR0FBRyxJQUFJLGVBQWUsQ0FBZSxFQUFFLEdBQUcsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO1FBRTlGOztXQUVHO1FBQ2EsWUFBTyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxFQUFFLENBQUM7UUFJcEQsUUFBRyxHQUFhLEVBQUUsQ0FBQztRQUVuQixlQUFVLEdBQWUsRUFBRSxDQUFDO1FBRTVCLFlBQU8sR0FBRyxJQUFJLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUV6QixXQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFeEIsU0FBSSxHQUEyQixFQUFFLENBQUM7UUFFbEMsVUFBSyxHQUEyQixFQUFFLENBQUM7UUFFM0M7O1dBRUc7UUFDYyxvQkFBZSxHQUFHLElB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S0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUM1SCxDQUFDO0lBRU0sV0FBVyxDQUFDLFNBQWlCO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdkIsSUFBSSxPQUFPLElBQUksS0FBSyxXQUFXLEVBQUU7WUFDL0IsTUFBTSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1NBQzVDO1FBQ0QsT0FBTyxJQUFJLE9BQU8sQ0FBaUIsT0FBTyxDQUFDLEVBQUU7WUFDM0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztZQUM1RCxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDOzsrSEF6YVUsZUFBZSxrQkFtQ04sVUFBVTttSUFuQ25CLGVBQWUsY0FGZCxNQUFNOzJGQUVQLGVBQWU7a0JBSDNCLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25COzswQkFvQ2MsTUFBTTsyQkFBQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBlbGl6YWJvdC5qcyB2LjEuMSAtIEVMSVpBIEpTIGxpYnJhcnkgKE4uTGFuZHN0ZWluZXIgMjAwNSlcbiAqIEVsaXphIGlzIGEgbW9jayBSb2dlcmlhbiBwc3ljaG90aGVyYXBpc3QuXG4gKiBPcmlnaW5hbCBwcm9ncmFtIGJ5IEpvc2VwaCBXZWl6ZW5iYXVtIGluIE1BRC1TTElQIGZvciBcIlByb2plY3QgTUFDXCIgYXQgTUlULlxuICogY2Y6IFdlaXplbmJhdW0sIEpvc2VwaCBcIkVMSVpBIC0gQSBDb21wdXRlciBQcm9ncmFtIEZvciB0aGUgU3R1ZHkgb2YgTmF0dXJhbCBMYW5ndWFnZSBDb21tdW5pY2F0aW9uIEJldHdlZW4gTWFuIGFuZCBNYWNoaW5lXCJcbiAqIGluOiBDb21tdW5pY2F0aW9ucyBvZiB0aGUgQUNNOyBWb2x1bWUgOSAsIElzc3VlIDEgKEphbnVhcnkgMTk2Nik6IHAgMzYtNDUuXG4gKiBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIGJ5IE5vcmJlcnQgTGFuZHN0ZWluZXIgMjAwNTsgPGh0dHA6Ly93d3cubWFzc2Vyay5hdD5cbiAqXG4gKiBgRWxpemFCb3QnIGlzIGFsc28gYSBnZW5lcmFsIGNoYXRib3QgZW5naW5lIHRoYXQgY2FuIGJlIHN1cHBsaWVkIHdpdGggYW55IHJ1bGUgc2V0LlxuICogKGZvciByZXF1aXJlZCBkYXRhIHN0cnVjdHVyZXMgY2YuIFwiZWxpemFkYXRhLmpzXCIgYW5kL29yIHNlZSB0aGUgZG9jdW1lbnRhdGlvbi4pXG4gKiBkYXRhIGlzIHBhcnNlZCBhbmQgdHJhbnNmb3JtZWQgZm9yIGludGVybmFsIHVzZSBhdCB0aGUgY3JlYXRpb24gdGltZSBvZiB0aGUgZmlyc3QgaW5zdGFuY2Ugb2YgdGhlIGBFbGl6YUJvdCcgY29uc3RydWN0b3IuXG4gKlxuICogSmF2YVNjcmlwdCBzb3VyY2U6IGh0dHBzOi8vZ2l0aHViLmNvbS9uYXRlbGV3aXMvZWxpemEtYXMtcHJvbWlzZWRcbiAqL1xuXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBFTElaQV9EQVRBIH0gZnJvbSAnLi4vLi4vY29uZmlnL2RhdGEuY29uZmlnJztcbmltcG9ydCB7IGVsaXphSW5pdGlhbENvbmZpZyB9IGZyb20gJy4uLy4uL2NvbmZpZy9lbGl6YS5jb25maWcnO1xuaW1wb3J0IHsgZWxpemFGaW5hbERlZmF1bHQgfSBmcm9tICcuLi8uLi9jb25maWcvZmluYWxzLmNvbmZpZyc7XG5pbXBvcnQgeyBlbGl6YUluaXRpYWxEZWZhdWx0IH0gZnJvbSAnLi4vLi4vY29uZmlnL2luaXRpYWxzLmNvbmZpZyc7XG5pbXBvcnQgeyBJQ2hhdE1lc3NhZ2UgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2NoYXQuaW50ZXJmYWNlJztcbmltcG9ydCB7IElFbGl6YUNvbmZpZywgSUVsaXphRGF0YSwgSUVsaXphS2V5d29yZCwgSUVsaXphUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2VsaXphLmludGVyZmFjZSc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBBcHBFbGl6YVNlcnZpY2Uge1xuICAvKipcbiAgICogRWxpemEgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY29uZmlnU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SUVsaXphQ29uZmlnPih7IC4uLmVsaXphSW5pdGlhbENvbmZpZyB9KTtcblxuICAvKipcbiAgICogUHVibGljbHkgcmVhZGFibGUgRWxpemEgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBjb25maWckID0gdGhpcy5jb25maWdTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIHByaXZhdGUgZGF0YT86IElFbGl6YURhdGE7XG5cbiAgcHJpdmF0ZSBtZW06IHN0cmluZ1tdID0gW107XG5cbiAgcHJpdmF0ZSBsYXN0Q2hvaWNlOiBudW1iZXJbXVtdID0gW107XG5cbiAgcHJpdmF0ZSBwb3N0RXhwID0gbmV3IFJlZ0V4cCgnJyk7XG5cbiAgcHJpdmF0ZSBwcmVFeHAgPSBuZXcgUmVnRXhwKCcnKTtcblxuICBwcml2YXRlIHByZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBwcml2YXRlIHBvc3RzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG5cbiAgLyoqXG4gICAqIENvbnZlcnNhdGlvbiBtZXNzYWdlcy5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgbWVzc2FnZXNTdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxJQ2hhdE1lc3NhZ2VbXT4oW10pO1xuXG4gIC8qKlxuICAgKiBQdWJsaWNseSByZWFkYWJsZSBjb252ZXJzYXRpb24gbWVzc2FnZXMuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbWVzc2FnZXMkID0gdGhpcy5tZXNzYWdlc1N1YmplY3QuYXNPYnNlcnZhYmxlKCk7XG5cbiAgY29uc3RydWN0b3IoQEluamVjdChFTElaQV9EQVRBKSBwdWJsaWMgcmVhZG9ubHkgZWxpemFEYXRhOiBJRWxpemFEYXRhKSB7XG4gICAgdGhpcy5zZXR1cChlbGl6YURhdGEpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgbmV4dCBjaGF0IG1lc3NhZ2UuXG4gICAqIEBwYXJhbSBtZXNzYWdlIGNoYXQgbWVzc2FnZVxuICAgKi9cbiAgcHVibGljIG5leHRNZXNzYWdlKG1lc3NhZ2U6IElDaGF0TWVzc2FnZSk6IHZvaWQge1xuICAgIHRoaXMubWVzc2FnZXNTdWJqZWN0Lm5leHQoWy4uLnRoaXMubWVzc2FnZXNTdWJqZWN0LnZhbHVlLCBtZXNzYWdlXSk7XG4gIH1cblxuICAvKipcbiAgICogTW9kaWZpZXMgRWxpemEgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIGNvbmZpZyBFbGl6YSBjb25maWdcbiAgICovXG4gIHB1YmxpYyBuZXh0Q29uZmlnKGNvbmZpZzogUGFydGlhbDxJRWxpemFDb25maWc+KTogdm9pZCB7XG4gICAgdGhpcy5jb25maWdTdWJqZWN0Lm5leHQoeyAuLi50aGlzLmNvbmZpZ1N1YmplY3QudmFsdWUsIC4uLmNvbmZpZyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHVwIEVsaXphLlxuICAgKiBAcGFyYW0gZGF0YSBFbGl6YSBkYXRhXG4gICAqIEBwYXJhbSByZWluaXRpYWxpemUgaW5kaWNhdGVzIHRoYXQgRWxpemEgc2hvdWxkIGJlIGluaXRpYWxpemVkIGFnYWluLCBldmVuIGlmIGl0J3MgZGF0YSBoYXMgYWxyZWFkeSBiZWVuIGluaXRpYWxpemVkXG4gICAqL1xuICBwdWJsaWMgc2V0dXAoZGF0YTogSUVsaXphRGF0YSwgcmVpbml0aWFsaXplID0gZmFsc2UpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuZGF0YSA9PT0gJ3VuZGVmaW5lZCcgfHwgcmVpbml0aWFsaXplKSB7XG4gICAgICB0aGlzLmluaXQoZGF0YSk7XG4gICAgfVxuICAgIHRoaXMucmVzZXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNldHMgRWxpemEuXG4gICAqL1xuICBwdWJsaWMgcmVzZXQoKTogdm9pZCB7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuZGF0YTtcbiAgICBpZiAodHlwZW9mIGRhdGEgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luaXRpYWxpemUgRWxpemEgZmlyc3QuJyk7XG4gICAgfVxuICAgIHRoaXMubWVtID0gW107XG4gICAgdGhpcy5sYXN0Q2hvaWNlID0gW107XG4gICAgZm9yIChsZXQgayA9IDA7IGsgPCBkYXRhLmtleXdvcmRzLmxlbmd0aDsgayArPSAxKSB7XG4gICAgICB0aGlzLmxhc3RDaG9pY2Vba10gPSBbXTtcbiAgICAgIGNvbnN0IHJ1bGVzID0gZGF0YS5rZXl3b3Jkc1trXS5ydWxlcztcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdGhpcy5sYXN0Q2hvaWNlW2tdW2ldID0gLTE7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMubWVzc2FnZXNTdWJqZWN0Lm5leHQoW3sgYm90OiB0cnVlLCB0ZXh0OiB0aGlzLmdldEluaXRpYWwoZGF0YSkgfV0pO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1saW5lcy1wZXItZnVuY3Rpb24sIGNvbXBsZXhpdHkgLS0gVE9ETyByZWZhY3RvclxuICBwcml2YXRlIGluaXQoZGF0YTogSUVsaXphRGF0YSk6IHZvaWQge1xuICAgIHRoaXMuZGF0YSA9IHsgLi4uZGF0YSB9O1xuICAgIC8vIFBhcnNlIGRhdGEgYW5kIGNvbnZlcnQgaXQgZnJvbSBjYW5vbmljYWwgZm9ybSB0byBpbnRlcm5hbCB1c2UuXG4gICAgLy8gUHJvZHVjZSBhIGxpc3Qgb2Ygc3lub255bXMuXG4gICAgY29uc3Qgc3luUGF0dGVybnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gaW4gdGhpcy5kYXRhLnN5bm9ueW1zKSB7XG4gICAgICBpZiAoaXRlbSkge1xuICAgICAgICBzeW5QYXR0ZXJuc1tpdGVtXSA9IGAoJHtpdGVtfXwke3RoaXMuZGF0YS5zeW5vbnltc1tpdGVtXS5qb2luKCd8Jyl9KWA7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIENoZWNrIGtleXdvcmRzLlxuICAgIGlmIChkYXRhLmtleXdvcmRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgRXJyb3IoJ0VsaXphIGRvZXMgbm90IGhhdmUgYW55IGNvbmZpZ3VyZWQga2V5d29yZHMuJyk7XG4gICAgfVxuICAgIC8vIEZpcnN0LCBjb252ZXJ0IHJ1bGVzIHRvIHJlZ2V4cHMuXG4gICAgLy8gRXhwYW5kIHN5bm9ueW1zIGFuZCBpbnNlcnQgYXN0ZXJpc2sgZXhwcmVzc2lvbnMgZm9yIGJhY2t0cmFja2luZy5cbiAgICBjb25zdCBzcmUgPSAvQChcXFMrKS87XG4gICAgY29uc3QgYXJlID0gLyhcXFMpXFxzKlxcKlxccyooXFxTKS87XG4gICAgY29uc3QgYXJlMSA9IC9eXFxzKlxcKlxccyooXFxTKS87XG4gICAgY29uc3QgYXJlMiA9IC8oXFxTKVxccypcXCpcXHMqJC87XG4gICAgY29uc3QgYXJlMyA9IC9eXFxzKlxcKlxccyokLztcbiAgICBjb25zdCB3c3JlID0gL1xccysvZztcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuZGF0YS5rZXl3b3Jkcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgY29uc3QgcnVsZXMgPSB0aGlzLmRhdGEua2V5d29yZHNbaV0ucnVsZXM7XG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHJ1bGVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgIGNvbnN0IHJ1bGUgPSBydWxlc1tqXTtcbiAgICAgICAgLy8gQ2hlY2sgbWVtIGZsYWcgYW5kIHN0b3JlIGl0IGFzIGRlY29tcCdzIGVsZW1lbnQgMi5cbiAgICAgICAgaWYgKHJ1bGUucGF0dGVybi5jaGFyQXQoMCkgPT09ICckJykge1xuICAgICAgICAgIGxldCBvZnMgPSAxO1xuICAgICAgICAgIHdoaWxlIChydWxlLnBhdHRlcm4uY2hhckF0KG9mcykgPT09ICcgJykge1xuICAgICAgICAgICAgb2ZzICs9IDE7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJ1bGUucGF0dGVybiA9IHJ1bGUucGF0dGVybi5zdWJzdHJpbmcob2ZzKTtcbiAgICAgICAgICBydWxlLm1lbW9yeSA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcnVsZS5tZW1vcnkgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbWF0Y2ggPSBydWxlLnBhdHRlcm4ubWF0Y2goc3JlKTtcbiAgICAgICAgd2hpbGUgKG1hdGNoICE9PSBudWxsKSB7XG4gICAgICAgICAgY29uc3Qgc3AgPSBzeW5QYXR0ZXJuc1ttYXRjaFsxXV0gPyBzeW5QYXR0ZXJuc1ttYXRjaFsxXV0gOiBtYXRjaFsxXTtcbiAgICAgICAgICBydWxlLnBhdHRlcm4gPSBydWxlLnBhdHRlcm4uc3Vic3RyaW5nKDAsIG1hdGNoLmluZGV4ID8/IDApICsgc3AgKyBydWxlLnBhdHRlcm4uc3Vic3RyaW5nKChtYXRjaC5pbmRleCA/PyAwKSArIG1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgICAgbWF0Y2ggPSBydWxlLnBhdHRlcm4ubWF0Y2goc3JlKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBFeHBhbmQgYXN0ZXJpc2sgZXhwcmVzc2lvbnMuXG4gICAgICAgIGlmIChhcmUzLnRlc3QocnVsZS5wYXR0ZXJuKSkge1xuICAgICAgICAgIHJ1bGUucGF0dGVybiA9ICdcXFxccyooLiopXFxcXHMqJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBtYXRjaCA9IHJ1bGUucGF0dGVybi5tYXRjaChhcmUpO1xuICAgICAgICAgIGlmIChtYXRjaCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGxlZnRQYXJ0ID0gJyc7XG4gICAgICAgICAgICBsZXQgcmlnaHRQYXJ0ID0gcnVsZS5wYXR0ZXJuO1xuICAgICAgICAgICAgd2hpbGUgKG1hdGNoICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIGxlZnRQYXJ0ICs9IHJpZ2h0UGFydC5zdWJzdHJpbmcoMCwgKG1hdGNoLmluZGV4ID8/IDApICsgMSk7XG4gICAgICAgICAgICAgIGlmIChtYXRjaFsxXSAhPT0gJyknKSB7XG4gICAgICAgICAgICAgICAgbGVmdFBhcnQgKz0gJ1xcXFxiJztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBsZWZ0UGFydCArPSAnXFxcXHMqKC4qKVxcXFxzKic7XG4gICAgICAgICAgICAgIGlmIChtYXRjaFsyXSAhPT0gJygnICYmIG1hdGNoWzJdICE9PSAnXFxcXCcpIHtcbiAgICAgICAgICAgICAgICBsZWZ0UGFydCArPSAnXFxcXGInO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGxlZnRQYXJ0ICs9IG1hdGNoWzJdO1xuICAgICAgICAgICAgICByaWdodFBhcnQgPSByaWdodFBhcnQuc3Vic3RyaW5nKChtYXRjaC5pbmRleCA/PyAwKSArIG1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgICAgICAgIG1hdGNoID0gcmlnaHRQYXJ0Lm1hdGNoKGFyZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBydWxlLnBhdHRlcm4gPSBsZWZ0UGFydCArIHJpZ2h0UGFydDtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWF0Y2ggPSBydWxlLnBhdHRlcm4ubWF0Y2goYXJlMSk7XG4gICAgICAgICAgaWYgKG1hdGNoICE9PSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgbGVmdFBhcnQgPSAnXFxcXHMqKC4qKVxcXFxzKic7XG4gICAgICAgICAgICBpZiAobWF0Y2hbMV0gIT09ICcpJyAmJiBtYXRjaFsxXSAhPT0gJ1xcXFwnKSB7XG4gICAgICAgICAgICAgIGxlZnRQYXJ0ICs9ICdcXFxcYic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBydWxlLnBhdHRlcm4gPSBsZWZ0UGFydCArIHJ1bGUucGF0dGVybi5zdWJzdHJpbmcoKG1hdGNoLmluZGV4ID8/IDApIC0gMSArIG1hdGNoWzBdLmxlbmd0aCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIG1hdGNoID0gcnVsZS5wYXR0ZXJuLm1hdGNoKGFyZTIpO1xuICAgICAgICAgIGlmIChtYXRjaCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IGxlZnRQYXJ0ID0gcnVsZS5wYXR0ZXJuLnN1YnN0cmluZygwLCAobWF0Y2guaW5kZXggPz8gMCkgKyAxKTtcbiAgICAgICAgICAgIGlmIChtYXRjaFsxXSAhPT0gJygnKSB7XG4gICAgICAgICAgICAgIGxlZnRQYXJ0ICs9ICdcXFxcYic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBydWxlLnBhdHRlcm4gPSBsZWZ0UGFydCArICdcXFxccyooLiopXFxcXHMqJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gRXhwYW5kIHdoaXRlc3BhY2VzLlxuICAgICAgICBydWxlLnBhdHRlcm4gPSBydWxlLnBhdHRlcm4ucmVwbGFjZSh3c3JlLCAnXFxcXHMrJyk7XG4gICAgICAgIHdzcmUubGFzdEluZGV4ID0gMDtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gU29ydCBrZXl3b3JkcyBieSByYW5rIChoaWdoZXN0IGZpcnN0KS5cbiAgICB0aGlzLmRhdGEua2V5d29yZHMuc29ydCh0aGlzLnNvcnRLZXl3b3Jkcyk7XG4gICAgLy8gQ29tcG9zZSByZWdleHBzIGFuZCByZWZzIGZvciBwcmVzIGFuZCBwb3N0cy5cbiAgICB0aGlzLmNvbXBvc2VSZWdFeHBzQW5kUHJlc0FuZFBvc3RzKHRoaXMuZGF0YSk7XG4gIH1cblxuICAvKipcbiAgICogQ29tcG9zZXMgcmVnZXhwcyBhbmQgcmVmcyBmb3IgcHJlcyBhbmQgcG9zdHMuXG4gICAqIEBwYXJhbSBkYXRhIEVsaXphIGRhdGFcbiAgICovXG4gIHByaXZhdGUgY29tcG9zZVJlZ0V4cHNBbmRQcmVzQW5kUG9zdHMoZGF0YTogSUVsaXphRGF0YSk6IHZvaWQge1xuICAgIHRoaXMucHJlcyA9IHt9O1xuICAgIHRoaXMucG9zdHMgPSB7fTtcbiAgICBpZiAoZGF0YS5wcmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgRXJyb3IoJ0VsaXphIGRvZXMgbm90IGhhdmUgYW55IGNvbmZpZ3VyZWQgcHJlIGV4cHJlc3Npb25zLicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEucHJlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgICBhLnB1c2goZGF0YS5wcmVzW2ldKTtcbiAgICAgICAgdGhpcy5wcmVzW2RhdGEucHJlc1tpXV0gPSBkYXRhLnByZXNbaSArIDFdO1xuICAgICAgfVxuICAgICAgdGhpcy5wcmVFeHAgPSBuZXcgUmVnRXhwKCdcXFxcYignICsgYS5qb2luKCd8JykgKyAnKVxcXFxiJyk7XG4gICAgfVxuICAgIGlmIChkYXRhLnBvc3RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgRXJyb3IoJ0VsaXphIGRvZXMgbm90IGhhdmUgYW55IGNvbmZpZ3VyZWQgcG9zdCBleHByZXNzaW9ucy4nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYSA9IFtdO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLnBvc3RzLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgIGEucHVzaChkYXRhLnBvc3RzW2ldKTtcbiAgICAgICAgdGhpcy5wb3N0c1tkYXRhLnBvc3RzW2ldXSA9IGRhdGEucG9zdHNbaSArIDFdO1xuICAgICAgfVxuICAgICAgdGhpcy5wb3N0RXhwID0gbmV3IFJlZ0V4cCgnXFxcXGIoJyArIGEuam9pbignfCcpICsgJylcXFxcYicpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGluZXMtcGVyLWZ1bmN0aW9uLCBjb21wbGV4aXR5IC0tIFRPRE8gcmVmYWN0b3JcbiAgcHJpdmF0ZSBleGVjUnVsZShkYXRhOiBJRWxpemFEYXRhLCBrOiBudW1iZXIsIHNlbnRlbmNlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGNvbmZpZyA9IHRoaXMuY29uZmlnU3ViamVjdC52YWx1ZTtcbiAgICBjb25zdCBydWxlcyA9IGRhdGEua2V5d29yZHNba10ucnVsZXM7XG4gICAgY29uc3QgcGFyYW1SZWdFeHAgPSAvXFwoKFswLTldKylcXCkvO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcnVsZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgIGNvbnN0IG1hdGNoID0gc2VudGVuY2UubWF0Y2gocnVsZXNbaV0ucGF0dGVybik7XG4gICAgICBpZiAobWF0Y2ggIT09IG51bGwpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IHJ1bGVzW2ldLm9wdGlvbnM7XG4gICAgICAgIGNvbnN0IG1lbW9yeSA9IHJ1bGVzW2ldLm1lbW9yeTtcbiAgICAgICAgbGV0IG9wdGlvbkluZGV4ID0gY29uZmlnLm5vUmFuZG9tID8gMCA6IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIG9wdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgaWYgKChjb25maWcubm9SYW5kb20gJiYgdGhpcy5sYXN0Q2hvaWNlW2tdW2ldID4gb3B0aW9uSW5kZXgpIHx8IHRoaXMubGFzdENob2ljZVtrXVtpXSA9PT0gb3B0aW9uSW5kZXgpIHtcbiAgICAgICAgICB0aGlzLmxhc3RDaG9pY2Vba11baV0gKz0gMTtcbiAgICAgICAgICBvcHRpb25JbmRleCA9IHRoaXMubGFzdENob2ljZVtrXVtpXTtcbiAgICAgICAgICBpZiAob3B0aW9uSW5kZXggPj0gb3B0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgICAgIG9wdGlvbkluZGV4ID0gMDtcbiAgICAgICAgICAgIHRoaXMubGFzdENob2ljZVtrXVtpXSA9IC0xO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmxhc3RDaG9pY2Vba11baV0gPSBvcHRpb25JbmRleDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVwbHkgPSBvcHRpb25zW29wdGlvbkluZGV4XTtcbiAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICAgIGNvbnN0IGRlYnVnTG9nID0gYG1hdGNoOlxcbmtleTogJHtkYXRhLmtleXdvcmRzW2tdLmtleX1cXG5yYW5rOiAke2RhdGEua2V5d29yZHNba10ucmFua31cXG5kZWNvbXA6ICR7cnVsZXNbaV0ucGF0dGVybn1cXG5yZWFzbWI6ICR7cmVwbHl9XFxubWVtb3J5OiAke21lbW9yeX1gO1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlIC0tIGRlYnVnIG91dHB1dFxuICAgICAgICAgIGNvbnNvbGUud2FybignZGVidWdMb2cnLCBkZWJ1Z0xvZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJlcGx5LnNlYXJjaCgnXmdvdG8gJykgPT09IDApIHtcbiAgICAgICAgICBjb25zdCBrZXkgPSByZXBseS5zdWJzdHJpbmcoNSk7XG4gICAgICAgICAgY29uc3Qga2kgPSB0aGlzLmdldFJ1bGVJbmRleEJ5S2V5KGRhdGEsIGtleSk7XG4gICAgICAgICAgaWYgKGtpID49IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV4ZWNSdWxlKGRhdGEsIGtpLCBzZW50ZW5jZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIFN1YnN0aXR1dGUgcG9zaXRpb25hbCBwYXJhbXMuXG4gICAgICAgIGxldCBwYXJhbVJlZ0V4cE1hdGNoID0gcmVwbHkubWF0Y2gocGFyYW1SZWdFeHApO1xuICAgICAgICBpZiAocGFyYW1SZWdFeHBNYXRjaCkge1xuICAgICAgICAgIGxldCBsZWZ0UGFydCA9ICcnO1xuICAgICAgICAgIGxldCByaWdodFBhcnQgPSByZXBseTtcbiAgICAgICAgICB3aGlsZSAocGFyYW1SZWdFeHBNYXRjaCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgbGV0IHBhcmFtID0gbWF0Y2hbcGFyc2VJbnQocGFyYW1SZWdFeHBNYXRjaFsxXSwgMTApXTtcbiAgICAgICAgICAgIC8vIFBvc3Rwcm9jZXNzIHBhcmFtLlxuICAgICAgICAgICAgbGV0IHBvc3RFeHBNYXRjaCA9IHBhcmFtLm1hdGNoKHRoaXMucG9zdEV4cCk7XG4gICAgICAgICAgICBpZiAocG9zdEV4cE1hdGNoICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgIGxldCBsZWZ0UGFydDIgPSAnJztcbiAgICAgICAgICAgICAgbGV0IHJpZ2h0UGFydDIgPSBwYXJhbTtcbiAgICAgICAgICAgICAgd2hpbGUgKHBvc3RFeHBNYXRjaCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGxlZnRQYXJ0MiArPSByaWdodFBhcnQyLnN1YnN0cmluZygwLCBwb3N0RXhwTWF0Y2guaW5kZXggPz8gMCkgKyB0aGlzLnBvc3RzW3Bvc3RFeHBNYXRjaFsxXV07XG4gICAgICAgICAgICAgICAgcmlnaHRQYXJ0MiA9IHJpZ2h0UGFydDIuc3Vic3RyaW5nKChwb3N0RXhwTWF0Y2guaW5kZXggPz8gMCkgKyBwb3N0RXhwTWF0Y2hbMF0ubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICBwb3N0RXhwTWF0Y2ggPSByaWdodFBhcnQyLm1hdGNoKHRoaXMucG9zdEV4cCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcGFyYW0gPSBsZWZ0UGFydDIgKyByaWdodFBhcnQyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGVmdFBhcnQgKz0gcmlnaHRQYXJ0LnN1YnN0cmluZygwLCBwYXJhbVJlZ0V4cE1hdGNoLmluZGV4KSArIHBhcmFtO1xuICAgICAgICAgICAgcmlnaHRQYXJ0ID0gcmlnaHRQYXJ0LnN1YnN0cmluZygocGFyYW1SZWdFeHBNYXRjaC5pbmRleCA/PyAwKSArIHBhcmFtUmVnRXhwTWF0Y2hbMF0ubGVuZ3RoKTtcbiAgICAgICAgICAgIHBhcmFtUmVnRXhwTWF0Y2ggPSByaWdodFBhcnQubWF0Y2gocGFyYW1SZWdFeHApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXBseSA9IGxlZnRQYXJ0ICsgcmlnaHRQYXJ0O1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkUmVwbHkgPSB0aGlzLnBvc3RUcmFuc2Zvcm0oZGF0YSwgcmVwbHkpO1xuICAgICAgICBpZiAobWVtb3J5KSB7XG4gICAgICAgICAgdGhpcy5tZW1TYXZlKHRyYW5zZm9ybWVkUmVwbHkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB0cmFuc2Zvcm1lZFJlcGx5O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5IC0tIFRPRE8gcmVmYWN0b3JcbiAgcHJpdmF0ZSB0cmFuc2Zvcm1Vc2VyUXVlcnkoZGF0YTogSUVsaXphRGF0YSwgaW5wdXQ6IHN0cmluZyk6IElFbGl6YVJlc3BvbnNlIHtcbiAgICBsZXQgcmVwbHkgPSAnJztcbiAgICAvLyBVbmlmeSB0ZXh0IHN0cmluZyBhbmQgc3BsaXQgdGV4dCBpbiBwYXJ0IHNlbnRlbmNlcyBhbmQgbG9vcCB0aHJvdWdoIHRoZW0uXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnNwbGl0VXNlclF1ZXJ5SW50b1BhcnRzKGlucHV0KTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICBsZXQgcGFydCA9IHBhcnRzW2ldO1xuICAgICAgaWYgKHBhcnQgIT09ICcnKSB7XG4gICAgICAgIC8vIENoZWNrIGZvciBxdWl0IGV4cHJlc3Npb25zLlxuICAgICAgICBmb3IgKGxldCBxID0gMDsgcSA8IGRhdGEucXVpdHMubGVuZ3RoOyBxICs9IDEpIHtcbiAgICAgICAgICBpZiAoZGF0YS5xdWl0c1txXSA9PT0gcGFydCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgcmVwbHk6IHRoaXMuZ2V0RmluYWwoZGF0YSksIGZpbmFsOiB0cnVlIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGxldCBtYXRjaCA9IHBhcnQubWF0Y2godGhpcy5wcmVFeHApO1xuICAgICAgICBpZiAobWF0Y2ggIT09IG51bGwpIHtcbiAgICAgICAgICBsZXQgbGVmdFBhcnQgPSAnJztcbiAgICAgICAgICBsZXQgcmlnaHRQYXJ0ID0gcGFydDtcbiAgICAgICAgICB3aGlsZSAobWF0Y2ggIT09IG51bGwpIHtcbiAgICAgICAgICAgIGxlZnRQYXJ0ICs9IHJpZ2h0UGFydC5zdWJzdHJpbmcoMCwgbWF0Y2guaW5kZXggPz8gMCkgKyB0aGlzLnByZXNbbWF0Y2hbMV1dO1xuICAgICAgICAgICAgcmlnaHRQYXJ0ID0gcmlnaHRQYXJ0LnN1YnN0cmluZygobWF0Y2guaW5kZXggPz8gMCkgKyBtYXRjaFswXS5sZW5ndGgpO1xuICAgICAgICAgICAgbWF0Y2ggPSByaWdodFBhcnQubWF0Y2godGhpcy5wcmVFeHApO1xuICAgICAgICAgIH1cbiAgICAgICAgICBwYXJ0ID0gbGVmdFBhcnQgKyByaWdodFBhcnQ7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTG9vcCB0cm91Z2gga2V5d29yZHMuXG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgZGF0YS5rZXl3b3Jkcy5sZW5ndGg7IGsgKz0gMSkge1xuICAgICAgICAgIGlmIChwYXJ0LnNlYXJjaChuZXcgUmVnRXhwKCdcXFxcYicgKyBkYXRhLmtleXdvcmRzW2tdLmtleSArICdcXFxcYicsICdpJykpID49IDApIHtcbiAgICAgICAgICAgIHJlcGx5ID0gdGhpcy5leGVjUnVsZShkYXRhLCBrLCBwYXJ0KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJlcGx5ICE9PSAnJykge1xuICAgICAgICAgICAgcmV0dXJuIHsgcmVwbHksIGZpbmFsOiBmYWxzZSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICAvLyBOb3RoaW5nIG1hdGNoZWQsIHRyeSBtZW0uXG4gICAgcmVwbHkgPSB0aGlzLm1lbUdldCgpO1xuICAgIC8vIElmIG5vdGhpbmcgaW4gbWVtLCB0cnkgeG5vbmUuXG4gICAgaWYgKHJlcGx5ID09PSAnJykge1xuICAgICAgY29uc3QgayA9IHRoaXMuZ2V0UnVsZUluZGV4QnlLZXkoZGF0YSwgJ3hub25lJyk7XG4gICAgICByZXBseSA9IGsgPj0gMCA/IHRoaXMuZXhlY1J1bGUoZGF0YSwgaywgJyAnKSA6IHJlcGx5O1xuICAgIH1cbiAgICByZXR1cm4geyByZXBseTogcmVwbHkgIT09ICcnID8gcmVwbHkgOiAnSSBhbSBhdCBhIGxvc3MgZm9yIHdvcmRzLicsIGZpbmFsOiBmYWxzZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFVuaWZ5IHRleHQgc3RyaW5nLCBzcGxpdCB0ZXh0IGludG8gcGFydGlhbCBzZW50ZW5jZXMgdG8gYmUgYWJsZSB0byBsb29wIHRocm91Z2ggdGhlbS5cbiAgICogQHBhcmFtIGlucHV0IHVzZXIgcXVlcnlcbiAgICogQHJldHVybnMgc3BsaXQgdXNlciBxdWVyeVxuICAgKi9cbiAgcHJpdmF0ZSBzcGxpdFVzZXJRdWVyeUludG9QYXJ0cyhpbnB1dDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHBhcnRzID0gaW5wdXRcbiAgICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgICAucmVwbGFjZSgvQCNcXCQlXFxeJlxcKlxcKFxcKV9cXCs9fmBcXHtcXFtcXH1cXF1cXHw6Ozw+XFwvXFxcXFxcdC9nLCAnICcpXG4gICAgICAucmVwbGFjZSgvXFxzKy0rXFxzKy9nLCAnLicpXG4gICAgICAucmVwbGFjZSgvXFxzKlssLj8hO10rXFxzKi9nLCAnLicpXG4gICAgICAucmVwbGFjZSgvXFxzKlxcYmJ1dFxcYlxccyovZywgJy4nKVxuICAgICAgLnJlcGxhY2UoL1xcc3syLH0vZywgJyAnKVxuICAgICAgLnNwbGl0KCcuJyk7XG4gICAgcmV0dXJuIHBhcnRzO1xuICB9XG5cbiAgcHJpdmF0ZSBzb3J0S2V5d29yZHMoYTogSUVsaXphS2V5d29yZCwgYjogSUVsaXphS2V5d29yZCkge1xuICAgIGlmIChhLnJhbmsgPiBiLnJhbmspIHtcbiAgICAgIHJldHVybiAtMTtcbiAgICB9IGVsc2UgaWYgKGEucmFuayA8IGIucmFuaykge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChhLmluZGV4ID4gYi5pbmRleCkge1xuICAgICAgcmV0dXJuIDE7XG4gICAgfSBlbHNlIGlmIChhLmluZGV4IDwgYi5pbmRleCkge1xuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHByaXZhdGUgcG9zdFRyYW5zZm9ybShkYXRhOiBJRWxpemFEYXRhLCBpbnB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBmaW5hbCBjbGVhbmluZ3NcbiAgICBsZXQgcmVzdWx0ID0gaW5wdXQucmVwbGFjZSgvXFxzezIsfS9nLCAnICcpLnJlcGxhY2UoL1xccytcXC4vZywgJy4nKTtcbiAgICBpZiAoZGF0YS5wb3N0VHJhbnNmb3Jtcy5sZW5ndGggPiAwKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGEucG9zdFRyYW5zZm9ybXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgY29uc3QgcG9zdFRyYW5zZm9ybSA9IGRhdGEucG9zdFRyYW5zZm9ybXNbaV07XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5yZXBsYWNlKHBvc3RUcmFuc2Zvcm0uc2VhcmNoVmFsdWUsIHBvc3RUcmFuc2Zvcm0ucmVwbGFjZVZhbHVlKTtcbiAgICAgICAgZGF0YS5wb3N0VHJhbnNmb3Jtc1tpXS5zZWFyY2hWYWx1ZS5sYXN0SW5kZXggPSAwO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5jb25maWdTdWJqZWN0LnZhbHVlLmNhcGl0YWxpemVGaXJzdExldHRlcikge1xuICAgICAgY29uc3QgbWF0Y2ggPSByZXN1bHQubWF0Y2goL14oW2Etel0pLyk7XG4gICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgcmVzdWx0ID0gbWF0Y2hbMF0udG9VcHBlckNhc2UoKSArIHJlc3VsdC5zdWJzdHJpbmcoMSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIGdldFJ1bGVJbmRleEJ5S2V5KGRhdGE6IElFbGl6YURhdGEsIGtleTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBmb3IgKGxldCBrID0gMDsgayA8IGRhdGEua2V5d29yZHMubGVuZ3RoOyBrICs9IDEpIHtcbiAgICAgIGlmIChkYXRhLmtleXdvcmRzW2tdLmtleSA9PT0ga2V5KSB7XG4gICAgICAgIHJldHVybiBrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICBwcml2YXRlIG1lbVNhdmUoaW5wdXQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubWVtLnB1c2goaW5wdXQpO1xuICAgIGlmICh0aGlzLm1lbS5sZW5ndGggPiB0aGlzLmNvbmZpZ1N1YmplY3QudmFsdWUubWVtU2l6ZSkge1xuICAgICAgdGhpcy5tZW0uc2hpZnQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1lbUdldCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLm1lbS5sZW5ndGggPiAwKSB7XG4gICAgICBpZiAodGhpcy5jb25maWdTdWJqZWN0LnZhbHVlLm5vUmFuZG9tKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm1lbS5zaGlmdCgpID8/ICcnO1xuICAgICAgfVxuICAgICAgY29uc3QgbiA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHRoaXMubWVtLmxlbmd0aCk7XG4gICAgICBjb25zdCByZXBseSA9IHRoaXMubWVtW25dO1xuICAgICAgZm9yIChsZXQgaSA9IG4gKyAxOyBpIDwgdGhpcy5tZW0ubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgdGhpcy5tZW1baSAtIDFdID0gdGhpcy5tZW1baV07XG4gICAgICB9XG4gICAgICB0aGlzLm1lbS5sZW5ndGggLT0gMTtcbiAgICAgIHJldHVybiByZXBseTtcbiAgICB9XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRGaW5hbChkYXRhOiBJRWxpemFEYXRhKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGF0YS5maW5hbHMubGVuZ3RoID09PSAwID8gZWxpemFGaW5hbERlZmF1bHQgOiBkYXRhLmZpbmFsc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBkYXRhLmZpbmFscy5sZW5ndGgpXTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SW5pdGlhbChkYXRhOiBJRWxpemFEYXRhKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZGF0YS5pbml0aWFscy5sZW5ndGggPT09IDAgPyBlbGl6YUluaXRpYWxEZWZhdWx0IDogZGF0YS5pbml0aWFsc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBkYXRhLmluaXRpYWxzLmxlbmd0aCldO1xuICB9XG5cbiAgcHVibGljIGdldFJlc3BvbnNlKHN0YXRlbWVudDogc3RyaW5nKTogUHJvbWlzZTxJRWxpemFSZXNwb25zZT4ge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmRhdGE7XG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbml0aWFsaXplIEVsaXphIGZpcnN0LicpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2U8SUVsaXphUmVzcG9uc2U+KHJlc29sdmUgPT4ge1xuICAgICAgY29uc3QgZWxpemFSZXBseSA9IHRoaXMudHJhbnNmb3JtVXNlclF1ZXJ5KGRhdGEsIHN0YXRlbWVudCk7XG4gICAgICByZXNvbHZlKGVsaXphUmVwbHkpO1xuICAgIH0pO1xuICB9XG59XG4iXX0=