@dodona/papyros 0.1.8-rc → 0.1.12-rc

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,556 @@
1
+ "use strict";
2
+ exports.id = 114;
3
+ exports.ids = [114];
4
+ exports.modules = {
5
+
6
+ /***/ 872:
7
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8
+
9
+
10
+ // EXPORTS
11
+ __webpack_require__.d(__webpack_exports__, {
12
+ "z": () => (/* binding */ Backend)
13
+ });
14
+
15
+ ;// CONCATENATED MODULE: ./src/ProgrammingLanguage.ts
16
+ var ProgrammingLanguage;
17
+ (function (ProgrammingLanguage) {
18
+ ProgrammingLanguage["Python"] = "Python";
19
+ ProgrammingLanguage["JavaScript"] = "JavaScript";
20
+ })(ProgrammingLanguage || (ProgrammingLanguage = {}));
21
+ var PROGRAMMING_LANGUAGES = [
22
+ ProgrammingLanguage.Python,
23
+ ProgrammingLanguage.JavaScript
24
+ ];
25
+ var LANGUAGE_MAP = new Map([
26
+ ["python", ProgrammingLanguage.Python],
27
+ ["javascript", ProgrammingLanguage.JavaScript]
28
+ ]);
29
+ function plFromString(language) {
30
+ var langLC = language.toLowerCase();
31
+ if (LANGUAGE_MAP.has(langLC)) {
32
+ return LANGUAGE_MAP.get(langLC);
33
+ }
34
+ else {
35
+ throw new Error("Unsupported language: " + language);
36
+ }
37
+ }
38
+
39
+ ;// CONCATENATED MODULE: ./src/Constants.ts
40
+
41
+ var MAIN_APP_ID = "papyros";
42
+ var OUTPUT_TA_ID = "code-output-area";
43
+ var INPUT_TA_ID = "code-input-area";
44
+ var EDITOR_WRAPPER_ID = "code-area";
45
+ var STATE_SPINNER_ID = "state-spinner";
46
+ var APPLICATION_STATE_TEXT_ID = "application-state-text";
47
+ var RUN_BTN_ID = "run-code-btn";
48
+ var TERMINATE_BTN_ID = "terminate-btn";
49
+ var PROGRAMMING_LANGUAGE_SELECT_ID = "programming-language-select";
50
+ var DEFAULT_PROGRAMMING_LANGUAGE = ProgrammingLanguage.Python;
51
+ var LOCALE_SELECT_ID = "locale-select";
52
+ var DEFAULT_LOCALE = "nl";
53
+ var INPUT_RELATIVE_URL = "/__papyros_input";
54
+ var SERVICE_WORKER_PATH = "./inputServiceWorker.js";
55
+
56
+ ;// CONCATENATED MODULE: ./src/util/Logging.ts
57
+ var __read = (undefined && undefined.__read) || function (o, n) {
58
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
59
+ if (!m) return o;
60
+ var i = m.call(o), r, ar = [], e;
61
+ try {
62
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
63
+ }
64
+ catch (error) { e = { error: error }; }
65
+ finally {
66
+ try {
67
+ if (r && !r.done && (m = i["return"])) m.call(i);
68
+ }
69
+ finally { if (e) throw e.error; }
70
+ }
71
+ return ar;
72
+ };
73
+ var __spreadArray = (undefined && undefined.__spreadArray) || function (to, from, pack) {
74
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
75
+ if (ar || !(i in from)) {
76
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
77
+ ar[i] = from[i];
78
+ }
79
+ }
80
+ return to.concat(ar || Array.prototype.slice.call(from));
81
+ };
82
+ var LogType;
83
+ (function (LogType) {
84
+ LogType[LogType["Debug"] = 0] = "Debug";
85
+ LogType[LogType["Error"] = 1] = "Error";
86
+ LogType[LogType["Important"] = 2] = "Important";
87
+ })(LogType || (LogType = {}));
88
+ var ENVIRONMENT = "production" || 0;
89
+ function papyrosLog(logType) {
90
+ var args = [];
91
+ for (var _i = 1; _i < arguments.length; _i++) {
92
+ args[_i - 1] = arguments[_i];
93
+ }
94
+ var doLog = ENVIRONMENT !== "production" || logType !== LogType.Debug;
95
+ if (doLog) {
96
+ if (logType === LogType.Error) {
97
+ console.error.apply(console, __spreadArray([], __read(args), false));
98
+ }
99
+ else {
100
+ console.log.apply(console, __spreadArray([], __read(args), false));
101
+ }
102
+ }
103
+ }
104
+
105
+ ;// CONCATENATED MODULE: ./src/Backend.ts
106
+ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _arguments, P, generator) {
107
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
108
+ return new (P || (P = Promise))(function (resolve, reject) {
109
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
110
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
111
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
112
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
113
+ });
114
+ };
115
+ var __generator = (undefined && undefined.__generator) || function (thisArg, body) {
116
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
117
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
118
+ function verb(n) { return function (v) { return step([n, v]); }; }
119
+ function step(op) {
120
+ if (f) throw new TypeError("Generator is already executing.");
121
+ while (_) try {
122
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
123
+ if (y = 0, t) op = [op[0] & 2, t.value];
124
+ switch (op[0]) {
125
+ case 0: case 1: t = op; break;
126
+ case 4: _.label++; return { value: op[1], done: false };
127
+ case 5: _.label++; y = op[1]; op = [0]; continue;
128
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
129
+ default:
130
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
131
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
132
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
133
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
134
+ if (t[2]) _.ops.pop();
135
+ _.trys.pop(); continue;
136
+ }
137
+ op = body.call(thisArg, _);
138
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
139
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
140
+ }
141
+ };
142
+
143
+
144
+ function getInputCallback(inputTextArray, inputMetaData) {
145
+ if (inputTextArray && inputMetaData) {
146
+ var textDecoder_1 = new TextDecoder();
147
+ return function () {
148
+ // eslint-disable-next-line no-constant-condition
149
+ while (true) {
150
+ if (Atomics.wait(inputMetaData, 0, 0, 100) === "timed-out") {
151
+ // papyrosLog.log("waiting on input");
152
+ // if (interruptBuffer[0] === 2) {
153
+ // return null;
154
+ // }
155
+ }
156
+ else {
157
+ break;
158
+ }
159
+ }
160
+ Atomics.store(inputMetaData, 0, 0);
161
+ var size = Atomics.exchange(inputMetaData, 1, 0);
162
+ var bytes = inputTextArray.slice(0, size);
163
+ return textDecoder_1.decode(bytes);
164
+ };
165
+ }
166
+ else {
167
+ return function () {
168
+ var request = new XMLHttpRequest();
169
+ do {
170
+ // `false` makes the request synchronous
171
+ request.open("GET", INPUT_RELATIVE_URL, false);
172
+ request.send(null);
173
+ } while (request.status >= 400); // todo better error handling
174
+ return request.responseText;
175
+ };
176
+ }
177
+ }
178
+ var Backend = /** @class */ (function () {
179
+ function Backend() {
180
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
181
+ this.onEvent = function () { };
182
+ this.runId = 0;
183
+ }
184
+ /**
185
+ * Initialize the backend, setting up any globals required
186
+ * @param {function(PapyrosEvent):void} onEvent Callback for when events occur
187
+ * @param {Uint8Array} inputTextArray Optional shared buffer for input
188
+ * @param {Int32Array} inputMetaData Optional shared buffer for metadata about input
189
+ * @return {Promise<void>} Promise of launching
190
+ */
191
+ Backend.prototype.launch = function (onEvent, inputTextArray, inputMetaData) {
192
+ var _this = this;
193
+ var inputCallback = getInputCallback(inputTextArray, inputMetaData);
194
+ this.onEvent = function (e) {
195
+ e.runId = _this.runId;
196
+ onEvent(e);
197
+ if (e.type === "input") {
198
+ return inputCallback();
199
+ }
200
+ };
201
+ return Promise.resolve();
202
+ };
203
+ /**
204
+ * Validate and run arbitrary code
205
+ * @param {string} code The code to run
206
+ * @param {string} runId The uuid for this execution
207
+ * @return {Promise<void>} Promise of execution
208
+ */
209
+ Backend.prototype.runCode = function (code, runId) {
210
+ return __awaiter(this, void 0, void 0, function () {
211
+ var data, error_1, errorString;
212
+ return __generator(this, function (_a) {
213
+ switch (_a.label) {
214
+ case 0:
215
+ this.runId = runId;
216
+ papyrosLog(LogType.Debug, "Running code in worker: ", code);
217
+ _a.label = 1;
218
+ case 1:
219
+ _a.trys.push([1, 3, , 4]);
220
+ return [4 /*yield*/, this._runCodeInternal(code)];
221
+ case 2:
222
+ data = _a.sent();
223
+ papyrosLog(LogType.Important, "ran code: " + code + " and received: ", data);
224
+ return [2 /*return*/, this.onEvent({ type: "success", data: data, runId: runId })];
225
+ case 3:
226
+ error_1 = _a.sent();
227
+ errorString = "toString" in error_1 ? error_1.toString() : JSON.stringify(error_1);
228
+ papyrosLog(LogType.Error, "Error during execution: ", error_1, errorString);
229
+ return [2 /*return*/, this.onEvent({ type: "error", data: errorString, runId: runId })];
230
+ case 4: return [2 /*return*/];
231
+ }
232
+ });
233
+ });
234
+ };
235
+ return Backend;
236
+ }());
237
+
238
+
239
+
240
+ /***/ }),
241
+
242
+ /***/ 375:
243
+ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
244
+
245
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
246
+ /* harmony export */ "Jj": () => (/* binding */ expose)
247
+ /* harmony export */ });
248
+ /* unused harmony exports createEndpoint, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap */
249
+ /**
250
+ * Copyright 2019 Google Inc. All Rights Reserved.
251
+ * Licensed under the Apache License, Version 2.0 (the "License");
252
+ * you may not use this file except in compliance with the License.
253
+ * You may obtain a copy of the License at
254
+ * http://www.apache.org/licenses/LICENSE-2.0
255
+ * Unless required by applicable law or agreed to in writing, software
256
+ * distributed under the License is distributed on an "AS IS" BASIS,
257
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
258
+ * See the License for the specific language governing permissions and
259
+ * limitations under the License.
260
+ */
261
+ const proxyMarker = Symbol("Comlink.proxy");
262
+ const createEndpoint = Symbol("Comlink.endpoint");
263
+ const releaseProxy = Symbol("Comlink.releaseProxy");
264
+ const throwMarker = Symbol("Comlink.thrown");
265
+ const isObject = (val) => (typeof val === "object" && val !== null) || typeof val === "function";
266
+ /**
267
+ * Internal transfer handle to handle objects marked to proxy.
268
+ */
269
+ const proxyTransferHandler = {
270
+ canHandle: (val) => isObject(val) && val[proxyMarker],
271
+ serialize(obj) {
272
+ const { port1, port2 } = new MessageChannel();
273
+ expose(obj, port1);
274
+ return [port2, [port2]];
275
+ },
276
+ deserialize(port) {
277
+ port.start();
278
+ return wrap(port);
279
+ },
280
+ };
281
+ /**
282
+ * Internal transfer handler to handle thrown exceptions.
283
+ */
284
+ const throwTransferHandler = {
285
+ canHandle: (value) => isObject(value) && throwMarker in value,
286
+ serialize({ value }) {
287
+ let serialized;
288
+ if (value instanceof Error) {
289
+ serialized = {
290
+ isError: true,
291
+ value: {
292
+ message: value.message,
293
+ name: value.name,
294
+ stack: value.stack,
295
+ },
296
+ };
297
+ }
298
+ else {
299
+ serialized = { isError: false, value };
300
+ }
301
+ return [serialized, []];
302
+ },
303
+ deserialize(serialized) {
304
+ if (serialized.isError) {
305
+ throw Object.assign(new Error(serialized.value.message), serialized.value);
306
+ }
307
+ throw serialized.value;
308
+ },
309
+ };
310
+ /**
311
+ * Allows customizing the serialization of certain values.
312
+ */
313
+ const transferHandlers = new Map([
314
+ ["proxy", proxyTransferHandler],
315
+ ["throw", throwTransferHandler],
316
+ ]);
317
+ function expose(obj, ep = self) {
318
+ ep.addEventListener("message", function callback(ev) {
319
+ if (!ev || !ev.data) {
320
+ return;
321
+ }
322
+ const { id, type, path } = Object.assign({ path: [] }, ev.data);
323
+ const argumentList = (ev.data.argumentList || []).map(fromWireValue);
324
+ let returnValue;
325
+ try {
326
+ const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);
327
+ const rawValue = path.reduce((obj, prop) => obj[prop], obj);
328
+ switch (type) {
329
+ case "GET" /* GET */:
330
+ {
331
+ returnValue = rawValue;
332
+ }
333
+ break;
334
+ case "SET" /* SET */:
335
+ {
336
+ parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);
337
+ returnValue = true;
338
+ }
339
+ break;
340
+ case "APPLY" /* APPLY */:
341
+ {
342
+ returnValue = rawValue.apply(parent, argumentList);
343
+ }
344
+ break;
345
+ case "CONSTRUCT" /* CONSTRUCT */:
346
+ {
347
+ const value = new rawValue(...argumentList);
348
+ returnValue = proxy(value);
349
+ }
350
+ break;
351
+ case "ENDPOINT" /* ENDPOINT */:
352
+ {
353
+ const { port1, port2 } = new MessageChannel();
354
+ expose(obj, port2);
355
+ returnValue = transfer(port1, [port1]);
356
+ }
357
+ break;
358
+ case "RELEASE" /* RELEASE */:
359
+ {
360
+ returnValue = undefined;
361
+ }
362
+ break;
363
+ default:
364
+ return;
365
+ }
366
+ }
367
+ catch (value) {
368
+ returnValue = { value, [throwMarker]: 0 };
369
+ }
370
+ Promise.resolve(returnValue)
371
+ .catch((value) => {
372
+ return { value, [throwMarker]: 0 };
373
+ })
374
+ .then((returnValue) => {
375
+ const [wireValue, transferables] = toWireValue(returnValue);
376
+ ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
377
+ if (type === "RELEASE" /* RELEASE */) {
378
+ // detach and deactive after sending release response above.
379
+ ep.removeEventListener("message", callback);
380
+ closeEndPoint(ep);
381
+ }
382
+ });
383
+ });
384
+ if (ep.start) {
385
+ ep.start();
386
+ }
387
+ }
388
+ function isMessagePort(endpoint) {
389
+ return endpoint.constructor.name === "MessagePort";
390
+ }
391
+ function closeEndPoint(endpoint) {
392
+ if (isMessagePort(endpoint))
393
+ endpoint.close();
394
+ }
395
+ function wrap(ep, target) {
396
+ return createProxy(ep, [], target);
397
+ }
398
+ function throwIfProxyReleased(isReleased) {
399
+ if (isReleased) {
400
+ throw new Error("Proxy has been released and is not useable");
401
+ }
402
+ }
403
+ function createProxy(ep, path = [], target = function () { }) {
404
+ let isProxyReleased = false;
405
+ const proxy = new Proxy(target, {
406
+ get(_target, prop) {
407
+ throwIfProxyReleased(isProxyReleased);
408
+ if (prop === releaseProxy) {
409
+ return () => {
410
+ return requestResponseMessage(ep, {
411
+ type: "RELEASE" /* RELEASE */,
412
+ path: path.map((p) => p.toString()),
413
+ }).then(() => {
414
+ closeEndPoint(ep);
415
+ isProxyReleased = true;
416
+ });
417
+ };
418
+ }
419
+ if (prop === "then") {
420
+ if (path.length === 0) {
421
+ return { then: () => proxy };
422
+ }
423
+ const r = requestResponseMessage(ep, {
424
+ type: "GET" /* GET */,
425
+ path: path.map((p) => p.toString()),
426
+ }).then(fromWireValue);
427
+ return r.then.bind(r);
428
+ }
429
+ return createProxy(ep, [...path, prop]);
430
+ },
431
+ set(_target, prop, rawValue) {
432
+ throwIfProxyReleased(isProxyReleased);
433
+ // FIXME: ES6 Proxy Handler `set` methods are supposed to return a
434
+ // boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
435
+ const [value, transferables] = toWireValue(rawValue);
436
+ return requestResponseMessage(ep, {
437
+ type: "SET" /* SET */,
438
+ path: [...path, prop].map((p) => p.toString()),
439
+ value,
440
+ }, transferables).then(fromWireValue);
441
+ },
442
+ apply(_target, _thisArg, rawArgumentList) {
443
+ throwIfProxyReleased(isProxyReleased);
444
+ const last = path[path.length - 1];
445
+ if (last === createEndpoint) {
446
+ return requestResponseMessage(ep, {
447
+ type: "ENDPOINT" /* ENDPOINT */,
448
+ }).then(fromWireValue);
449
+ }
450
+ // We just pretend that `bind()` didn’t happen.
451
+ if (last === "bind") {
452
+ return createProxy(ep, path.slice(0, -1));
453
+ }
454
+ const [argumentList, transferables] = processArguments(rawArgumentList);
455
+ return requestResponseMessage(ep, {
456
+ type: "APPLY" /* APPLY */,
457
+ path: path.map((p) => p.toString()),
458
+ argumentList,
459
+ }, transferables).then(fromWireValue);
460
+ },
461
+ construct(_target, rawArgumentList) {
462
+ throwIfProxyReleased(isProxyReleased);
463
+ const [argumentList, transferables] = processArguments(rawArgumentList);
464
+ return requestResponseMessage(ep, {
465
+ type: "CONSTRUCT" /* CONSTRUCT */,
466
+ path: path.map((p) => p.toString()),
467
+ argumentList,
468
+ }, transferables).then(fromWireValue);
469
+ },
470
+ });
471
+ return proxy;
472
+ }
473
+ function myFlat(arr) {
474
+ return Array.prototype.concat.apply([], arr);
475
+ }
476
+ function processArguments(argumentList) {
477
+ const processed = argumentList.map(toWireValue);
478
+ return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];
479
+ }
480
+ const transferCache = new WeakMap();
481
+ function transfer(obj, transfers) {
482
+ transferCache.set(obj, transfers);
483
+ return obj;
484
+ }
485
+ function proxy(obj) {
486
+ return Object.assign(obj, { [proxyMarker]: true });
487
+ }
488
+ function windowEndpoint(w, context = self, targetOrigin = "*") {
489
+ return {
490
+ postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),
491
+ addEventListener: context.addEventListener.bind(context),
492
+ removeEventListener: context.removeEventListener.bind(context),
493
+ };
494
+ }
495
+ function toWireValue(value) {
496
+ for (const [name, handler] of transferHandlers) {
497
+ if (handler.canHandle(value)) {
498
+ const [serializedValue, transferables] = handler.serialize(value);
499
+ return [
500
+ {
501
+ type: "HANDLER" /* HANDLER */,
502
+ name,
503
+ value: serializedValue,
504
+ },
505
+ transferables,
506
+ ];
507
+ }
508
+ }
509
+ return [
510
+ {
511
+ type: "RAW" /* RAW */,
512
+ value,
513
+ },
514
+ transferCache.get(value) || [],
515
+ ];
516
+ }
517
+ function fromWireValue(value) {
518
+ switch (value.type) {
519
+ case "HANDLER" /* HANDLER */:
520
+ return transferHandlers.get(value.name).deserialize(value.value);
521
+ case "RAW" /* RAW */:
522
+ return value.value;
523
+ }
524
+ }
525
+ function requestResponseMessage(ep, msg, transfers) {
526
+ return new Promise((resolve) => {
527
+ const id = generateUUID();
528
+ ep.addEventListener("message", function l(ev) {
529
+ if (!ev.data || !ev.data.id || ev.data.id !== id) {
530
+ return;
531
+ }
532
+ ep.removeEventListener("message", l);
533
+ resolve(ev.data);
534
+ });
535
+ if (ep.start) {
536
+ ep.start();
537
+ }
538
+ ep.postMessage(Object.assign({ id }, msg), transfers);
539
+ });
540
+ }
541
+ function generateUUID() {
542
+ return new Array(4)
543
+ .fill(0)
544
+ .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))
545
+ .join("-");
546
+ }
547
+
548
+
549
+ //# sourceMappingURL=comlink.mjs.map
550
+
551
+
552
+ /***/ })
553
+
554
+ };
555
+ ;
556
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsSUFBSTtBQUMzQyxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRXNIO0FBQ3RIIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vUGFweXJvcy8uL3NyYy9Qcm9ncmFtbWluZ0xhbmd1YWdlLnRzIiwid2VicGFjazovL1BhcHlyb3MvLi9zcmMvQ29uc3RhbnRzLnRzIiwid2VicGFjazovL1BhcHlyb3MvLi9zcmMvdXRpbC9Mb2dnaW5nLnRzIiwid2VicGFjazovL1BhcHlyb3MvLi9zcmMvQmFja2VuZC50cyIsIndlYnBhY2s6Ly9QYXB5cm9zLy4vbm9kZV9tb2R1bGVzL2NvbWxpbmsvZGlzdC9lc20vY29tbGluay5tanMiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGVudW0gUHJvZ3JhbW1pbmdMYW5ndWFnZSB7XG4gICAgUHl0aG9uID0gXCJQeXRob25cIixcbiAgICBKYXZhU2NyaXB0ID0gXCJKYXZhU2NyaXB0XCJcbn1cblxuZXhwb3J0IGNvbnN0IFBST0dSQU1NSU5HX0xBTkdVQUdFUyA9IFtcbiAgICBQcm9ncmFtbWluZ0xhbmd1YWdlLlB5dGhvbixcbiAgICBQcm9ncmFtbWluZ0xhbmd1YWdlLkphdmFTY3JpcHRcbl07XG5cbmNvbnN0IExBTkdVQUdFX01BUCA9IG5ldyBNYXAoW1xuICAgIFtcInB5dGhvblwiLCBQcm9ncmFtbWluZ0xhbmd1YWdlLlB5dGhvbl0sXG4gICAgW1wiamF2YXNjcmlwdFwiLCBQcm9ncmFtbWluZ0xhbmd1YWdlLkphdmFTY3JpcHRdXG5dKTtcblxuZXhwb3J0IGZ1bmN0aW9uIHBsRnJvbVN0cmluZyhsYW5ndWFnZTogc3RyaW5nKTogUHJvZ3JhbW1pbmdMYW5ndWFnZSB7XG4gICAgY29uc3QgbGFuZ0xDID0gbGFuZ3VhZ2UudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoTEFOR1VBR0VfTUFQLmhhcyhsYW5nTEMpKSB7XG4gICAgICAgIHJldHVybiBMQU5HVUFHRV9NQVAuZ2V0KGxhbmdMQykhO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgbGFuZ3VhZ2U6ICR7bGFuZ3VhZ2V9YCk7XG4gICAgfVxufVxuIiwiaW1wb3J0IHsgUHJvZ3JhbW1pbmdMYW5ndWFnZSB9IGZyb20gXCIuL1Byb2dyYW1taW5nTGFuZ3VhZ2VcIjtcblxuZXhwb3J0IGNvbnN0IE1BSU5fQVBQX0lEID0gXCJwYXB5cm9zXCI7XG5cbmV4cG9ydCBjb25zdCBPVVRQVVRfVEFfSUQgPSBcImNvZGUtb3V0cHV0LWFyZWFcIjtcbmV4cG9ydCBjb25zdCBJTlBVVF9UQV9JRCA9IFwiY29kZS1pbnB1dC1hcmVhXCI7XG5leHBvcnQgY29uc3QgRURJVE9SX1dSQVBQRVJfSUQgPSBcImNvZGUtYXJlYVwiO1xuXG5leHBvcnQgY29uc3QgU1RBVEVfU1BJTk5FUl9JRCA9IFwic3RhdGUtc3Bpbm5lclwiO1xuZXhwb3J0IGNvbnN0IEFQUExJQ0FUSU9OX1NUQVRFX1RFWFRfSUQgPSBcImFwcGxpY2F0aW9uLXN0YXRlLXRleHRcIjtcblxuZXhwb3J0IGNvbnN0IFJVTl9CVE5fSUQgPSBcInJ1bi1jb2RlLWJ0blwiO1xuZXhwb3J0IGNvbnN0IFRFUk1JTkFURV9CVE5fSUQgPSBcInRlcm1pbmF0ZS1idG5cIjtcblxuZXhwb3J0IGNvbnN0IFBST0dSQU1NSU5HX0xBTkdVQUdFX1NFTEVDVF9JRCA9IFwicHJvZ3JhbW1pbmctbGFuZ3VhZ2Utc2VsZWN0XCI7XG5leHBvcnQgY29uc3QgREVGQVVMVF9QUk9HUkFNTUlOR19MQU5HVUFHRSA9IFByb2dyYW1taW5nTGFuZ3VhZ2UuUHl0aG9uO1xuXG5leHBvcnQgY29uc3QgTE9DQUxFX1NFTEVDVF9JRCA9IFwibG9jYWxlLXNlbGVjdFwiO1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTE9DQUxFID0gXCJubFwiO1xuXG5leHBvcnQgY29uc3QgSU5QVVRfUkVMQVRJVkVfVVJMID0gXCIvX19wYXB5cm9zX2lucHV0XCI7XG5leHBvcnQgY29uc3QgU0VSVklDRV9XT1JLRVJfUEFUSCA9IFwiLi9pbnB1dFNlcnZpY2VXb3JrZXIuanNcIjtcbiIsImV4cG9ydCBlbnVtIExvZ1R5cGUge1xuICAgIERlYnVnLCBFcnJvciwgSW1wb3J0YW50XG59XG5cbmNvbnN0IEVOVklST05NRU5UOiBzdHJpbmcgPSBwcm9jZXNzLmVudi5OT0RFX0VOViB8fCBcImRldmVsb3BtZW50XCI7XG5leHBvcnQgZnVuY3Rpb24gcGFweXJvc0xvZyhsb2dUeXBlOiBMb2dUeXBlLCAuLi5hcmdzOiBhbnlbXSk6IHZvaWQge1xuICAgIGNvbnN0IGRvTG9nID0gRU5WSVJPTk1FTlQgIT09IFwicHJvZHVjdGlvblwiIHx8IGxvZ1R5cGUgIT09IExvZ1R5cGUuRGVidWc7XG4gICAgaWYgKGRvTG9nKSB7XG4gICAgICAgIGlmIChsb2dUeXBlID09PSBMb2dUeXBlLkVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKC4uLmFyZ3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coLi4uYXJncyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJpbXBvcnQgeyBJTlBVVF9SRUxBVElWRV9VUkwgfSBmcm9tIFwiLi9Db25zdGFudHNcIjtcbmltcG9ydCB7IFBhcHlyb3NFdmVudCB9IGZyb20gXCIuL1BhcHlyb3NFdmVudFwiO1xuaW1wb3J0IHsgTG9nVHlwZSwgcGFweXJvc0xvZyB9IGZyb20gXCIuL3V0aWwvTG9nZ2luZ1wiO1xuXG5mdW5jdGlvbiBnZXRJbnB1dENhbGxiYWNrKGlucHV0VGV4dEFycmF5PzogVWludDhBcnJheSwgaW5wdXRNZXRhRGF0YT86IEludDMyQXJyYXkpOiAoKSA9PiBzdHJpbmcge1xuICAgIGlmIChpbnB1dFRleHRBcnJheSAmJiBpbnB1dE1ldGFEYXRhKSB7XG4gICAgICAgIGNvbnN0IHRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCk7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc3RhbnQtY29uZGl0aW9uXG4gICAgICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgICAgICAgIGlmIChBdG9taWNzLndhaXQoaW5wdXRNZXRhRGF0YSwgMCwgMCwgMTAwKSA9PT0gXCJ0aW1lZC1vdXRcIikge1xuICAgICAgICAgICAgICAgICAgICAvLyBwYXB5cm9zTG9nLmxvZyhcIndhaXRpbmcgb24gaW5wdXRcIik7XG4gICAgICAgICAgICAgICAgICAgIC8vIGlmIChpbnRlcnJ1cHRCdWZmZXJbMF0gPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQXRvbWljcy5zdG9yZShpbnB1dE1ldGFEYXRhLCAwLCAwKTtcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSBBdG9taWNzLmV4Y2hhbmdlKGlucHV0TWV0YURhdGEsIDEsIDApO1xuICAgICAgICAgICAgY29uc3QgYnl0ZXMgPSBpbnB1dFRleHRBcnJheS5zbGljZSgwLCBzaXplKTtcbiAgICAgICAgICAgIHJldHVybiB0ZXh0RGVjb2Rlci5kZWNvZGUoYnl0ZXMpO1xuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgLy8gYGZhbHNlYCBtYWtlcyB0aGUgcmVxdWVzdCBzeW5jaHJvbm91c1xuICAgICAgICAgICAgICAgIHJlcXVlc3Qub3BlbihcIkdFVFwiLCBJTlBVVF9SRUxBVElWRV9VUkwsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICByZXF1ZXN0LnNlbmQobnVsbCk7XG4gICAgICAgICAgICB9IHdoaWxlIChyZXF1ZXN0LnN0YXR1cyA+PSA0MDApOyAvLyB0b2RvIGJldHRlciBlcnJvciBoYW5kbGluZ1xuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3QucmVzcG9uc2VUZXh0O1xuICAgICAgICB9O1xuICAgIH1cbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhY2tlbmQge1xuICAgIG9uRXZlbnQ6IChlOiBQYXB5cm9zRXZlbnQpID0+IGFueTtcbiAgICBydW5JZDogbnVtYmVyO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZW1wdHktZnVuY3Rpb25cbiAgICAgICAgdGhpcy5vbkV2ZW50ID0gKCkgPT4geyB9O1xuICAgICAgICB0aGlzLnJ1bklkID0gMDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIHRoZSBiYWNrZW5kLCBzZXR0aW5nIHVwIGFueSBnbG9iYWxzIHJlcXVpcmVkXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbihQYXB5cm9zRXZlbnQpOnZvaWR9IG9uRXZlbnQgQ2FsbGJhY2sgZm9yIHdoZW4gZXZlbnRzIG9jY3VyXG4gICAgICogQHBhcmFtIHtVaW50OEFycmF5fSBpbnB1dFRleHRBcnJheSBPcHRpb25hbCBzaGFyZWQgYnVmZmVyIGZvciBpbnB1dFxuICAgICAqIEBwYXJhbSB7SW50MzJBcnJheX0gaW5wdXRNZXRhRGF0YSBPcHRpb25hbCBzaGFyZWQgYnVmZmVyIGZvciBtZXRhZGF0YSBhYm91dCBpbnB1dFxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IFByb21pc2Ugb2YgbGF1bmNoaW5nXG4gICAgICovXG4gICAgbGF1bmNoKG9uRXZlbnQ6IChlOiBQYXB5cm9zRXZlbnQpID0+IHZvaWQsXG4gICAgICAgIGlucHV0VGV4dEFycmF5PzogVWludDhBcnJheSwgaW5wdXRNZXRhRGF0YT86IEludDMyQXJyYXkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgaW5wdXRDYWxsYmFjayA9IGdldElucHV0Q2FsbGJhY2soaW5wdXRUZXh0QXJyYXksIGlucHV0TWV0YURhdGEpO1xuICAgICAgICB0aGlzLm9uRXZlbnQgPSAoZTogUGFweXJvc0V2ZW50KSA9PiB7XG4gICAgICAgICAgICBlLnJ1bklkID0gdGhpcy5ydW5JZDtcbiAgICAgICAgICAgIG9uRXZlbnQoZSk7XG4gICAgICAgICAgICBpZiAoZS50eXBlID09PSBcImlucHV0XCIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaW5wdXRDYWxsYmFjaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgYWJzdHJhY3QgX3J1bkNvZGVJbnRlcm5hbChjb2RlOiBzdHJpbmcpOiBQcm9taXNlPGFueT47XG5cbiAgICAvKipcbiAgICAgKiBWYWxpZGF0ZSBhbmQgcnVuIGFyYml0cmFyeSBjb2RlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvZGUgVGhlIGNvZGUgdG8gcnVuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHJ1bklkIFRoZSB1dWlkIGZvciB0aGlzIGV4ZWN1dGlvblxuICAgICAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IFByb21pc2Ugb2YgZXhlY3V0aW9uXG4gICAgICovXG4gICAgYXN5bmMgcnVuQ29kZShjb2RlOiBzdHJpbmcsIHJ1bklkOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdGhpcy5ydW5JZCA9IHJ1bklkO1xuICAgICAgICBwYXB5cm9zTG9nKExvZ1R5cGUuRGVidWcsIFwiUnVubmluZyBjb2RlIGluIHdvcmtlcjogXCIsIGNvZGUpO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuX3J1bkNvZGVJbnRlcm5hbChjb2RlKTtcbiAgICAgICAgICAgIHBhcHlyb3NMb2coTG9nVHlwZS5JbXBvcnRhbnQsIFwicmFuIGNvZGU6IFwiICsgY29kZSArIFwiIGFuZCByZWNlaXZlZDogXCIsIGRhdGEpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMub25FdmVudCh7IHR5cGU6IFwic3VjY2Vzc1wiLCBkYXRhOiBkYXRhLCBydW5JZDogcnVuSWQgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yU3RyaW5nID0gXCJ0b1N0cmluZ1wiIGluIGVycm9yID8gZXJyb3IudG9TdHJpbmcoKSA6IEpTT04uc3RyaW5naWZ5KGVycm9yKTtcbiAgICAgICAgICAgIHBhcHlyb3NMb2coTG9nVHlwZS5FcnJvciwgXCJFcnJvciBkdXJpbmcgZXhlY3V0aW9uOiBcIiwgZXJyb3IsIGVycm9yU3RyaW5nKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9uRXZlbnQoeyB0eXBlOiBcImVycm9yXCIsIGRhdGE6IGVycm9yU3RyaW5nLCBydW5JZDogcnVuSWQgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcclxuICogQ29weXJpZ2h0IDIwMTkgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcclxuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxyXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcclxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxyXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXHJcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcclxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXHJcbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcclxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXHJcbiAqL1xyXG5jb25zdCBwcm94eU1hcmtlciA9IFN5bWJvbChcIkNvbWxpbmsucHJveHlcIik7XHJcbmNvbnN0IGNyZWF0ZUVuZHBvaW50ID0gU3ltYm9sKFwiQ29tbGluay5lbmRwb2ludFwiKTtcclxuY29uc3QgcmVsZWFzZVByb3h5ID0gU3ltYm9sKFwiQ29tbGluay5yZWxlYXNlUHJveHlcIik7XHJcbmNvbnN0IHRocm93TWFya2VyID0gU3ltYm9sKFwiQ29tbGluay50aHJvd25cIik7XHJcbmNvbnN0IGlzT2JqZWN0ID0gKHZhbCkgPT4gKHR5cGVvZiB2YWwgPT09IFwib2JqZWN0XCIgJiYgdmFsICE9PSBudWxsKSB8fCB0eXBlb2YgdmFsID09PSBcImZ1bmN0aW9uXCI7XHJcbi8qKlxyXG4gKiBJbnRlcm5hbCB0cmFuc2ZlciBoYW5kbGUgdG8gaGFuZGxlIG9iamVjdHMgbWFya2VkIHRvIHByb3h5LlxyXG4gKi9cclxuY29uc3QgcHJveHlUcmFuc2ZlckhhbmRsZXIgPSB7XHJcbiAgICBjYW5IYW5kbGU6ICh2YWwpID0+IGlzT2JqZWN0KHZhbCkgJiYgdmFsW3Byb3h5TWFya2VyXSxcclxuICAgIHNlcmlhbGl6ZShvYmopIHtcclxuICAgICAgICBjb25zdCB7IHBvcnQxLCBwb3J0MiB9ID0gbmV3IE1lc3NhZ2VDaGFubmVsKCk7XHJcbiAgICAgICAgZXhwb3NlKG9iaiwgcG9ydDEpO1xyXG4gICAgICAgIHJldHVybiBbcG9ydDIsIFtwb3J0Ml1dO1xyXG4gICAgfSxcclxuICAgIGRlc2VyaWFsaXplKHBvcnQpIHtcclxuICAgICAgICBwb3J0LnN0YXJ0KCk7XHJcbiAgICAgICAgcmV0dXJuIHdyYXAocG9ydCk7XHJcbiAgICB9LFxyXG59O1xyXG4vKipcclxuICogSW50ZXJuYWwgdHJhbnNmZXIgaGFuZGxlciB0byBoYW5kbGUgdGhyb3duIGV4Y2VwdGlvbnMuXHJcbiAqL1xyXG5jb25zdCB0aHJvd1RyYW5zZmVySGFuZGxlciA9IHtcclxuICAgIGNhbkhhbmRsZTogKHZhbHVlKSA9PiBpc09iamVjdCh2YWx1ZSkgJiYgdGhyb3dNYXJrZXIgaW4gdmFsdWUsXHJcbiAgICBzZXJpYWxpemUoeyB2YWx1ZSB9KSB7XHJcbiAgICAgICAgbGV0IHNlcmlhbGl6ZWQ7XHJcbiAgICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRXJyb3IpIHtcclxuICAgICAgICAgICAgc2VyaWFsaXplZCA9IHtcclxuICAgICAgICAgICAgICAgIGlzRXJyb3I6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB2YWx1ZToge1xyXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IHZhbHVlLm1lc3NhZ2UsXHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogdmFsdWUubmFtZSxcclxuICAgICAgICAgICAgICAgICAgICBzdGFjazogdmFsdWUuc3RhY2ssXHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgc2VyaWFsaXplZCA9IHsgaXNFcnJvcjogZmFsc2UsIHZhbHVlIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBbc2VyaWFsaXplZCwgW11dO1xyXG4gICAgfSxcclxuICAgIGRlc2VyaWFsaXplKHNlcmlhbGl6ZWQpIHtcclxuICAgICAgICBpZiAoc2VyaWFsaXplZC5pc0Vycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IE9iamVjdC5hc3NpZ24obmV3IEVycm9yKHNlcmlhbGl6ZWQudmFsdWUubWVzc2FnZSksIHNlcmlhbGl6ZWQudmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aHJvdyBzZXJpYWxpemVkLnZhbHVlO1xyXG4gICAgfSxcclxufTtcclxuLyoqXHJcbiAqIEFsbG93cyBjdXN0b21pemluZyB0aGUgc2VyaWFsaXphdGlvbiBvZiBjZXJ0YWluIHZhbHVlcy5cclxuICovXHJcbmNvbnN0IHRyYW5zZmVySGFuZGxlcnMgPSBuZXcgTWFwKFtcclxuICAgIFtcInByb3h5XCIsIHByb3h5VHJhbnNmZXJIYW5kbGVyXSxcclxuICAgIFtcInRocm93XCIsIHRocm93VHJhbnNmZXJIYW5kbGVyXSxcclxuXSk7XHJcbmZ1bmN0aW9uIGV4cG9zZShvYmosIGVwID0gc2VsZikge1xyXG4gICAgZXAuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgZnVuY3Rpb24gY2FsbGJhY2soZXYpIHtcclxuICAgICAgICBpZiAoIWV2IHx8ICFldi5kYXRhKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgeyBpZCwgdHlwZSwgcGF0aCB9ID0gT2JqZWN0LmFzc2lnbih7IHBhdGg6IFtdIH0sIGV2LmRhdGEpO1xyXG4gICAgICAgIGNvbnN0IGFyZ3VtZW50TGlzdCA9IChldi5kYXRhLmFyZ3VtZW50TGlzdCB8fCBbXSkubWFwKGZyb21XaXJlVmFsdWUpO1xyXG4gICAgICAgIGxldCByZXR1cm5WYWx1ZTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBwYXRoLnNsaWNlKDAsIC0xKS5yZWR1Y2UoKG9iaiwgcHJvcCkgPT4gb2JqW3Byb3BdLCBvYmopO1xyXG4gICAgICAgICAgICBjb25zdCByYXdWYWx1ZSA9IHBhdGgucmVkdWNlKChvYmosIHByb3ApID0+IG9ialtwcm9wXSwgb2JqKTtcclxuICAgICAgICAgICAgc3dpdGNoICh0eXBlKSB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiR0VUXCIgLyogR0VUICovOlxyXG4gICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSByYXdWYWx1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiU0VUXCIgLyogU0VUICovOlxyXG4gICAgICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50W3BhdGguc2xpY2UoLTEpWzBdXSA9IGZyb21XaXJlVmFsdWUoZXYuZGF0YS52YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiQVBQTFlcIiAvKiBBUFBMWSAqLzpcclxuICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gcmF3VmFsdWUuYXBwbHkocGFyZW50LCBhcmd1bWVudExpc3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJDT05TVFJVQ1RcIiAvKiBDT05TVFJVQ1QgKi86XHJcbiAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IG5ldyByYXdWYWx1ZSguLi5hcmd1bWVudExpc3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHByb3h5KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiRU5EUE9JTlRcIiAvKiBFTkRQT0lOVCAqLzpcclxuICAgICAgICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgcG9ydDEsIHBvcnQyIH0gPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwb3NlKG9iaiwgcG9ydDIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHRyYW5zZmVyKHBvcnQxLCBbcG9ydDFdKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFwiUkVMRUFTRVwiIC8qIFJFTEVBU0UgKi86XHJcbiAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5WYWx1ZSA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAodmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSB7IHZhbHVlLCBbdGhyb3dNYXJrZXJdOiAwIH07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFByb21pc2UucmVzb2x2ZShyZXR1cm5WYWx1ZSlcclxuICAgICAgICAgICAgLmNhdGNoKCh2YWx1ZSkgPT4ge1xyXG4gICAgICAgICAgICByZXR1cm4geyB2YWx1ZSwgW3Rocm93TWFya2VyXTogMCB9O1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgICAgIC50aGVuKChyZXR1cm5WYWx1ZSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBbd2lyZVZhbHVlLCB0cmFuc2ZlcmFibGVzXSA9IHRvV2lyZVZhbHVlKHJldHVyblZhbHVlKTtcclxuICAgICAgICAgICAgZXAucG9zdE1lc3NhZ2UoT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCB3aXJlVmFsdWUpLCB7IGlkIH0pLCB0cmFuc2ZlcmFibGVzKTtcclxuICAgICAgICAgICAgaWYgKHR5cGUgPT09IFwiUkVMRUFTRVwiIC8qIFJFTEVBU0UgKi8pIHtcclxuICAgICAgICAgICAgICAgIC8vIGRldGFjaCBhbmQgZGVhY3RpdmUgYWZ0ZXIgc2VuZGluZyByZWxlYXNlIHJlc3BvbnNlIGFib3ZlLlxyXG4gICAgICAgICAgICAgICAgZXAucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICAgICAgY2xvc2VFbmRQb2ludChlcCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG4gICAgaWYgKGVwLnN0YXJ0KSB7XHJcbiAgICAgICAgZXAuc3RhcnQoKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBpc01lc3NhZ2VQb3J0KGVuZHBvaW50KSB7XHJcbiAgICByZXR1cm4gZW5kcG9pbnQuY29uc3RydWN0b3IubmFtZSA9PT0gXCJNZXNzYWdlUG9ydFwiO1xyXG59XHJcbmZ1bmN0aW9uIGNsb3NlRW5kUG9pbnQoZW5kcG9pbnQpIHtcclxuICAgIGlmIChpc01lc3NhZ2VQb3J0KGVuZHBvaW50KSlcclxuICAgICAgICBlbmRwb2ludC5jbG9zZSgpO1xyXG59XHJcbmZ1bmN0aW9uIHdyYXAoZXAsIHRhcmdldCkge1xyXG4gICAgcmV0dXJuIGNyZWF0ZVByb3h5KGVwLCBbXSwgdGFyZ2V0KTtcclxufVxyXG5mdW5jdGlvbiB0aHJvd0lmUHJveHlSZWxlYXNlZChpc1JlbGVhc2VkKSB7XHJcbiAgICBpZiAoaXNSZWxlYXNlZCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlByb3h5IGhhcyBiZWVuIHJlbGVhc2VkIGFuZCBpcyBub3QgdXNlYWJsZVwiKTtcclxuICAgIH1cclxufVxyXG5mdW5jdGlvbiBjcmVhdGVQcm94eShlcCwgcGF0aCA9IFtdLCB0YXJnZXQgPSBmdW5jdGlvbiAoKSB7IH0pIHtcclxuICAgIGxldCBpc1Byb3h5UmVsZWFzZWQgPSBmYWxzZTtcclxuICAgIGNvbnN0IHByb3h5ID0gbmV3IFByb3h5KHRhcmdldCwge1xyXG4gICAgICAgIGdldChfdGFyZ2V0LCBwcm9wKSB7XHJcbiAgICAgICAgICAgIHRocm93SWZQcm94eVJlbGVhc2VkKGlzUHJveHlSZWxlYXNlZCk7XHJcbiAgICAgICAgICAgIGlmIChwcm9wID09PSByZWxlYXNlUHJveHkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RSZXNwb25zZU1lc3NhZ2UoZXAsIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJSRUxFQVNFXCIgLyogUkVMRUFTRSAqLyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGF0aDogcGF0aC5tYXAoKHApID0+IHAudG9TdHJpbmcoKSksXHJcbiAgICAgICAgICAgICAgICAgICAgfSkudGhlbigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsb3NlRW5kUG9pbnQoZXApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc1Byb3h5UmVsZWFzZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAocHJvcCA9PT0gXCJ0aGVuXCIpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IHRoZW46ICgpID0+IHByb3h5IH07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBjb25zdCByID0gcmVxdWVzdFJlc3BvbnNlTWVzc2FnZShlcCwge1xyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwiR0VUXCIgLyogR0VUICovLFxyXG4gICAgICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgubWFwKChwKSA9PiBwLnRvU3RyaW5nKCkpLFxyXG4gICAgICAgICAgICAgICAgfSkudGhlbihmcm9tV2lyZVZhbHVlKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByLnRoZW4uYmluZChyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlUHJveHkoZXAsIFsuLi5wYXRoLCBwcm9wXSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBzZXQoX3RhcmdldCwgcHJvcCwgcmF3VmFsdWUpIHtcclxuICAgICAgICAgICAgdGhyb3dJZlByb3h5UmVsZWFzZWQoaXNQcm94eVJlbGVhc2VkKTtcclxuICAgICAgICAgICAgLy8gRklYTUU6IEVTNiBQcm94eSBIYW5kbGVyIGBzZXRgIG1ldGhvZHMgYXJlIHN1cHBvc2VkIHRvIHJldHVybiBhXHJcbiAgICAgICAgICAgIC8vIGJvb2xlYW4uIFRvIHNob3cgZ29vZCB3aWxsLCB3ZSByZXR1cm4gdHJ1ZSBhc3luY2hyb25vdXNseSDCr1xcXyjjg4QpXy/Cr1xyXG4gICAgICAgICAgICBjb25zdCBbdmFsdWUsIHRyYW5zZmVyYWJsZXNdID0gdG9XaXJlVmFsdWUocmF3VmFsdWUpO1xyXG4gICAgICAgICAgICByZXR1cm4gcmVxdWVzdFJlc3BvbnNlTWVzc2FnZShlcCwge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogXCJTRVRcIiAvKiBTRVQgKi8sXHJcbiAgICAgICAgICAgICAgICBwYXRoOiBbLi4ucGF0aCwgcHJvcF0ubWFwKChwKSA9PiBwLnRvU3RyaW5nKCkpLFxyXG4gICAgICAgICAgICAgICAgdmFsdWUsXHJcbiAgICAgICAgICAgIH0sIHRyYW5zZmVyYWJsZXMpLnRoZW4oZnJvbVdpcmVWYWx1ZSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBhcHBseShfdGFyZ2V0LCBfdGhpc0FyZywgcmF3QXJndW1lbnRMaXN0KSB7XHJcbiAgICAgICAgICAgIHRocm93SWZQcm94eVJlbGVhc2VkKGlzUHJveHlSZWxlYXNlZCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGxhc3QgPSBwYXRoW3BhdGgubGVuZ3RoIC0gMV07XHJcbiAgICAgICAgICAgIGlmIChsYXN0ID09PSBjcmVhdGVFbmRwb2ludCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RSZXNwb25zZU1lc3NhZ2UoZXAsIHtcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIkVORFBPSU5UXCIgLyogRU5EUE9JTlQgKi8sXHJcbiAgICAgICAgICAgICAgICB9KS50aGVuKGZyb21XaXJlVmFsdWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFdlIGp1c3QgcHJldGVuZCB0aGF0IGBiaW5kKClgIGRpZG7igJl0IGhhcHBlbi5cclxuICAgICAgICAgICAgaWYgKGxhc3QgPT09IFwiYmluZFwiKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlUHJveHkoZXAsIHBhdGguc2xpY2UoMCwgLTEpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb25zdCBbYXJndW1lbnRMaXN0LCB0cmFuc2ZlcmFibGVzXSA9IHByb2Nlc3NBcmd1bWVudHMocmF3QXJndW1lbnRMaXN0KTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RSZXNwb25zZU1lc3NhZ2UoZXAsIHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IFwiQVBQTFlcIiAvKiBBUFBMWSAqLyxcclxuICAgICAgICAgICAgICAgIHBhdGg6IHBhdGgubWFwKChwKSA9PiBwLnRvU3RyaW5nKCkpLFxyXG4gICAgICAgICAgICAgICAgYXJndW1lbnRMaXN0LFxyXG4gICAgICAgICAgICB9LCB0cmFuc2ZlcmFibGVzKS50aGVuKGZyb21XaXJlVmFsdWUpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY29uc3RydWN0KF90YXJnZXQsIHJhd0FyZ3VtZW50TGlzdCkge1xyXG4gICAgICAgICAgICB0aHJvd0lmUHJveHlSZWxlYXNlZChpc1Byb3h5UmVsZWFzZWQpO1xyXG4gICAgICAgICAgICBjb25zdCBbYXJndW1lbnRMaXN0LCB0cmFuc2ZlcmFibGVzXSA9IHByb2Nlc3NBcmd1bWVudHMocmF3QXJndW1lbnRMaXN0KTtcclxuICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RSZXNwb25zZU1lc3NhZ2UoZXAsIHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IFwiQ09OU1RSVUNUXCIgLyogQ09OU1RSVUNUICovLFxyXG4gICAgICAgICAgICAgICAgcGF0aDogcGF0aC5tYXAoKHApID0+IHAudG9TdHJpbmcoKSksXHJcbiAgICAgICAgICAgICAgICBhcmd1bWVudExpc3QsXHJcbiAgICAgICAgICAgIH0sIHRyYW5zZmVyYWJsZXMpLnRoZW4oZnJvbVdpcmVWYWx1ZSk7XHJcbiAgICAgICAgfSxcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIHByb3h5O1xyXG59XHJcbmZ1bmN0aW9uIG15RmxhdChhcnIpIHtcclxuICAgIHJldHVybiBBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KFtdLCBhcnIpO1xyXG59XHJcbmZ1bmN0aW9uIHByb2Nlc3NBcmd1bWVudHMoYXJndW1lbnRMaXN0KSB7XHJcbiAgICBjb25zdCBwcm9jZXNzZWQgPSBhcmd1bWVudExpc3QubWFwKHRvV2lyZVZhbHVlKTtcclxuICAgIHJldHVybiBbcHJvY2Vzc2VkLm1hcCgodikgPT4gdlswXSksIG15RmxhdChwcm9jZXNzZWQubWFwKCh2KSA9PiB2WzFdKSldO1xyXG59XHJcbmNvbnN0IHRyYW5zZmVyQ2FjaGUgPSBuZXcgV2Vha01hcCgpO1xyXG5mdW5jdGlvbiB0cmFuc2ZlcihvYmosIHRyYW5zZmVycykge1xyXG4gICAgdHJhbnNmZXJDYWNoZS5zZXQob2JqLCB0cmFuc2ZlcnMpO1xyXG4gICAgcmV0dXJuIG9iajtcclxufVxyXG5mdW5jdGlvbiBwcm94eShvYmopIHtcclxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKG9iaiwgeyBbcHJveHlNYXJrZXJdOiB0cnVlIH0pO1xyXG59XHJcbmZ1bmN0aW9uIHdpbmRvd0VuZHBvaW50KHcsIGNvbnRleHQgPSBzZWxmLCB0YXJnZXRPcmlnaW4gPSBcIipcIikge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgICBwb3N0TWVzc2FnZTogKG1zZywgdHJhbnNmZXJhYmxlcykgPT4gdy5wb3N0TWVzc2FnZShtc2csIHRhcmdldE9yaWdpbiwgdHJhbnNmZXJhYmxlcyksXHJcbiAgICAgICAgYWRkRXZlbnRMaXN0ZW5lcjogY29udGV4dC5hZGRFdmVudExpc3RlbmVyLmJpbmQoY29udGV4dCksXHJcbiAgICAgICAgcmVtb3ZlRXZlbnRMaXN0ZW5lcjogY29udGV4dC5yZW1vdmVFdmVudExpc3RlbmVyLmJpbmQoY29udGV4dCksXHJcbiAgICB9O1xyXG59XHJcbmZ1bmN0aW9uIHRvV2lyZVZhbHVlKHZhbHVlKSB7XHJcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBoYW5kbGVyXSBvZiB0cmFuc2ZlckhhbmRsZXJzKSB7XHJcbiAgICAgICAgaWYgKGhhbmRsZXIuY2FuSGFuZGxlKHZhbHVlKSkge1xyXG4gICAgICAgICAgICBjb25zdCBbc2VyaWFsaXplZFZhbHVlLCB0cmFuc2ZlcmFibGVzXSA9IGhhbmRsZXIuc2VyaWFsaXplKHZhbHVlKTtcclxuICAgICAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIkhBTkRMRVJcIiAvKiBIQU5ETEVSICovLFxyXG4gICAgICAgICAgICAgICAgICAgIG5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHNlcmlhbGl6ZWRWYWx1ZSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB0cmFuc2ZlcmFibGVzLFxyXG4gICAgICAgICAgICBdO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgICB0eXBlOiBcIlJBV1wiIC8qIFJBVyAqLyxcclxuICAgICAgICAgICAgdmFsdWUsXHJcbiAgICAgICAgfSxcclxuICAgICAgICB0cmFuc2ZlckNhY2hlLmdldCh2YWx1ZSkgfHwgW10sXHJcbiAgICBdO1xyXG59XHJcbmZ1bmN0aW9uIGZyb21XaXJlVmFsdWUodmFsdWUpIHtcclxuICAgIHN3aXRjaCAodmFsdWUudHlwZSkge1xyXG4gICAgICAgIGNhc2UgXCJIQU5ETEVSXCIgLyogSEFORExFUiAqLzpcclxuICAgICAgICAgICAgcmV0dXJuIHRyYW5zZmVySGFuZGxlcnMuZ2V0KHZhbHVlLm5hbWUpLmRlc2VyaWFsaXplKHZhbHVlLnZhbHVlKTtcclxuICAgICAgICBjYXNlIFwiUkFXXCIgLyogUkFXICovOlxyXG4gICAgICAgICAgICByZXR1cm4gdmFsdWUudmFsdWU7XHJcbiAgICB9XHJcbn1cclxuZnVuY3Rpb24gcmVxdWVzdFJlc3BvbnNlTWVzc2FnZShlcCwgbXNnLCB0cmFuc2ZlcnMpIHtcclxuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGlkID0gZ2VuZXJhdGVVVUlEKCk7XHJcbiAgICAgICAgZXAuYWRkRXZlbnRMaXN0ZW5lcihcIm1lc3NhZ2VcIiwgZnVuY3Rpb24gbChldikge1xyXG4gICAgICAgICAgICBpZiAoIWV2LmRhdGEgfHwgIWV2LmRhdGEuaWQgfHwgZXYuZGF0YS5pZCAhPT0gaWQpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlcC5yZW1vdmVFdmVudExpc3RlbmVyKFwibWVzc2FnZVwiLCBsKTtcclxuICAgICAgICAgICAgcmVzb2x2ZShldi5kYXRhKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAoZXAuc3RhcnQpIHtcclxuICAgICAgICAgICAgZXAuc3RhcnQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZXAucG9zdE1lc3NhZ2UoT2JqZWN0LmFzc2lnbih7IGlkIH0sIG1zZyksIHRyYW5zZmVycyk7XHJcbiAgICB9KTtcclxufVxyXG5mdW5jdGlvbiBnZW5lcmF0ZVVVSUQoKSB7XHJcbiAgICByZXR1cm4gbmV3IEFycmF5KDQpXHJcbiAgICAgICAgLmZpbGwoMClcclxuICAgICAgICAubWFwKCgpID0+IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKS50b1N0cmluZygxNikpXHJcbiAgICAgICAgLmpvaW4oXCItXCIpO1xyXG59XG5cbmV4cG9ydCB7IGNyZWF0ZUVuZHBvaW50LCBleHBvc2UsIHByb3h5LCBwcm94eU1hcmtlciwgcmVsZWFzZVByb3h5LCB0cmFuc2ZlciwgdHJhbnNmZXJIYW5kbGVycywgd2luZG93RW5kcG9pbnQsIHdyYXAgfTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbWxpbmsubWpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9