@sdkgen/node-runtime 0.0.0-dev.20230106165109 → 0.0.0-dev.20230109134521

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 (41) hide show
  1. package/dist/spec/error.spec.js +3 -4
  2. package/dist/spec/rest/rest.spec.js +24 -24
  3. package/dist/spec/runtime/errors.spec.js +15 -14
  4. package/dist/spec/runtime/middleware.spec.js +15 -14
  5. package/dist/spec/simple/legacyNodeClient.js +6 -32
  6. package/dist/spec/simple/simple.spec.js +27 -28
  7. package/dist/spec/types.js +27 -28
  8. package/dist/spec/types.spec.js +54 -55
  9. package/dist/src/api-config.js +4 -8
  10. package/dist/src/context.js +2 -2
  11. package/dist/src/encode-decode.js +12 -50
  12. package/dist/src/error.js +4 -9
  13. package/dist/src/execute.js +12 -14
  14. package/dist/src/http-client.js +25 -27
  15. package/dist/src/http-server.js +160 -170
  16. package/dist/src/index.js +8 -18
  17. package/dist/src/new-interface.js +200 -0
  18. package/dist/src/swagger.js +126 -115
  19. package/dist/src/test-wrapper.js +25 -23
  20. package/dist/src/utils.js +2 -5
  21. package/package.json +27 -22
  22. package/dist/spec/error.spec.d.ts +0 -1
  23. package/dist/spec/rest/rest.spec.d.ts +0 -1
  24. package/dist/spec/runtime/errors.spec.d.ts +0 -1
  25. package/dist/spec/runtime/middleware.spec.d.ts +0 -1
  26. package/dist/spec/simple/legacyNodeClient.d.ts +0 -17
  27. package/dist/spec/simple/simple.spec.d.ts +0 -1
  28. package/dist/spec/types.d.ts +0 -1
  29. package/dist/spec/types.spec.d.ts +0 -1
  30. package/dist/src/api-config.d.ts +0 -15
  31. package/dist/src/context.d.ts +0 -38
  32. package/dist/src/encode-decode.d.ts +0 -32
  33. package/dist/src/error.d.ts +0 -18
  34. package/dist/src/execute.d.ts +0 -3
  35. package/dist/src/http-client.d.ts +0 -17
  36. package/dist/src/http-server.d.ts +0 -37
  37. package/dist/src/index.d.ts +0 -7
  38. package/dist/src/swagger.d.ts +0 -2
  39. package/dist/src/test-wrapper.d.ts +0 -3
  40. package/dist/src/utils.d.ts +0 -6
  41. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,36 +1,29 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SdkgenHttpServer = void 0;
7
- const crypto_1 = require("crypto");
8
- const fs_1 = require("fs");
9
- const http_1 = require("http");
10
- const os_1 = require("os");
11
- const querystring_1 = require("querystring");
12
- const url_1 = require("url");
13
- const util_1 = require("util");
14
- const csharp_generator_1 = require("@sdkgen/csharp-generator");
15
- const dart_generator_1 = require("@sdkgen/dart-generator");
16
- const fsharp_generator_1 = require("@sdkgen/fsharp-generator");
17
- const kotlin_generator_1 = require("@sdkgen/kotlin-generator");
18
- const parser_1 = require("@sdkgen/parser");
19
- const playground_1 = require("@sdkgen/playground");
20
- const swift_generator_1 = require("@sdkgen/swift-generator");
21
- const typescript_generator_1 = require("@sdkgen/typescript-generator");
22
- const busboy_1 = __importDefault(require("busboy"));
23
- const file_type_1 = __importDefault(require("file-type"));
24
- const request_ip_1 = require("request-ip");
25
- const serve_handler_1 = __importDefault(require("serve-handler"));
26
- const encode_decode_1 = require("./encode-decode");
27
- const error_1 = require("./error");
28
- const execute_1 = require("./execute");
29
- const swagger_1 = require("./swagger");
30
- const utils_1 = require("./utils");
31
- class SdkgenHttpServer {
1
+ import { randomBytes } from "crypto";
2
+ import { createReadStream, createWriteStream, unlink } from "fs";
3
+ import { createServer } from "http";
4
+ import { hostname } from "os";
5
+ import { parse as parseQuerystring } from "querystring";
6
+ import { parse as parseUrl } from "url";
7
+ import { promisify } from "util";
8
+ import { generateCSharpServerSource } from "@sdkgen/csharp-generator";
9
+ import { generateDartClientSource } from "@sdkgen/dart-generator";
10
+ import { generateFSharpServerSource } from "@sdkgen/fsharp-generator";
11
+ import { generateAndroidClientSource } from "@sdkgen/kotlin-generator";
12
+ import { DecimalPrimitiveType, Base64PrimitiveType, BigIntPrimitiveType, BoolPrimitiveType, BytesPrimitiveType, CnpjPrimitiveType, CpfPrimitiveType, DatePrimitiveType, DateTimePrimitiveType, FloatPrimitiveType, HexPrimitiveType, HtmlPrimitiveType, IntPrimitiveType, MoneyPrimitiveType, OptionalType, RestAnnotation, StringPrimitiveType, UIntPrimitiveType, UuidPrimitiveType, VoidPrimitiveType, XmlPrimitiveType, } from "@sdkgen/parser";
13
+ import { PLAYGROUND_PUBLIC_PATH } from "@sdkgen/playground";
14
+ import { generateSwiftClientSource } from "@sdkgen/swift-generator";
15
+ import { generateBrowserClientSource, generateNodeClientSource, generateNodeServerSource } from "@sdkgen/typescript-generator";
16
+ import Busboy from "busboy";
17
+ import { fileTypeFromBuffer } from "file-type";
18
+ import { getClientIp } from "request-ip";
19
+ import staticFilesHandler from "serve-handler";
20
+ import { decode, encode } from "./encode-decode.js";
21
+ import { Fatal } from "./error.js";
22
+ import { executeRequest } from "./execute.js";
23
+ import { setupSwagger } from "./swagger.js";
24
+ import { has } from "./utils.js";
25
+ export class SdkgenHttpServer {
32
26
  constructor(apiConfig, ...maybeExtraContext) {
33
- var _a;
34
27
  this.apiConfig = apiConfig;
35
28
  this.headers = new Map();
36
29
  this.healthChecks = [];
@@ -71,7 +64,7 @@ class SdkgenHttpServer {
71
64
  this.handleRequestWithBody(req, res, body, hrStart).catch((e) => this.writeReply(res, null, { error: e }, hrStart));
72
65
  };
73
66
  // Google Cloud Functions add a rawBody property to the request object
74
- if ((0, utils_1.has)(req, "rawBody") && req.rawBody instanceof Buffer) {
67
+ if (has(req, "rawBody") && req.rawBody instanceof Buffer) {
75
68
  handleBody(req.rawBody);
76
69
  }
77
70
  else {
@@ -83,21 +76,21 @@ class SdkgenHttpServer {
83
76
  });
84
77
  }
85
78
  };
86
- this.extraContext = ((_a = maybeExtraContext[0]) !== null && _a !== void 0 ? _a : {});
87
- this.httpServer = (0, http_1.createServer)(this.handleRequest.bind(this));
79
+ this.extraContext = (maybeExtraContext[0] ?? {});
80
+ this.httpServer = createServer(this.handleRequest.bind(this));
88
81
  this.enableCors();
89
82
  this.attachRestHandlers();
90
83
  const targetTable = [
91
- ["/targets/android/client.kt", (ast) => (0, kotlin_generator_1.generateAndroidClientSource)(ast, true)],
92
- ["/targets/android/client_without_callbacks.kt", (ast) => (0, kotlin_generator_1.generateAndroidClientSource)(ast, false)],
93
- ["/targets/dotnet/api.cs", csharp_generator_1.generateCSharpServerSource],
94
- ["/targets/dotnet/api.fs", fsharp_generator_1.generateFSharpServerSource],
95
- ["/targets/flutter/client.dart", dart_generator_1.generateDartClientSource],
96
- ["/targets/ios/client.swift", (ast) => (0, swift_generator_1.generateSwiftClientSource)(ast, false)],
97
- ["/targets/ios/client-rx.swift", (ast) => (0, swift_generator_1.generateSwiftClientSource)(ast, true)],
98
- ["/targets/node/api.ts", typescript_generator_1.generateNodeServerSource],
99
- ["/targets/node/client.ts", typescript_generator_1.generateNodeClientSource],
100
- ["/targets/web/client.ts", typescript_generator_1.generateBrowserClientSource],
84
+ ["/targets/android/client.kt", (ast) => generateAndroidClientSource(ast, true)],
85
+ ["/targets/android/client_without_callbacks.kt", (ast) => generateAndroidClientSource(ast, false)],
86
+ ["/targets/dotnet/api.cs", generateCSharpServerSource],
87
+ ["/targets/dotnet/api.fs", generateFSharpServerSource],
88
+ ["/targets/flutter/client.dart", generateDartClientSource],
89
+ ["/targets/ios/client.swift", (ast) => generateSwiftClientSource(ast, false)],
90
+ ["/targets/ios/client-rx.swift", (ast) => generateSwiftClientSource(ast, true)],
91
+ ["/targets/node/api.ts", generateNodeServerSource],
92
+ ["/targets/node/client.ts", generateNodeClientSource],
93
+ ["/targets/web/client.ts", generateBrowserClientSource],
101
94
  ];
102
95
  for (const [path, generateFn] of targetTable) {
103
96
  this.addHttpHandler("GET", path, (_req, res) => {
@@ -137,11 +130,11 @@ class SdkgenHttpServer {
137
130
  if (req.url) {
138
131
  req.url = req.url.endsWith("/playground") ? req.url.replace(/\/playground/u, "/index.html") : req.url.replace(/\/playground/u, "");
139
132
  }
140
- (0, serve_handler_1.default)(req, res, {
133
+ staticFilesHandler(req, res, {
141
134
  cleanUrls: false,
142
135
  directoryListing: false,
143
136
  etag: true,
144
- public: playground_1.PLAYGROUND_PUBLIC_PATH,
137
+ public: PLAYGROUND_PUBLIC_PATH,
145
138
  }).catch(e => {
146
139
  console.error(e);
147
140
  res.statusCode = 500;
@@ -160,34 +153,35 @@ class SdkgenHttpServer {
160
153
  return new Promise(resolve => {
161
154
  this.httpServer.listen(port, () => {
162
155
  const addr = this.httpServer.address();
163
- let addrString;
164
- if (addr === null) {
165
- addrString = undefined;
156
+ let urlHost;
157
+ if (addr.address === "::") {
158
+ urlHost = `localhost:${addr.port}`;
166
159
  }
167
- else if (typeof addr === "string") {
168
- addrString = addr;
160
+ else if (addr.family === "ipv6") {
161
+ urlHost = `[${addr.address}]:${addr.port}`;
169
162
  }
170
163
  else {
171
- addrString = `${addr.address}:${addr.port}`;
164
+ urlHost = `${addr.address}:${addr.port}`;
172
165
  }
173
- if (!addrString) {
174
- console.log(`Listening.`);
175
- resolve();
176
- return;
166
+ if (addr.address === "::" || addr.address === "0.0.0.0") {
167
+ console.log(`\nListening on port ${addr.port}`);
168
+ }
169
+ else {
170
+ console.log(`\nListening on port ${addr.port} (${addr.address})`);
177
171
  }
178
- console.log(`Listening on ${addrString}`);
179
172
  if (this.introspection) {
180
- console.log(`Access the sdkgen Playground at http://${addrString}/playground`);
173
+ console.log(`Playground: http://${urlHost}/playground`);
181
174
  }
182
175
  if (this.hasSwagger) {
183
- console.log(`Access the REST API Swagger at http://${addrString}/swagger`);
176
+ console.log(`Swagger UI: http://${urlHost}/swagger`);
184
177
  }
178
+ console.log("");
185
179
  resolve();
186
180
  });
187
181
  });
188
182
  }
189
183
  async close() {
190
- return (0, util_1.promisify)(this.httpServer.close.bind(this.httpServer))();
184
+ return promisify(this.httpServer.close.bind(this.httpServer))();
191
185
  }
192
186
  enableCors() {
193
187
  this.addHeader("Access-Control-Allow-Methods", "DELETE, HEAD, PUT, POST, PATCH, GET, OPTIONS");
@@ -213,11 +207,10 @@ class SdkgenHttpServer {
213
207
  const matchingHandlers = this.handlers
214
208
  .filter(({ method }) => method === req.method)
215
209
  .filter(({ matcher }) => {
216
- var _a;
217
210
  if (typeof matcher === "string") {
218
211
  return matcher === path;
219
212
  }
220
- return ((_a = matcher.exec(path)) === null || _a === void 0 ? void 0 : _a[0]) === path;
213
+ return matcher.exec(path)?.[0] === path;
221
214
  })
222
215
  .sort(({ matcher: first }, { matcher: second }) => {
223
216
  // Prefer string matches instead of Regexp matches
@@ -252,11 +245,11 @@ class SdkgenHttpServer {
252
245
  }
253
246
  for (const op of this.apiConfig.ast.operations) {
254
247
  for (const ann of op.annotations) {
255
- if (!(ann instanceof parser_1.RestAnnotation)) {
248
+ if (!(ann instanceof RestAnnotation)) {
256
249
  continue;
257
250
  }
258
251
  if (!this.hasSwagger) {
259
- (0, swagger_1.setupSwagger)(this);
252
+ setupSwagger(this);
260
253
  this.hasSwagger = true;
261
254
  }
262
255
  const pathFragments = ann.path.split(/\{\w+\}/u);
@@ -273,12 +266,11 @@ class SdkgenHttpServer {
273
266
  }
274
267
  // eslint-disable-next-line @typescript-eslint/no-misused-promises
275
268
  this.addHttpHandler(ann.method, new RegExp(pathRegex, "u"), async (req, res, body) => {
276
- var _a, _b, _c, _d, _e, _f, _g;
277
269
  try {
278
270
  const args = {};
279
271
  const files = [];
280
- const { pathname, query } = (0, url_1.parse)((_a = req.url) !== null && _a !== void 0 ? _a : "");
281
- const match = pathname === null || pathname === void 0 ? void 0 : pathname.match(pathRegex);
272
+ const { pathname, query } = parseUrl(req.url ?? "");
273
+ const match = pathname?.match(pathRegex);
282
274
  if (!match) {
283
275
  res.statusCode = 404;
284
276
  return;
@@ -289,33 +281,33 @@ class SdkgenHttpServer {
289
281
  const argValue = match[i + 1];
290
282
  simpleArgs.set(argName, argValue);
291
283
  }
292
- const parsedQuery = query ? (0, querystring_1.parse)(query) : {};
284
+ const parsedQuery = query ? parseQuerystring(query) : {};
293
285
  for (const argName of ann.queryVariables) {
294
- const argValue = (_b = parsedQuery[argName]) !== null && _b !== void 0 ? _b : null;
286
+ const argValue = parsedQuery[argName] ?? null;
295
287
  if (argValue === null) {
296
288
  continue;
297
289
  }
298
290
  simpleArgs.set(argName, Array.isArray(argValue) ? argValue.join("") : argValue);
299
291
  }
300
292
  for (const [headerName, argName] of ann.headers) {
301
- const argValue = (_c = req.headers[headerName.toLowerCase()]) !== null && _c !== void 0 ? _c : null;
293
+ const argValue = req.headers[headerName.toLowerCase()] ?? null;
302
294
  if (argValue === null) {
303
295
  continue;
304
296
  }
305
297
  simpleArgs.set(argName, Array.isArray(argValue) ? argValue.join("") : argValue);
306
298
  }
307
- if (!ann.bodyVariable && ((_d = req.headers["content-type"]) === null || _d === void 0 ? void 0 : _d.match(/^application\/x-www-form-urlencoded/iu))) {
308
- const parsedBody = (0, querystring_1.parse)(body.toString());
299
+ if (!ann.bodyVariable && req.headers["content-type"]?.match(/^application\/x-www-form-urlencoded/iu)) {
300
+ const parsedBody = parseQuerystring(body.toString());
309
301
  for (const argName of ann.queryVariables) {
310
- const argValue = (_e = parsedBody[argName]) !== null && _e !== void 0 ? _e : null;
302
+ const argValue = parsedBody[argName] ?? null;
311
303
  if (argValue === null) {
312
304
  continue;
313
305
  }
314
306
  simpleArgs.set(argName, Array.isArray(argValue) ? argValue.join("") : argValue);
315
307
  }
316
308
  }
317
- else if (!ann.bodyVariable && ((_f = req.headers["content-type"]) === null || _f === void 0 ? void 0 : _f.match(/^multipart\/form-data/iu))) {
318
- const busboy = (0, busboy_1.default)({ headers: req.headers });
309
+ else if (!ann.bodyVariable && req.headers["content-type"]?.match(/^multipart\/form-data/iu)) {
310
+ const busboy = Busboy({ headers: req.headers });
319
311
  const filePromises = [];
320
312
  busboy.on("field", (field, value) => {
321
313
  if (ann.queryVariables.includes(field)) {
@@ -323,15 +315,15 @@ class SdkgenHttpServer {
323
315
  }
324
316
  });
325
317
  busboy.on("file", (_field, stream, info) => {
326
- const tempName = (0, crypto_1.randomBytes)(32).toString("hex");
327
- const writeStream = (0, fs_1.createWriteStream)(tempName);
318
+ const tempName = randomBytes(32).toString("hex");
319
+ const writeStream = createWriteStream(tempName);
328
320
  filePromises.push(new Promise((resolve, reject) => {
329
321
  writeStream.on("error", reject);
330
322
  writeStream.on("close", () => {
331
- const contents = (0, fs_1.createReadStream)(tempName);
323
+ const contents = createReadStream(tempName);
332
324
  files.push({ contents, name: info.filename });
333
325
  contents.on("open", () => {
334
- (0, fs_1.unlink)(tempName, err => {
326
+ unlink(tempName, err => {
335
327
  if (err) {
336
328
  reject(err);
337
329
  }
@@ -356,13 +348,13 @@ class SdkgenHttpServer {
356
348
  else if (ann.bodyVariable) {
357
349
  const argName = ann.bodyVariable;
358
350
  const arg = op.args.find(x => x.name === argName);
359
- if (/application\/json/iu.test((_g = req.headers["content-type"]) !== null && _g !== void 0 ? _g : "")) {
351
+ if (/application\/json/iu.test(req.headers["content-type"] ?? "")) {
360
352
  args[argName] = JSON.parse(body.toString());
361
353
  }
362
354
  else if (arg) {
363
355
  let { type } = arg;
364
356
  let solved = false;
365
- if (type instanceof parser_1.OptionalType) {
357
+ if (type instanceof OptionalType) {
366
358
  if (body.length === 0) {
367
359
  args[argName] = null;
368
360
  solved = true;
@@ -372,24 +364,24 @@ class SdkgenHttpServer {
372
364
  }
373
365
  }
374
366
  if (!solved) {
375
- if (type instanceof parser_1.BoolPrimitiveType ||
376
- type instanceof parser_1.IntPrimitiveType ||
377
- type instanceof parser_1.UIntPrimitiveType ||
378
- type instanceof parser_1.FloatPrimitiveType ||
379
- type instanceof parser_1.StringPrimitiveType ||
380
- type instanceof parser_1.DatePrimitiveType ||
381
- type instanceof parser_1.DateTimePrimitiveType ||
382
- type instanceof parser_1.MoneyPrimitiveType ||
383
- type instanceof parser_1.DecimalPrimitiveType ||
384
- type instanceof parser_1.BigIntPrimitiveType ||
385
- type instanceof parser_1.CpfPrimitiveType ||
386
- type instanceof parser_1.CnpjPrimitiveType ||
387
- type instanceof parser_1.UuidPrimitiveType ||
388
- type instanceof parser_1.HexPrimitiveType ||
389
- type instanceof parser_1.Base64PrimitiveType) {
367
+ if (type instanceof BoolPrimitiveType ||
368
+ type instanceof IntPrimitiveType ||
369
+ type instanceof UIntPrimitiveType ||
370
+ type instanceof FloatPrimitiveType ||
371
+ type instanceof StringPrimitiveType ||
372
+ type instanceof DatePrimitiveType ||
373
+ type instanceof DateTimePrimitiveType ||
374
+ type instanceof MoneyPrimitiveType ||
375
+ type instanceof DecimalPrimitiveType ||
376
+ type instanceof BigIntPrimitiveType ||
377
+ type instanceof CpfPrimitiveType ||
378
+ type instanceof CnpjPrimitiveType ||
379
+ type instanceof UuidPrimitiveType ||
380
+ type instanceof HexPrimitiveType ||
381
+ type instanceof Base64PrimitiveType) {
390
382
  simpleArgs.set(argName, body.toString());
391
383
  }
392
- else if (type instanceof parser_1.BytesPrimitiveType) {
384
+ else if (type instanceof BytesPrimitiveType) {
393
385
  args[argName] = body.toString("base64");
394
386
  }
395
387
  else {
@@ -404,7 +396,7 @@ class SdkgenHttpServer {
404
396
  continue;
405
397
  }
406
398
  let { type } = arg;
407
- if (type instanceof parser_1.OptionalType) {
399
+ if (type instanceof OptionalType) {
408
400
  if (argValue === null) {
409
401
  args[argName] = null;
410
402
  continue;
@@ -417,7 +409,7 @@ class SdkgenHttpServer {
417
409
  args[argName] = argValue;
418
410
  continue;
419
411
  }
420
- if (type instanceof parser_1.BoolPrimitiveType) {
412
+ if (type instanceof BoolPrimitiveType) {
421
413
  if (argValue === "true") {
422
414
  args[argName] = true;
423
415
  }
@@ -428,17 +420,17 @@ class SdkgenHttpServer {
428
420
  args[argName] = argValue;
429
421
  }
430
422
  }
431
- else if (type instanceof parser_1.UIntPrimitiveType || type instanceof parser_1.IntPrimitiveType || type instanceof parser_1.MoneyPrimitiveType) {
423
+ else if (type instanceof UIntPrimitiveType || type instanceof IntPrimitiveType || type instanceof MoneyPrimitiveType) {
432
424
  args[argName] = parseInt(argValue, 10);
433
425
  }
434
- else if (type instanceof parser_1.FloatPrimitiveType) {
426
+ else if (type instanceof FloatPrimitiveType) {
435
427
  args[argName] = parseFloat(argValue);
436
428
  }
437
429
  else {
438
430
  args[argName] = argValue;
439
431
  }
440
432
  }
441
- const ip = (0, request_ip_1.getClientIp)(req);
433
+ const ip = getClientIp(req);
442
434
  if (!ip) {
443
435
  throw new Error("Couldn't determine client IP");
444
436
  }
@@ -446,7 +438,7 @@ class SdkgenHttpServer {
446
438
  args,
447
439
  deviceInfo: {
448
440
  fingerprint: null,
449
- id: (0, crypto_1.randomBytes)(16).toString("hex"),
441
+ id: randomBytes(16).toString("hex"),
450
442
  language: null,
451
443
  platform: null,
452
444
  timezone: null,
@@ -456,7 +448,7 @@ class SdkgenHttpServer {
456
448
  extra: {},
457
449
  files,
458
450
  headers: req.headers,
459
- id: (0, crypto_1.randomBytes)(16).toString("hex"),
451
+ id: randomBytes(16).toString("hex"),
460
452
  ip,
461
453
  name: op.name,
462
454
  version: 3,
@@ -468,12 +460,12 @@ class SdkgenHttpServer {
468
460
  res.setHeader(headerKey, headerValue);
469
461
  }
470
462
  }
471
- if (ctx === null || ctx === void 0 ? void 0 : ctx.response.statusCode) {
463
+ if (ctx?.response.statusCode) {
472
464
  res.statusCode = ctx.response.statusCode;
473
465
  }
474
466
  if (reply.error) {
475
467
  const error = this.makeResponseError(reply.error);
476
- if (!(ctx === null || ctx === void 0 ? void 0 : ctx.response.statusCode)) {
468
+ if (!ctx?.response.statusCode) {
477
469
  res.statusCode = error.type === "Fatal" ? 500 : 400;
478
470
  }
479
471
  res.setHeader("content-type", "application/json");
@@ -488,9 +480,9 @@ class SdkgenHttpServer {
488
480
  }
489
481
  else {
490
482
  let type = op.returnType;
491
- if (type instanceof parser_1.OptionalType) {
483
+ if (type instanceof OptionalType) {
492
484
  if (reply.result === null) {
493
- if (!(ctx === null || ctx === void 0 ? void 0 : ctx.response.statusCode)) {
485
+ if (!ctx?.response.statusCode) {
494
486
  res.statusCode = ann.method === "GET" ? 404 : 204;
495
487
  }
496
488
  res.end();
@@ -498,42 +490,41 @@ class SdkgenHttpServer {
498
490
  }
499
491
  type = type.base;
500
492
  }
501
- if (type instanceof parser_1.BoolPrimitiveType ||
502
- type instanceof parser_1.IntPrimitiveType ||
503
- type instanceof parser_1.UIntPrimitiveType ||
504
- type instanceof parser_1.FloatPrimitiveType ||
505
- type instanceof parser_1.StringPrimitiveType ||
506
- type instanceof parser_1.DatePrimitiveType ||
507
- type instanceof parser_1.DateTimePrimitiveType ||
508
- type instanceof parser_1.MoneyPrimitiveType ||
509
- type instanceof parser_1.DecimalPrimitiveType ||
510
- type instanceof parser_1.BigIntPrimitiveType ||
511
- type instanceof parser_1.CpfPrimitiveType ||
512
- type instanceof parser_1.CnpjPrimitiveType ||
513
- type instanceof parser_1.UuidPrimitiveType ||
514
- type instanceof parser_1.HexPrimitiveType ||
515
- type instanceof parser_1.Base64PrimitiveType) {
493
+ if (type instanceof BoolPrimitiveType ||
494
+ type instanceof IntPrimitiveType ||
495
+ type instanceof UIntPrimitiveType ||
496
+ type instanceof FloatPrimitiveType ||
497
+ type instanceof StringPrimitiveType ||
498
+ type instanceof DatePrimitiveType ||
499
+ type instanceof DateTimePrimitiveType ||
500
+ type instanceof MoneyPrimitiveType ||
501
+ type instanceof DecimalPrimitiveType ||
502
+ type instanceof BigIntPrimitiveType ||
503
+ type instanceof CpfPrimitiveType ||
504
+ type instanceof CnpjPrimitiveType ||
505
+ type instanceof UuidPrimitiveType ||
506
+ type instanceof HexPrimitiveType ||
507
+ type instanceof Base64PrimitiveType) {
516
508
  res.setHeader("content-type", "text/plain");
517
509
  res.write(`${reply.result}`);
518
510
  res.end();
519
511
  }
520
- else if (type instanceof parser_1.HtmlPrimitiveType) {
512
+ else if (type instanceof HtmlPrimitiveType) {
521
513
  res.setHeader("content-type", "text/html");
522
514
  res.write(`${reply.result}`);
523
515
  res.end();
524
516
  }
525
- else if (type instanceof parser_1.XmlPrimitiveType) {
517
+ else if (type instanceof XmlPrimitiveType) {
526
518
  res.setHeader("content-type", "text/xml");
527
519
  res.write(`${reply.result}`);
528
520
  res.end();
529
521
  }
530
- else if (type instanceof parser_1.BytesPrimitiveType) {
522
+ else if (type instanceof BytesPrimitiveType) {
531
523
  const buffer = Buffer.from(reply.result, "base64");
532
524
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
533
- file_type_1.default.fromBuffer(buffer)
525
+ fileTypeFromBuffer(buffer)
534
526
  .then(fileType => {
535
- var _a;
536
- res.setHeader("content-type", (_a = fileType === null || fileType === void 0 ? void 0 : fileType.mime) !== null && _a !== void 0 ? _a : "application/octet-stream");
527
+ res.setHeader("content-type", fileType?.mime ?? "application/octet-stream");
537
528
  })
538
529
  .catch(err => {
539
530
  console.error(err);
@@ -573,13 +564,12 @@ class SdkgenHttpServer {
573
564
  }
574
565
  }
575
566
  async handleRequestWithBody(req, res, body, hrStart) {
576
- var _a, _b;
577
- const { pathname, query } = (0, url_1.parse)((_a = req.url) !== null && _a !== void 0 ? _a : "");
578
- let path = pathname !== null && pathname !== void 0 ? pathname : "";
567
+ const { pathname, query } = parseUrl(req.url ?? "");
568
+ let path = pathname ?? "";
579
569
  if (path.startsWith(this.ignoredUrlPrefix)) {
580
570
  path = path.slice(this.ignoredUrlPrefix.length);
581
571
  }
582
- if (!((_b = req.headers["content-type"]) === null || _b === void 0 ? void 0 : _b.match(/application\/sdkgen/iu))) {
572
+ if (!req.headers["content-type"]?.match(/application\/sdkgen/iu)) {
583
573
  const externalHandler = this.findBestHandler(path, req);
584
574
  if (externalHandler) {
585
575
  this.log(`HTTP ${req.method} ${path}${query ? `?${query}` : ""}`);
@@ -621,27 +611,31 @@ class SdkgenHttpServer {
621
611
  res.end();
622
612
  return;
623
613
  }
624
- const clientIp = (0, request_ip_1.getClientIp)(req);
614
+ const clientIp = getClientIp(req);
625
615
  if (!clientIp) {
626
616
  this.writeReply(res, null, {
627
- error: new error_1.Fatal("Couldn't determine client IP"),
617
+ error: new Fatal("Couldn't determine client IP"),
628
618
  }, hrStart);
629
619
  return;
630
620
  }
631
621
  const request = this.parseRequest(req, body.toString(), clientIp);
632
622
  if (!request) {
633
623
  this.writeReply(res, null, {
634
- error: new error_1.Fatal("Couldn't parse request"),
624
+ error: new Fatal("Couldn't parse request"),
635
625
  }, hrStart);
636
626
  return;
637
627
  }
638
628
  await this.executeRequest(request, (ctx, reply) => this.writeReply(res, ctx, reply, hrStart));
639
629
  }
640
630
  async executeRequest(request, writeReply) {
641
- const ctx = Object.assign(Object.assign({}, this.extraContext), { request, response: {
631
+ const ctx = {
632
+ ...this.extraContext,
633
+ request,
634
+ response: {
642
635
  headers: new Map(),
643
- } });
644
- writeReply(ctx, await (0, execute_1.executeRequest)(ctx, this.apiConfig));
636
+ },
637
+ };
638
+ writeReply(ctx, await executeRequest(ctx, this.apiConfig));
645
639
  }
646
640
  parseRequest(req, body, ip) {
647
641
  switch (this.identifyRequestVersion(req, body)) {
@@ -657,21 +651,20 @@ class SdkgenHttpServer {
657
651
  }
658
652
  identifyRequestVersion(_req, body) {
659
653
  const parsed = JSON.parse(body);
660
- if (typeof parsed === "object" && parsed && (0, utils_1.has)(parsed, "version") && typeof parsed.version === "number") {
654
+ if (typeof parsed === "object" && parsed && has(parsed, "version") && typeof parsed.version === "number") {
661
655
  return parsed.version;
662
656
  }
663
- else if (typeof parsed === "object" && parsed && (0, utils_1.has)(parsed, "requestId")) {
657
+ else if (typeof parsed === "object" && parsed && has(parsed, "requestId")) {
664
658
  return 2;
665
659
  }
666
- else if (typeof parsed === "object" && parsed && (0, utils_1.has)(parsed, "device")) {
660
+ else if (typeof parsed === "object" && parsed && has(parsed, "device")) {
667
661
  return 1;
668
662
  }
669
663
  return 3;
670
664
  }
671
665
  // Old Sdkgen format
672
666
  parseRequestV1(req, body, ip) {
673
- var _a, _b;
674
- const parsed = (0, encode_decode_1.decode)({
667
+ const parsed = decode({
675
668
  Request: {
676
669
  args: "json",
677
670
  device: "RequestDevice",
@@ -688,7 +681,7 @@ class SdkgenHttpServer {
688
681
  version: "string?",
689
682
  },
690
683
  }, "root", "Request", JSON.parse(body));
691
- const deviceId = (_a = parsed.device.id) !== null && _a !== void 0 ? _a : (0, crypto_1.randomBytes)(20).toString("hex");
684
+ const deviceId = parsed.device.id ?? randomBytes(20).toString("hex");
692
685
  if (!parsed.args || Array.isArray(parsed.args) || typeof parsed.args !== "object") {
693
686
  throw new Error("Expected 'args' to be an object");
694
687
  }
@@ -700,7 +693,7 @@ class SdkgenHttpServer {
700
693
  language: parsed.device.language,
701
694
  platform: parsed.device.platform,
702
695
  timezone: parsed.device.timezone,
703
- type: (_b = parsed.device.type) !== null && _b !== void 0 ? _b : (typeof parsed.device.platform === "string" ? parsed.device.platform : ""),
696
+ type: parsed.device.type ?? (typeof parsed.device.platform === "string" ? parsed.device.platform : ""),
704
697
  version: parsed.device.version,
705
698
  },
706
699
  extra: {},
@@ -714,8 +707,7 @@ class SdkgenHttpServer {
714
707
  }
715
708
  // Maxima sdkgen format
716
709
  parseRequestV2(req, body, ip) {
717
- var _a, _b;
718
- const parsed = (0, encode_decode_1.decode)({
710
+ const parsed = decode({
719
711
  Request: {
720
712
  args: "json",
721
713
  deviceFingerprint: "string?",
@@ -742,7 +734,7 @@ class SdkgenHttpServer {
742
734
  id: parsed.deviceId,
743
735
  language: parsed.info.language,
744
736
  platform: {
745
- browserUserAgent: (_a = parsed.info.browserUserAgent) !== null && _a !== void 0 ? _a : null,
737
+ browserUserAgent: parsed.info.browserUserAgent ?? null,
746
738
  },
747
739
  timezone: null,
748
740
  type: parsed.info.type,
@@ -754,7 +746,7 @@ class SdkgenHttpServer {
754
746
  },
755
747
  files: [],
756
748
  headers: req.headers,
757
- id: `${parsed.deviceId}-${(_b = parsed.requestId) !== null && _b !== void 0 ? _b : (0, crypto_1.randomBytes)(16).toString("hex")}`,
749
+ id: `${parsed.deviceId}-${parsed.requestId ?? randomBytes(16).toString("hex")}`,
758
750
  ip,
759
751
  name: parsed.name,
760
752
  version: 2,
@@ -762,8 +754,7 @@ class SdkgenHttpServer {
762
754
  }
763
755
  // New sdkgen format
764
756
  parseRequestV3(req, body, ip) {
765
- var _a, _b, _c, _d;
766
- const parsed = (0, encode_decode_1.decode)({
757
+ const parsed = decode({
767
758
  DeviceInfo: {
768
759
  fingerprint: "string?",
769
760
  id: "string?",
@@ -781,7 +772,7 @@ class SdkgenHttpServer {
781
772
  requestId: "string?",
782
773
  },
783
774
  }, "root", "Request", JSON.parse(body));
784
- const deviceInfo = (_a = parsed.deviceInfo) !== null && _a !== void 0 ? _a : {
775
+ const deviceInfo = parsed.deviceInfo ?? {
785
776
  fingerprint: null,
786
777
  id: null,
787
778
  language: null,
@@ -790,7 +781,7 @@ class SdkgenHttpServer {
790
781
  type: null,
791
782
  version: null,
792
783
  };
793
- const deviceId = (_b = deviceInfo.id) !== null && _b !== void 0 ? _b : (0, crypto_1.randomBytes)(16).toString("hex");
784
+ const deviceId = deviceInfo.id ?? randomBytes(16).toString("hex");
794
785
  if (!parsed.args || Array.isArray(parsed.args) || typeof parsed.args !== "object") {
795
786
  throw new Error("Expected 'args' to be an object");
796
787
  }
@@ -800,15 +791,15 @@ class SdkgenHttpServer {
800
791
  fingerprint: deviceInfo.fingerprint,
801
792
  id: deviceId,
802
793
  language: deviceInfo.language,
803
- platform: typeof deviceInfo.platform === "object" ? Object.assign({}, deviceInfo.platform) : {},
794
+ platform: typeof deviceInfo.platform === "object" ? { ...deviceInfo.platform } : {},
804
795
  timezone: deviceInfo.timezone,
805
- type: (_c = deviceInfo.type) !== null && _c !== void 0 ? _c : "api",
796
+ type: deviceInfo.type ?? "api",
806
797
  version: deviceInfo.version,
807
798
  },
808
- extra: typeof parsed.extra === "object" ? Object.assign({}, parsed.extra) : {},
799
+ extra: typeof parsed.extra === "object" ? { ...parsed.extra } : {},
809
800
  files: [],
810
801
  headers: req.headers,
811
- id: `${deviceId}-${(_d = parsed.requestId) !== null && _d !== void 0 ? _d : (0, crypto_1.randomBytes)(16).toString("hex")}`,
802
+ id: `${deviceId}-${parsed.requestId ?? randomBytes(16).toString("hex")}`,
812
803
  ip,
813
804
  name: parsed.name,
814
805
  version: 3,
@@ -816,11 +807,11 @@ class SdkgenHttpServer {
816
807
  }
817
808
  makeResponseError(err) {
818
809
  let type = "Fatal";
819
- if (typeof err === "object" && err !== null && (0, utils_1.has)(err, "type") && typeof err.type === "string") {
810
+ if (typeof err === "object" && err !== null && has(err, "type") && typeof err.type === "string") {
820
811
  ({ type } = err);
821
812
  }
822
813
  let message;
823
- if (typeof err === "object" && err !== null && (0, utils_1.has)(err, "message") && typeof err.message === "string") {
814
+ if (typeof err === "object" && err !== null && has(err, "message") && typeof err.message === "string") {
824
815
  ({ message } = err);
825
816
  }
826
817
  else if (err instanceof Error) {
@@ -833,14 +824,14 @@ class SdkgenHttpServer {
833
824
  message = `${err}`;
834
825
  }
835
826
  let data;
836
- if (typeof err === "object" && err !== null && (0, utils_1.has)(err, "data")) {
827
+ if (typeof err === "object" && err !== null && has(err, "data")) {
837
828
  ({ data } = err);
838
829
  }
839
830
  const error = this.apiConfig.ast.errors.find(x => x.name === type);
840
831
  if (error) {
841
- if (!(error.dataType instanceof parser_1.VoidPrimitiveType)) {
832
+ if (!(error.dataType instanceof VoidPrimitiveType)) {
842
833
  try {
843
- data = (0, encode_decode_1.encode)(this.apiConfig.astJson.typeTable, `error.${type}`, error.dataType.name, data);
834
+ data = encode(this.apiConfig.astJson.typeTable, `error.${type}`, error.dataType.name, data);
844
835
  }
845
836
  catch (encodeError) {
846
837
  message = `Failed to encode error ${type} because: ${encodeError}. Original message: ${message}`;
@@ -854,11 +845,10 @@ class SdkgenHttpServer {
854
845
  return { data, message, type };
855
846
  }
856
847
  writeReply(res, ctx, reply, hrStart) {
857
- var _a, _b;
858
848
  if (!ctx) {
859
849
  res.statusCode = 500;
860
850
  res.write(JSON.stringify({
861
- error: this.makeResponseError((_a = reply.error) !== null && _a !== void 0 ? _a : new error_1.Fatal("Response without context")),
851
+ error: this.makeResponseError(reply.error ?? new Fatal("Response without context")),
862
852
  }));
863
853
  res.end();
864
854
  return;
@@ -881,7 +871,7 @@ class SdkgenHttpServer {
881
871
  deviceId: ctx.request.deviceInfo.id,
882
872
  duration,
883
873
  error: reply.error ? this.makeResponseError(reply.error) : null,
884
- host: (0, os_1.hostname)(),
874
+ host: hostname(),
885
875
  id: ctx.request.id,
886
876
  ok: !reply.error,
887
877
  result: reply.error ? null : reply.result,
@@ -913,7 +903,7 @@ class SdkgenHttpServer {
913
903
  const response = {
914
904
  duration,
915
905
  error: reply.error ? this.makeResponseError(reply.error) : null,
916
- host: (0, os_1.hostname)(),
906
+ host: hostname(),
917
907
  result: reply.error ? null : reply.result,
918
908
  };
919
909
  if (response.error && !ctx.response.statusCode) {
@@ -927,7 +917,7 @@ class SdkgenHttpServer {
927
917
  default: {
928
918
  res.statusCode = 500;
929
919
  res.write(JSON.stringify({
930
- error: this.makeResponseError((_b = reply.error) !== null && _b !== void 0 ? _b : new error_1.Fatal("Unknown request version")),
920
+ error: this.makeResponseError(reply.error ?? new Fatal("Unknown request version")),
931
921
  }));
932
922
  res.end();
933
923
  return;
@@ -935,4 +925,4 @@ class SdkgenHttpServer {
935
925
  }
936
926
  }
937
927
  }
938
- exports.SdkgenHttpServer = SdkgenHttpServer;
928
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC1zZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaHR0cC1zZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUNyQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBRWpFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFcEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLElBQUksQ0FBQztBQUM5QixPQUFPLEVBQUUsS0FBSyxJQUFJLGdCQUFnQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hELE9BQU8sRUFBRSxLQUFLLElBQUksUUFBUSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFakMsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDbEUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdEUsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFdkUsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixtQkFBbUIsRUFDbkIsbUJBQW1CLEVBQ25CLGlCQUFpQixFQUNqQixrQkFBa0IsRUFDbEIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixpQkFBaUIsRUFDakIscUJBQXFCLEVBQ3JCLGtCQUFrQixFQUNsQixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixrQkFBa0IsRUFDbEIsWUFBWSxFQUNaLGNBQWMsRUFDZCxtQkFBbUIsRUFDbkIsaUJBQWlCLEVBQ2pCLGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIsZ0JB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Q0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztpQkFDdEY7Z0JBRUQsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDOUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3BDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztnQkFDVixNQUFNO2FBQ1A7WUFFRCxPQUFPLENBQUMsQ0FBQztnQkFDUCxHQUFHLENBQUMsVUFBVSxHQUFHLEdBQUcsQ0FBQztnQkFDckIsR0FBRyxDQUFDLEtBQUssQ0FDUCxJQUFJLENBQUMsU0FBUyxDQUFDO29CQUNiLEtBQUssRUFBRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLEtBQUssSUFBSSxJQUFJLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO2lCQUNuRixDQUFDLENBQ0gsQ0FBQztnQkFDRixHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQ1YsT0FBTzthQUNSO1NBQ0Y7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByYW5kb21CeXRlcyB9IGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCB7IGNyZWF0ZVJlYWRTdHJlYW0sIGNyZWF0ZVdyaXRlU3RyZWFtLCB1bmxpbmsgfSBmcm9tIFwiZnNcIjtcbmltcG9ydCB0eXBlIHsgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXIsIFNlcnZlclJlc3BvbnNlIH0gZnJvbSBcImh0dHBcIjtcbmltcG9ydCB7IGNyZWF0ZVNlcnZlciB9IGZyb20gXCJodHRwXCI7XG5pbXBvcnQgdHlwZSB7IEFkZHJlc3NJbmZvIH0gZnJvbSBcIm5ldFwiO1xuaW1wb3J0IHsgaG9zdG5hbWUgfSBmcm9tIFwib3NcIjtcbmltcG9ydCB7IHBhcnNlIGFzIHBhcnNlUXVlcnlzdHJpbmcgfSBmcm9tIFwicXVlcnlzdHJpbmdcIjtcbmltcG9ydCB7IHBhcnNlIGFzIHBhcnNlVXJsIH0gZnJvbSBcInVybFwiO1xuaW1wb3J0IHsgcHJvbWlzaWZ5IH0gZnJvbSBcInV0aWxcIjtcblxuaW1wb3J0IHsgZ2VuZXJhdGVDU2hhcnBTZXJ2ZXJTb3VyY2UgfSBmcm9tIFwiQHNka2dlbi9jc2hhcnAtZ2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZURhcnRDbGllbnRTb3VyY2UgfSBmcm9tIFwiQHNka2dlbi9kYXJ0LWdlbmVyYXRvclwiO1xuaW1wb3J0IHsgZ2VuZXJhdGVGU2hhcnBTZXJ2ZXJTb3VyY2UgfSBmcm9tIFwiQHNka2dlbi9mc2hhcnAtZ2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZUFuZHJvaWRDbGllbnRTb3VyY2UgfSBmcm9tIFwiQHNka2dlbi9rb3RsaW4tZ2VuZXJhdG9yXCI7XG5pbXBvcnQgdHlwZSB7IEFzdFJvb3QgfSBmcm9tIFwiQHNka2dlbi9wYXJzZXJcIjtcbmltcG9ydCB7XG4gIERlY2ltYWxQcmltaXRpdmVUeXBlLFxuICBCYXNlNjRQcmltaXRpdmVUeXBlLFxuICBCaWdJbnRQcmltaXRpdmVUeXBlLFxuICBCb29sUHJpbWl0aXZlVHlwZSxcbiAgQnl0ZXNQcmltaXRpdmVUeXBlLFxuICBDbnBqUHJpbWl0aXZlVHlwZSxcbiAgQ3BmUHJpbWl0aXZlVHlwZSxcbiAgRGF0ZVByaW1pdGl2ZVR5cGUsXG4gIERhdGVUaW1lUHJpbWl0aXZlVHlwZSxcbiAgRmxvYXRQcmltaXRpdmVUeXBlLFxuICBIZXhQcmltaXRpdmVUeXBlLFxuICBIdG1sUHJpbWl0aXZlVHlwZSxcbiAgSW50UHJpbWl0aXZlVHlwZSxcbiAgTW9uZXlQcmltaXRpdmVUeXBlLFxuICBPcHRpb25hbFR5cGUsXG4gIFJlc3RBbm5vdGF0aW9uLFxuICBTdHJpbmdQcmltaXRpdmVUeXBlLFxuICBVSW50UHJpbWl0aXZlVHlwZSxcbiAgVXVpZFByaW1pdGl2ZVR5cGUsXG4gIFZvaWRQcmltaXRpdmVUeXBlLFxuICBYbWxQcmltaXRpdmVUeXBlLFxufSBmcm9tIFwiQHNka2dlbi9wYXJzZXJcIjtcbmltcG9ydCB7IFBMQVlHUk9VTkRfUFVCTElDX1BBVEggfSBmcm9tIFwiQHNka2dlbi9wbGF5Z3JvdW5kXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZVN3aWZ0Q2xpZW50U291cmNlIH0gZnJvbSBcIkBzZGtnZW4vc3dpZnQtZ2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBnZW5lcmF0ZUJyb3dzZXJDbGllbnRTb3VyY2UsIGdlbmVyYXRlTm9kZUNsaWVudFNvdXJjZSwgZ2VuZXJhdGVOb2RlU2VydmVyU291cmNlIH0gZnJvbSBcIkBzZGtnZW4vdHlwZXNjcmlwdC1nZW5lcmF0b3JcIjtcbmltcG9ydCBCdXNib3kgZnJvbSBcImJ1c2JveVwiO1xuaW1wb3J0IHsgZmlsZVR5cGVGcm9tQnVmZmVyIH0gZnJvbSBcImZpbGUtdHlwZVwiO1xuaW1wb3J0IHsgZ2V0Q2xpZW50SXAgfSBmcm9tIFwicmVxdWVzdC1pcFwiO1xuaW1wb3J0IHN0YXRpY0ZpbGVzSGFuZGxlciBmcm9tIFwic2VydmUtaGFuZGxlclwiO1xuXG5pbXBvcnQgdHlwZSB7IEJhc2VBcGlDb25maWcgfSBmcm9tIFwiLi9hcGktY29uZmlnLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENvbnRleHQsIENvbnRleHRSZXBseSwgQ29udGV4dFJlcXVlc3QgfSBmcm9tIFwiLi9jb250ZXh0LmpzXCI7XG5pbXBvcnQgeyBkZWNvZGUsIGVuY29kZSB9IGZyb20gXCIuL2VuY29kZS1kZWNvZGUuanNcIjtcbmltcG9ydCB7IEZhdGFsIH0gZnJvbSBcIi4vZXJyb3IuanNcIjtcbmltcG9ydCB7IGV4ZWN1dGVSZXF1ZXN0IH0gZnJvbSBcIi4vZXhlY3V0ZS5qc1wiO1xuaW1wb3J0IHsgc2V0dXBTd2FnZ2VyIH0gZnJvbSBcIi4vc3dhZ2dlci5qc1wiO1xuaW1wb3J0IHsgaGFzIH0gZnJvbSBcIi4vdXRpbHMuanNcIjtcblxuZXhwb3J0IGNsYXNzIFNka2dlbkh0dHBTZXJ2ZXI8RXh0cmFDb250ZXh0VCA9IHVua25vd24+IHtcbiAgcHVibGljIGh0dHBTZXJ2ZXI6IFNlcnZlcjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGhlYWRlcnMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaGVhbHRoQ2hlY2tzOiBBcnJheTwoKSA9PiBQcm9taXNlPGJvb2xlYW4+PiA9IFtdO1xuXG4gIHByaXZhdGUgaGFuZGxlcnM6IEFycmF5PHtcbiAgICBtZXRob2Q6IHN0cmluZztcbiAgICBtYXRjaGVyOiBzdHJpbmcgfCBSZWdFeHA7XG4gICAgaGFuZGxlcihyZXE6IEluY29taW5nTWVzc2FnZSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSwgYm9keTogQnVmZmVyKTogdm9pZDtcbiAgfT4gPSBbXTtcblxuICBwdWJsaWMgZHluYW1pY0NvcnNPcmlnaW4gPSB0cnVlO1xuXG4gIHB1YmxpYyBpbnRyb3NwZWN0aW9uID0gdHJ1ZTtcblxuICBwdWJsaWMgbG9nID0gKG1lc3NhZ2U6IHN0cmluZykgPT4ge1xuICAgIGNvbnNvbGUubG9nKGAke25ldyBEYXRlKCkudG9JU09TdHJpbmcoKX0gJHttZXNzYWdlfWApO1xuICB9O1xuXG4gIHByaXZhdGUgaGFzU3dhZ2dlciA9IGZhbHNlO1xuXG4gIHByaXZhdGUgaWdub3JlZFVybFByZWZpeCA9IFwiXCI7XG5cbiAgcHJpdmF0ZSBleHRyYUNvbnRleHQ6IEV4dHJhQ29udGV4dFQ7XG5cbiAgY29uc3RydWN0b3IocHVibGljIGFwaUNvbmZpZzogQmFzZUFwaUNvbmZpZzxFeHRyYUNvbnRleHRUPiwgLi4ubWF5YmVFeHRyYUNvbnRleHQ6IHt9IGV4dGVuZHMgRXh0cmFDb250ZXh0VCA/IFt7fT9dIDogW0V4dHJhQ29udGV4dFRdKSB7XG4gICAgdGhpcy5leHRyYUNvbnRleHQgPSAobWF5YmVFeHRyYUNvbnRleHRbMF0gPz8ge30pIGFzIEV4dHJhQ29udGV4dFQ7XG4gICAgdGhpcy5odHRwU2VydmVyID0gY3JlYXRlU2VydmVyKHRoaXMuaGFuZGxlUmVxdWVzdC5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLmVuYWJsZUNvcnMoKTtcbiAgICB0aGlzLmF0dGFjaFJlc3RIYW5kbGVycygpO1xuXG4gICAgY29uc3QgdGFyZ2V0VGFibGUgPSBbXG4gICAgICBbXCIvdGFyZ2V0cy9hbmRyb2lkL2NsaWVudC5rdFwiLCAoYXN0OiBBc3RSb290KSA9PiBnZW5lcmF0ZUFuZHJvaWRDbGllbnRTb3VyY2UoYXN0LCB0cnVlKV0sXG4gICAgICBbXCIvdGFyZ2V0cy9hbmRyb2lkL2NsaWVudF93aXRob3V0X2NhbGxiYWNrcy5rdFwiLCAoYXN0OiBBc3RSb290KSA9PiBnZW5lcmF0ZUFuZHJvaWRDbGllbnRTb3VyY2UoYXN0LCBmYWxzZSldLFxuICAgICAgW1wiL3RhcmdldHMvZG90bmV0L2FwaS5jc1wiLCBnZW5lcmF0ZUNTaGFycFNlcnZlclNvdXJjZV0sXG4gICAgICBbXCIvdGFyZ2V0cy9kb3RuZXQvYXBpLmZzXCIsIGdlbmVyYXRlRlNoYXJwU2VydmVyU291cmNlXSxcbiAgICAgIFtcIi90YXJnZXRzL2ZsdXR0ZXIvY2xpZW50LmRhcnRcIiwgZ2VuZXJhdGVEYXJ0Q2xpZW50U291cmNlXSxcbiAgICAgIFtcIi90YXJnZXRzL2lvcy9jbGllbnQuc3dpZnRcIiwgKGFzdDogQXN0Um9vdCkgPT4gZ2VuZXJhdGVTd2lmdENsaWVudFNvdXJjZShhc3QsIGZhbHNlKV0sXG4gICAgICBbXCIvdGFyZ2V0cy9pb3MvY2xpZW50LXJ4LnN3aWZ0XCIsIChhc3Q6IEFzdFJvb3QpID0+IGdlbmVyYXRlU3dpZnRDbGllbnRTb3VyY2UoYXN0LCB0cnVlKV0sXG4gICAgICBbXCIvdGFyZ2V0cy9ub2RlL2FwaS50c1wiLCBnZW5lcmF0ZU5vZGVTZXJ2ZXJTb3VyY2VdLFxuICAgICAgW1wiL3RhcmdldHMvbm9kZS9jbGllbnQudHNcIiwgZ2VuZXJhdGVOb2RlQ2xpZW50U291cmNlXSxcbiAgICAgIFtcIi90YXJnZXRzL3dlYi9jbGllbnQudHNcIiwgZ2VuZXJhdGVCcm93c2VyQ2xpZW50U291cmNlXSxcbiAgICBdIGFzIGNvbnN0O1xuXG4gICAgZm9yIChjb25zdCBbcGF0aCwgZ2VuZXJhdGVGbl0gb2YgdGFyZ2V0VGFibGUpIHtcbiAgICAgIHRoaXMuYWRkSHR0cEhhbmRsZXIoXCJHRVRcIiwgcGF0aCwgKF9yZXEsIHJlcykgPT4ge1xuICAgICAgICBpZiAoIXRoaXMuaW50cm9zcGVjdGlvbikge1xuICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNDA0O1xuICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJlcy5zZXRIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW1cIik7XG4gICAgICAgICAgcmVzLndyaXRlKGdlbmVyYXRlRm4odGhpcy5hcGlDb25maWcuYXN0KSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNTAwO1xuICAgICAgICAgIHJlcy53cml0ZShgJHtlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5hZGRIdHRwSGFuZGxlcihcIkdFVFwiLCBcIi9hc3QuanNvblwiLCAoX3JlcSwgcmVzKSA9PiB7XG4gICAgICBpZiAoIXRoaXMuaW50cm9zcGVjdGlvbikge1xuICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNDtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlcy5zZXRIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xuICAgICAgcmVzLndyaXRlKEpTT04uc3RyaW5naWZ5KGFwaUNvbmZpZy5hc3RKc29uKSk7XG4gICAgICByZXMuZW5kKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFkZEh0dHBIYW5kbGVyKFwiR0VUXCIsIC9eXFwvcGxheWdyb3VuZC4qL3UsIChyZXEsIHJlcykgPT4ge1xuICAgICAgaWYgKCF0aGlzLmludHJvc3BlY3Rpb24pIHtcbiAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA0MDQ7XG4gICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAocmVxLnVybCkge1xuICAgICAgICByZXEudXJsID0gcmVxLnVybC5lbmRzV2l0aChcIi9wbGF5Z3JvdW5kXCIpID8gcmVxLnVybC5yZXBsYWNlKC9cXC9wbGF5Z3JvdW5kL3UsIFwiL2luZGV4Lmh0bWxcIikgOiByZXEudXJsLnJlcGxhY2UoL1xcL3BsYXlncm91bmQvdSwgXCJcIik7XG4gICAgICB9XG5cbiAgICAgIHN0YXRpY0ZpbGVzSGFuZGxlcihyZXEsIHJlcywge1xuICAgICAgICBjbGVhblVybHM6IGZhbHNlLFxuICAgICAgICBkaXJlY3RvcnlMaXN0aW5nOiBmYWxzZSxcbiAgICAgICAgZXRhZzogdHJ1ZSxcbiAgICAgICAgcHVibGljOiBQTEFZR1JPVU5EX1BVQkxJQ19QQVRILFxuICAgICAgfSkuY2F0Y2goZSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNTAwO1xuICAgICAgICByZXMud3JpdGUoYCR7ZX1gKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICByZWdpc3RlckhlYWx0aENoZWNrKGhlYWx0aENoZWNrOiAoKSA9PiBQcm9taXNlPGJvb2xlYW4+KTogdm9pZCB7XG4gICAgdGhpcy5oZWFsdGhDaGVja3MucHVzaChoZWFsdGhDaGVjayk7XG4gIH1cblxuICBpZ25vcmVVcmxQcmVmaXgodXJsUHJlZml4OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmlnbm9yZWRVcmxQcmVmaXggPSB1cmxQcmVmaXg7XG4gIH1cblxuICBhc3luYyBsaXN0ZW4ocG9ydCA9IDgwMDApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICB0aGlzLmh0dHBTZXJ2ZXIubGlzdGVuKHBvcnQsICgpID0+IHtcbiAgICAgICAgY29uc3QgYWRkciA9IHRoaXMuaHR0cFNlcnZlci5hZGRyZXNzKCkgYXMgQWRkcmVzc0luZm87XG4gICAgICAgIGxldCB1cmxIb3N0OiBzdHJpbmc7XG5cbiAgICAgICAgaWYgKGFkZHIuYWRkcmVzcyA9PT0gXCI6OlwiKSB7XG4gICAgICAgICAgdXJsSG9zdCA9IGBsb2NhbGhvc3Q6JHthZGRyLnBvcnR9YDtcbiAgICAgICAgfSBlbHNlIGlmIChhZGRyLmZhbWlseSA9PT0gXCJpcHY2XCIpIHtcbiAgICAgICAgICB1cmxIb3N0ID0gYFske2FkZHIuYWRkcmVzc31dOiR7YWRkci5wb3J0fWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdXJsSG9zdCA9IGAke2FkZHIuYWRkcmVzc306JHthZGRyLnBvcnR9YDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChhZGRyLmFkZHJlc3MgPT09IFwiOjpcIiB8fCBhZGRyLmFkZHJlc3MgPT09IFwiMC4wLjAuMFwiKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYFxcbkxpc3RlbmluZyBvbiBwb3J0ICR7YWRkci5wb3J0fWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBcXG5MaXN0ZW5pbmcgb24gcG9ydCAke2FkZHIucG9ydH0gKCR7YWRkci5hZGRyZXNzfSlgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmludHJvc3BlY3Rpb24pIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgUGxheWdyb3VuZDogaHR0cDovLyR7dXJsSG9zdH0vcGxheWdyb3VuZGApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaGFzU3dhZ2dlcikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBTd2FnZ2VyIFVJOiBodHRwOi8vJHt1cmxIb3N0fS9zd2FnZ2VyYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zb2xlLmxvZyhcIlwiKTtcblxuICAgICAgICByZXNvbHZlKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIGNsb3NlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBwcm9taXNpZnkodGhpcy5odHRwU2VydmVyLmNsb3NlLmJpbmQodGhpcy5odHRwU2VydmVyKSkoKTtcbiAgfVxuXG4gIHByaXZhdGUgZW5hYmxlQ29ycygpIHtcbiAgICB0aGlzLmFkZEhlYWRlcihcIkFjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHNcIiwgXCJERUxFVEUsIEhFQUQsIFBVVCwgUE9TVCwgUEFUQ0gsIEdFVCwgT1BUSU9OU1wiKTtcbiAgICB0aGlzLmFkZEhlYWRlcihcIkFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnNcIiwgXCJDb250ZW50LVR5cGVcIik7XG4gICAgdGhpcy5hZGRIZWFkZXIoXCJBY2Nlc3MtQ29udHJvbC1NYXgtQWdlXCIsIFwiODY0MDBcIik7XG4gIH1cblxuICBhZGRIZWFkZXIoaGVhZGVyOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjbGVhbkhlYWRlciA9IGhlYWRlci50b0xvd2VyQ2FzZSgpLnRyaW0oKTtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuaGVhZGVycy5nZXQoY2xlYW5IZWFkZXIpO1xuXG4gICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICBpZiAoIWV4aXN0aW5nLmluY2x1ZGVzKHZhbHVlKSkge1xuICAgICAgICB0aGlzLmhlYWRlcnMuc2V0KGNsZWFuSGVhZGVyLCBgJHtleGlzdGluZ30sICR7dmFsdWV9YCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaGVhZGVycy5zZXQoY2xlYW5IZWFkZXIsIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICBhZGRIdHRwSGFuZGxlcihtZXRob2Q6IHN0cmluZywgbWF0Y2hlcjogc3RyaW5nIHwgUmVnRXhwLCBoYW5kbGVyOiAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UsIGJvZHk6IEJ1ZmZlcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMuaGFuZGxlcnMucHVzaCh7IGhhbmRsZXIsIG1hdGNoZXIsIG1ldGhvZCB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZmluZEJlc3RIYW5kbGVyKHBhdGg6IHN0cmluZywgcmVxOiBJbmNvbWluZ01lc3NhZ2UpIHtcbiAgICBjb25zdCBtYXRjaGluZ0hhbmRsZXJzID0gdGhpcy5oYW5kbGVyc1xuICAgICAgLmZpbHRlcigoeyBtZXRob2QgfSkgPT4gbWV0aG9kID09PSByZXEubWV0aG9kKVxuICAgICAgLmZpbHRlcigoeyBtYXRjaGVyIH0pID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBtYXRjaGVyID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgcmV0dXJuIG1hdGNoZXIgPT09IHBhdGg7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbWF0Y2hlci5leGVjKHBhdGgpPy5bMF0gPT09IHBhdGg7XG4gICAgICB9KVxuICAgICAgLnNvcnQoKHsgbWF0Y2hlcjogZmlyc3QgfSwgeyBtYXRjaGVyOiBzZWNvbmQgfSkgPT4ge1xuICAgICAgICAvLyBQcmVmZXIgc3RyaW5nIG1hdGNoZXMgaW5zdGVhZCBvZiBSZWdleHAgbWF0Y2hlc1xuICAgICAgICBpZiAodHlwZW9mIGZpcnN0ID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiBzZWNvbmQgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZmlyc3QgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHNlY29uZCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RNYXRjaCA9IGZpcnN0LmV4ZWMocGF0aCk7XG4gICAgICAgIGNvbnN0IHNlY29uZE1hdGNoID0gc2Vjb25kLmV4ZWMocGF0aCk7XG5cbiAgICAgICAgaWYgKCFmaXJzdE1hdGNoKSB7XG4gICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzZWNvbmRNYXRjaCkge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29tcHV0ZSBob3cgbWFueSBjaGFyYWN0ZXJzIHdlcmUgTk9UIHBhcnQgb2YgYSBjYXB0dXJlIGdyb3VwXG4gICAgICAgIGNvbnN0IGZpcnN0TGVuZ3RoID0gZmlyc3RNYXRjaFswXS5sZW5ndGggLSBmaXJzdE1hdGNoLnNsaWNlKDEpLnJlZHVjZSgoYWNjLCBjdXIpID0+IGFjYyArIGN1ci5sZW5ndGgsIDApO1xuICAgICAgICBjb25zdCBzZWNvbmRMZW5ndGggPSBzZWNvbmRNYXRjaFswXS5sZW5ndGggLSBzZWNvbmRNYXRjaC5zbGljZSgxKS5yZWR1Y2UoKGFjYywgY3VyKSA9PiBhY2MgKyBjdXIubGVuZ3RoLCAwKTtcblxuICAgICAgICAvLyBQcmVmZXIgdGhlIG1heGltdW0gbnVtYmVyIG9mIG5vbi1jYXB0dXJlZCBjaGFyYWN0ZXJzXG4gICAgICAgIHJldHVybiBzZWNvbmRMZW5ndGggLSBmaXJzdExlbmd0aDtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIG1hdGNoaW5nSGFuZGxlcnMubGVuZ3RoID8gbWF0Y2hpbmdIYW5kbGVyc1swXSA6IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGF0dGFjaFJlc3RIYW5kbGVycygpIHtcbiAgICBmdW5jdGlvbiBlc2NhcGVSZWdFeHAoc3RyOiBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBzdHIucmVwbGFjZSgvWy4qKz9eJHt9KCl8W1xcXVxcXFxdL2d1LCBcIlxcXFwkJlwiKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG9wIG9mIHRoaXMuYXBpQ29uZmlnLmFzdC5vcGVyYXRpb25zKSB7XG4gICAgICBmb3IgKGNvbnN0IGFubiBvZiBvcC5hbm5vdGF0aW9ucykge1xuICAgICAgICBpZiAoIShhbm4gaW5zdGFuY2VvZiBSZXN0QW5ub3RhdGlvbikpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5oYXNTd2FnZ2VyKSB7XG4gICAgICAgICAgc2V0dXBTd2FnZ2VyKHRoaXMpO1xuICAgICAgICAgIHRoaXMuaGFzU3dhZ2dlciA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXRoRnJhZ21lbnRzID0gYW5uLnBhdGguc3BsaXQoL1xce1xcdytcXH0vdSk7XG5cbiAgICAgICAgbGV0IHBhdGhSZWdleCA9IFwiXlwiO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGF0aEZyYWdtZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgIGlmIChpID4gMCkge1xuICAgICAgICAgICAgcGF0aFJlZ2V4ICs9IFwiKFteL10rPylcIjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBwYXRoUmVnZXggKz0gZXNjYXBlUmVnRXhwKHBhdGhGcmFnbWVudHNbaV0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcGF0aFJlZ2V4ICs9IFwiLz8kXCI7XG5cbiAgICAgICAgZm9yIChjb25zdCBoZWFkZXIgb2YgYW5uLmhlYWRlcnMua2V5cygpKSB7XG4gICAgICAgICAgdGhpcy5hZGRIZWFkZXIoXCJBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzXCIsIGhlYWRlci50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbWlzdXNlZC1wcm9taXNlc1xuICAgICAgICB0aGlzLmFkZEh0dHBIYW5kbGVyKGFubi5tZXRob2QsIG5ldyBSZWdFeHAocGF0aFJlZ2V4LCBcInVcIiksIGFzeW5jIChyZXEsIHJlcywgYm9keSkgPT4ge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBhcmdzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgICAgICAgICAgY29uc3QgZmlsZXM6IENvbnRleHRSZXF1ZXN0W1wiZmlsZXNcIl0gPSBbXTtcblxuICAgICAgICAgICAgY29uc3QgeyBwYXRobmFtZSwgcXVlcnkgfSA9IHBhcnNlVXJsKHJlcS51cmwgPz8gXCJcIik7XG4gICAgICAgICAgICBjb25zdCBtYXRjaCA9IHBhdGhuYW1lPy5tYXRjaChwYXRoUmVnZXgpO1xuXG4gICAgICAgICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNDA0O1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNpbXBsZUFyZ3MgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nIHwgbnVsbD4oKTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhbm4ucGF0aFZhcmlhYmxlcy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgICBjb25zdCBhcmdOYW1lID0gYW5uLnBhdGhWYXJpYWJsZXNbaV07XG4gICAgICAgICAgICAgIGNvbnN0IGFyZ1ZhbHVlID0gbWF0Y2hbaSArIDFdO1xuXG4gICAgICAgICAgICAgIHNpbXBsZUFyZ3Muc2V0KGFyZ05hbWUsIGFyZ1ZhbHVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcGFyc2VkUXVlcnkgPSBxdWVyeSA/IHBhcnNlUXVlcnlzdHJpbmcocXVlcnkpIDoge307XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgYXJnTmFtZSBvZiBhbm4ucXVlcnlWYXJpYWJsZXMpIHtcbiAgICAgICAgICAgICAgY29uc3QgYXJnVmFsdWUgPSBwYXJzZWRRdWVyeVthcmdOYW1lXSA/PyBudWxsO1xuXG4gICAgICAgICAgICAgIGlmIChhcmdWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgc2ltcGxlQXJncy5zZXQoYXJnTmFtZSwgQXJyYXkuaXNBcnJheShhcmdWYWx1ZSkgPyBhcmdWYWx1ZS5qb2luKFwiXCIpIDogYXJnVmFsdWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKGNvbnN0IFtoZWFkZXJOYW1lLCBhcmdOYW1lXSBvZiBhbm4uaGVhZGVycykge1xuICAgICAgICAgICAgICBjb25zdCBhcmdWYWx1ZSA9IHJlcS5oZWFkZXJzW2hlYWRlck5hbWUudG9Mb3dlckNhc2UoKV0gPz8gbnVsbDtcblxuICAgICAgICAgICAgICBpZiAoYXJnVmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHNpbXBsZUFyZ3Muc2V0KGFyZ05hbWUsIEFycmF5LmlzQXJyYXkoYXJnVmFsdWUpID8gYXJnVmFsdWUuam9pbihcIlwiKSA6IGFyZ1ZhbHVlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFhbm4uYm9keVZhcmlhYmxlICYmIHJlcS5oZWFkZXJzW1wiY29udGVudC10eXBlXCJdPy5tYXRjaCgvXmFwcGxpY2F0aW9uXFwveC13d3ctZm9ybS11cmxlbmNvZGVkL2l1KSkge1xuICAgICAgICAgICAgICBjb25zdCBwYXJzZWRCb2R5ID0gcGFyc2VRdWVyeXN0cmluZyhib2R5LnRvU3RyaW5nKCkpO1xuXG4gICAgICAgICAgICAgIGZvciAoY29uc3QgYXJnTmFtZSBvZiBhbm4ucXVlcnlWYXJpYWJsZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBhcmdWYWx1ZSA9IHBhcnNlZEJvZHlbYXJnTmFtZV0gPz8gbnVsbDtcblxuICAgICAgICAgICAgICAgIGlmIChhcmdWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgc2ltcGxlQXJncy5zZXQoYXJnTmFtZSwgQXJyYXkuaXNBcnJheShhcmdWYWx1ZSkgPyBhcmdWYWx1ZS5qb2luKFwiXCIpIDogYXJnVmFsdWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCFhbm4uYm9keVZhcmlhYmxlICYmIHJlcS5oZWFkZXJzW1wiY29udGVudC10eXBlXCJdPy5tYXRjaCgvXm11bHRpcGFydFxcL2Zvcm0tZGF0YS9pdSkpIHtcbiAgICAgICAgICAgICAgY29uc3QgYnVzYm95ID0gQnVzYm95KHsgaGVhZGVyczogcmVxLmhlYWRlcnMgfSk7XG4gICAgICAgICAgICAgIGNvbnN0IGZpbGVQcm9taXNlczogQXJyYXk8UHJvbWlzZTx2b2lkPj4gPSBbXTtcblxuICAgICAgICAgICAgICBidXNib3kub24oXCJmaWVsZFwiLCAoZmllbGQsIHZhbHVlKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGFubi5xdWVyeVZhcmlhYmxlcy5pbmNsdWRlcyhmaWVsZCkpIHtcbiAgICAgICAgICAgICAgICAgIHNpbXBsZUFyZ3Muc2V0KGZpZWxkLCBgJHt2YWx1ZX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIGJ1c2JveS5vbihcImZpbGVcIiwgKF9maWVsZCwgc3RyZWFtLCBpbmZvKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGVtcE5hbWUgPSByYW5kb21CeXRlcygzMikudG9TdHJpbmcoXCJoZXhcIik7XG4gICAgICAgICAgICAgICAgY29uc3Qgd3JpdGVTdHJlYW0gPSBjcmVhdGVXcml0ZVN0cmVhbSh0ZW1wTmFtZSk7XG5cbiAgICAgICAgICAgICAgICBmaWxlUHJvbWlzZXMucHVzaChcbiAgICAgICAgICAgICAgICAgIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgd3JpdGVTdHJlYW0ub24oXCJlcnJvclwiLCByZWplY3QpO1xuXG4gICAgICAgICAgICAgICAgICAgIHdyaXRlU3RyZWFtLm9uKFwiY2xvc2VcIiwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRlbnRzID0gY3JlYXRlUmVhZFN0cmVhbSh0ZW1wTmFtZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICBmaWxlcy5wdXNoKHsgY29udGVudHMsIG5hbWU6IGluZm8uZmlsZW5hbWUgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICBjb250ZW50cy5vbihcIm9wZW5cIiwgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdW5saW5rKHRlbXBOYW1lLCBlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgd3JpdGVTdHJlYW0ub24oXCJvcGVuXCIsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICBzdHJlYW0ucGlwZSh3cml0ZVN0cmVhbSk7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIGJ1c2JveS5vbihcImZpbmlzaFwiLCByZXNvbHZlKTtcbiAgICAgICAgICAgICAgICBidXNib3kub24oXCJlcnJvclwiLCByZWplY3QpO1xuICAgICAgICAgICAgICAgIGJ1c2JveS53cml0ZShib2R5KTtcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoZmlsZVByb21pc2VzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYW5uLmJvZHlWYXJpYWJsZSkge1xuICAgICAgICAgICAgICBjb25zdCBhcmdOYW1lID0gYW5uLmJvZHlWYXJpYWJsZTtcbiAgICAgICAgICAgICAgY29uc3QgYXJnID0gb3AuYXJncy5maW5kKHggPT4geC5uYW1lID09PSBhcmdOYW1lKTtcblxuICAgICAgICAgICAgICBpZiAoL2FwcGxpY2F0aW9uXFwvanNvbi9pdS50ZXN0KHJlcS5oZWFkZXJzW1wiY29udGVudC10eXBlXCJdID8/IFwiXCIpKSB7XG4gICAgICAgICAgICAgICAgYXJnc1thcmdOYW1lXSA9IEpTT04ucGFyc2UoYm9keS50b1N0cmluZygpKTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChhcmcpIHtcbiAgICAgICAgICAgICAgICBsZXQgeyB0eXBlIH0gPSBhcmc7XG4gICAgICAgICAgICAgICAgbGV0IHNvbHZlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBPcHRpb25hbFR5cGUpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChib2R5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBhcmdzW2FyZ05hbWVdID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgPSB0eXBlLmJhc2U7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFzb2x2ZWQpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIEJvb2xQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBJbnRQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBVSW50UHJpbWl0aXZlVHlwZSB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlIGluc3RhbmNlb2YgRmxvYXRQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBTdHJpbmdQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBEYXRlUHJpbWl0aXZlVHlwZSB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlIGluc3RhbmNlb2YgRGF0ZVRpbWVQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBNb25leVByaW1pdGl2ZVR5cGUgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIERlY2ltYWxQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBCaWdJbnRQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBDcGZQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBDbnBqUHJpbWl0aXZlVHlwZSB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlIGluc3RhbmNlb2YgVXVpZFByaW1pdGl2ZVR5cGUgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIEhleFByaW1pdGl2ZVR5cGUgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIEJhc2U2NFByaW1pdGl2ZVR5cGVcbiAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBzaW1wbGVBcmdzLnNldChhcmdOYW1lLCBib2R5LnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgQnl0ZXNQcmltaXRpdmVUeXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIGFyZ3NbYXJnTmFtZV0gPSBib2R5LnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXJnc1thcmdOYW1lXSA9IEpTT04ucGFyc2UoYm9keS50b1N0cmluZygpKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBbYXJnTmFtZSwgYXJnVmFsdWVdIG9mIHNpbXBsZUFyZ3MpIHtcbiAgICAgICAgICAgICAgY29uc3QgYXJnID0gb3AuYXJncy5maW5kKHggPT4geC5uYW1lID09PSBhcmdOYW1lKTtcblxuICAgICAgICAgICAgICBpZiAoIWFyZykge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgbGV0IHsgdHlwZSB9ID0gYXJnO1xuXG4gICAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgT3B0aW9uYWxUeXBlKSB7XG4gICAgICAgICAgICAgICAgaWYgKGFyZ1ZhbHVlID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICBhcmdzW2FyZ05hbWVdID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0eXBlID0gdHlwZS5iYXNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChhcmdWYWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGFyZ3NbYXJnTmFtZV0gPSBhcmdWYWx1ZTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICh0eXBlIGluc3RhbmNlb2YgQm9vbFByaW1pdGl2ZVR5cGUpIHtcbiAgICAgICAgICAgICAgICBpZiAoYXJnVmFsdWUgPT09IFwidHJ1ZVwiKSB7XG4gICAgICAgICAgICAgICAgICBhcmdzW2FyZ05hbWVdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFyZ1ZhbHVlID09PSBcImZhbHNlXCIpIHtcbiAgICAgICAgICAgICAgICAgIGFyZ3NbYXJnTmFtZV0gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgYXJnc1thcmdOYW1lXSA9IGFyZ1ZhbHVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgVUludFByaW1pdGl2ZVR5cGUgfHwgdHlwZSBpbnN0YW5jZW9mIEludFByaW1pdGl2ZVR5cGUgfHwgdHlwZSBpbnN0YW5jZW9mIE1vbmV5UHJpbWl0aXZlVHlwZSkge1xuICAgICAgICAgICAgICAgIGFyZ3NbYXJnTmFtZV0gPSBwYXJzZUludChhcmdWYWx1ZSwgMTApO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBGbG9hdFByaW1pdGl2ZVR5cGUpIHtcbiAgICAgICAgICAgICAgICBhcmdzW2FyZ05hbWVdID0gcGFyc2VGbG9hdChhcmdWYWx1ZSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXJnc1thcmdOYW1lXSA9IGFyZ1ZhbHVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlwID0gZ2V0Q2xpZW50SXAocmVxKTtcblxuICAgICAgICAgICAgaWYgKCFpcCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZG4ndCBkZXRlcm1pbmUgY2xpZW50IElQXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByZXF1ZXN0OiBDb250ZXh0UmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgYXJncyxcbiAgICAgICAgICAgICAgZGV2aWNlSW5mbzoge1xuICAgICAgICAgICAgICAgIGZpbmdlcnByaW50OiBudWxsLFxuICAgICAgICAgICAgICAgIGlkOiByYW5kb21CeXRlcygxNikudG9TdHJpbmcoXCJoZXhcIiksXG4gICAgICAgICAgICAgICAgbGFuZ3VhZ2U6IG51bGwsXG4gICAgICAgICAgICAgICAgcGxhdGZvcm06IG51bGwsXG4gICAgICAgICAgICAgICAgdGltZXpvbmU6IG51bGwsXG4gICAgICAgICAgICAgICAgdHlwZTogXCJyZXN0XCIsXG4gICAgICAgICAgICAgICAgdmVyc2lvbjogbnVsbCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgZXh0cmE6IHt9LFxuICAgICAgICAgICAgICBmaWxlcyxcbiAgICAgICAgICAgICAgaGVhZGVyczogcmVxLmhlYWRlcnMsXG4gICAgICAgICAgICAgIGlkOiByYW5kb21CeXRlcygxNikudG9TdHJpbmcoXCJoZXhcIiksXG4gICAgICAgICAgICAgIGlwLFxuICAgICAgICAgICAgICBuYW1lOiBvcC5uYW1lLFxuICAgICAgICAgICAgICB2ZXJzaW9uOiAzLFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5leGVjdXRlUmVxdWVzdChyZXF1ZXN0LCAoY3R4LCByZXBseSkgPT4ge1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmIChjdHgpIHtcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2hlYWRlcktleSwgaGVhZGVyVmFsdWVdIG9mIGN0eC5yZXNwb25zZS5oZWFkZXJzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXMuc2V0SGVhZGVyKGhlYWRlcktleSwgaGVhZGVyVmFsdWUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChjdHg/LnJlc3BvbnNlLnN0YXR1c0NvZGUpIHtcbiAgICAgICAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlcGx5LmVycm9yKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IHRoaXMubWFrZVJlc3BvbnNlRXJyb3IocmVwbHkuZXJyb3IpO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoIWN0eD8ucmVzcG9uc2Uuc3RhdHVzQ29kZSkge1xuICAgICAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IGVycm9yLnR5cGUgPT09IFwiRmF0YWxcIiA/IDUwMCA6IDQwMDtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgcmVzLnNldEhlYWRlcihcImNvbnRlbnQtdHlwZVwiLCBcImFwcGxpY2F0aW9uL2pzb25cIik7XG4gICAgICAgICAgICAgICAgICByZXMud3JpdGUoSlNPTi5zdHJpbmdpZnkoZXJyb3IpKTtcbiAgICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAocmVxLmhlYWRlcnMuYWNjZXB0ID09PSBcImFwcGxpY2F0aW9uL2pzb25cIikge1xuICAgICAgICAgICAgICAgICAgcmVzLnNldEhlYWRlcihcImNvbnRlbnQtdHlwZVwiLCBcImFwcGxpY2F0aW9uL2pzb25cIik7XG4gICAgICAgICAgICAgICAgICByZXMud3JpdGUoSlNPTi5zdHJpbmdpZnkocmVwbHkucmVzdWx0KSk7XG4gICAgICAgICAgICAgICAgICByZXMuZW5kKCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGxldCB0eXBlID0gb3AucmV0dXJuVHlwZTtcblxuICAgICAgICAgICAgICAgICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBPcHRpb25hbFR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcGx5LnJlc3VsdCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgIGlmICghY3R4Py5yZXNwb25zZS5zdGF0dXNDb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IGFubi5tZXRob2QgPT09IFwiR0VUXCIgPyA0MDQgOiAyMDQ7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHR5cGUgPSB0eXBlLmJhc2U7XG4gICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIEJvb2xQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBJbnRQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBVSW50UHJpbWl0aXZlVHlwZSB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlIGluc3RhbmNlb2YgRmxvYXRQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBTdHJpbmdQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBEYXRlUHJpbWl0aXZlVHlwZSB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlIGluc3RhbmNlb2YgRGF0ZVRpbWVQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBNb25leVByaW1pdGl2ZVR5cGUgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIERlY2ltYWxQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBCaWdJbnRQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBDcGZQcmltaXRpdmVUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAgIHR5cGUgaW5zdGFuY2VvZiBDbnBqUHJpbWl0aXZlVHlwZSB8fFxuICAgICAgICAgICAgICAgICAgICB0eXBlIGluc3RhbmNlb2YgVXVpZFByaW1pdGl2ZVR5cGUgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIEhleFByaW1pdGl2ZVR5cGUgfHxcbiAgICAgICAgICAgICAgICAgICAgdHlwZSBpbnN0YW5jZW9mIEJhc2U2NFByaW1pdGl2ZVR5cGVcbiAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICByZXMuc2V0SGVhZGVyKFwiY29udGVudC10eXBlXCIsIFwidGV4dC9wbGFpblwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzLndyaXRlKGAke3JlcGx5LnJlc3VsdH1gKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgSHRtbFByaW1pdGl2ZVR5cGUpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzLnNldEhlYWRlcihcImNvbnRlbnQtdHlwZVwiLCBcInRleHQvaHRtbFwiKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzLndyaXRlKGAke3JlcGx5LnJlc3VsdH1gKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWG1sUHJpbWl0aXZlVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICByZXMuc2V0SGVhZGVyKFwiY29udGVudC10eXBlXCIsIFwidGV4dC94bWxcIik7XG4gICAgICAgICAgICAgICAgICAgIHJlcy53cml0ZShgJHtyZXBseS5yZXN1bHR9YCk7XG4gICAgICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIEJ5dGVzUHJpbWl0aXZlVHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShyZXBseS5yZXN1bHQgYXMgc3RyaW5nLCBcImJhc2U2NFwiKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWZsb2F0aW5nLXByb21pc2VzXG4gICAgICAgICAgICAgICAgICAgIGZpbGVUeXBlRnJvbUJ1ZmZlcihidWZmZXIpXG4gICAgICAgICAgICAgICAgICAgICAgLnRoZW4oZmlsZVR5cGUgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzLnNldEhlYWRlcihcImNvbnRlbnQtdHlwZVwiLCBmaWxlVHlwZT8ubWltZSA/PyBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzLnNldEhlYWRlcihcImNvbnRlbnQtdHlwZVwiLCBcImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbVwiKTtcbiAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlcy53cml0ZShidWZmZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoXCJjb250ZW50LXR5cGVcIiwgXCJhcHBsaWNhdGlvbi9qc29uXCIpO1xuICAgICAgICAgICAgICAgICAgICByZXMud3JpdGUoSlNPTi5zdHJpbmdpZnkocmVwbHkucmVzdWx0KSk7XG4gICAgICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNTAwO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgaWYgKCFyZXMuaGVhZGVyc1NlbnQpIHtcbiAgICAgICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA1MDA7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVSZXF1ZXN0ID0gKHJlcTogSW5jb21pbmdNZXNzYWdlLCByZXM6IFNlcnZlclJlc3BvbnNlKSA9PiB7XG4gICAgY29uc3QgaHJTdGFydCA9IHByb2Nlc3MuaHJ0aW1lKCk7XG5cbiAgICByZXEub24oXCJlcnJvclwiLCBlcnIgPT4ge1xuICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgcmVzLmVuZCgpO1xuICAgIH0pO1xuXG4gICAgcmVzLm9uKFwiZXJyb3JcIiwgZXJyID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgIHJlcy5lbmQoKTtcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmR5bmFtaWNDb3JzT3JpZ2luICYmIHJlcS5oZWFkZXJzLm9yaWdpbikge1xuICAgICAgcmVzLnNldEhlYWRlcihcIkFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblwiLCByZXEuaGVhZGVycy5vcmlnaW4pO1xuICAgICAgcmVzLnNldEhlYWRlcihcIlZhcnlcIiwgXCJPcmlnaW5cIik7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbaGVhZGVyLCB2YWx1ZV0gb2YgdGhpcy5oZWFkZXJzKSB7XG4gICAgICBpZiAocmVxLm1ldGhvZCA9PT0gXCJPUFRJT05TXCIgJiYgIWhlYWRlci5zdGFydHNXaXRoKFwiYWNjZXNzLWNvbnRyb2wtXCIpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICByZXMuc2V0SGVhZGVyKGhlYWRlciwgdmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChyZXEubWV0aG9kID09PSBcIk9QVElPTlNcIikge1xuICAgICAgcmVzLndyaXRlSGVhZCgyMDApO1xuICAgICAgcmVzLmVuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZUJvZHkgPSAoYm9keTogQnVmZmVyKSA9PiB7XG4gICAgICB0aGlzLmhhbmRsZVJlcXVlc3RXaXRoQm9keShyZXEsIHJlcywgYm9keSwgaHJTdGFydCkuY2F0Y2goKGU6IHVua25vd24pID0+IHRoaXMud3JpdGVSZXBseShyZXMsIG51bGwsIHsgZXJyb3I6IGUgfSwgaHJTdGFydCkpO1xuICAgIH07XG5cbiAgICAvLyBHb29nbGUgQ2xvdWQgRnVuY3Rpb25zIGFkZCBhIHJhd0JvZHkgcHJvcGVydHkgdG8gdGhlIHJlcXVlc3Qgb2JqZWN0XG4gICAgaWYgKGhhcyhyZXEsIFwicmF3Qm9keVwiKSAmJiByZXEucmF3Qm9keSBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgaGFuZGxlQm9keShyZXEucmF3Qm9keSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGJvZHk6IEJ1ZmZlcltdID0gW107XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWFyZ3VtZW50XG4gICAgICByZXEub24oXCJkYXRhXCIsIGNodW5rID0+IGJvZHkucHVzaChjaHVuaykpO1xuXG4gICAgICByZXEub24oXCJlbmRcIiwgKCkgPT4ge1xuICAgICAgICBoYW5kbGVCb2R5KEJ1ZmZlci5jb25jYXQoYm9keSkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHByaXZhdGUgYXN5bmMgaGFuZGxlUmVxdWVzdFdpdGhCb2R5KHJlcTogSW5jb21pbmdNZXNzYWdlLCByZXM6IFNlcnZlclJlc3BvbnNlLCBib2R5OiBCdWZmZXIsIGhyU3RhcnQ6IFtudW1iZXIsIG51bWJlcl0pIHtcbiAgICBjb25zdCB7IHBhdGhuYW1lLCBxdWVyeSB9ID0gcGFyc2VVcmwocmVxLnVybCA/PyBcIlwiKTtcbiAgICBsZXQgcGF0aCA9IHBhdGhuYW1lID8/IFwiXCI7XG5cbiAgICBpZiAocGF0aC5zdGFydHNXaXRoKHRoaXMuaWdub3JlZFVybFByZWZpeCkpIHtcbiAgICAgIHBhdGggPSBwYXRoLnNsaWNlKHRoaXMuaWdub3JlZFVybFByZWZpeC5sZW5ndGgpO1xuICAgIH1cblxuICAgIGlmICghcmVxLmhlYWRlcnNbXCJjb250ZW50LXR5cGVcIl0/Lm1hdGNoKC9hcHBsaWNhdGlvblxcL3Nka2dlbi9pdSkpIHtcbiAgICAgIGNvbnN0IGV4dGVybmFsSGFuZGxlciA9IHRoaXMuZmluZEJlc3RIYW5kbGVyKHBhdGgsIHJlcSk7XG5cbiAgICAgIGlmIChleHRlcm5hbEhhbmRsZXIpIHtcbiAgICAgICAgdGhpcy5sb2coYEhUVFAgJHtyZXEubWV0aG9kfSAke3BhdGh9JHtxdWVyeSA/IGA/JHtxdWVyeX1gIDogXCJcIn1gKTtcbiAgICAgICAgZXh0ZXJuYWxIYW5kbGVyLmhhbmRsZXIocmVxLCByZXMsIGJvZHkpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzLnNldEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIik7XG5cbiAgICBpZiAocmVxLm1ldGhvZCA9PT0gXCJIRUFEXCIpIHtcbiAgICAgIHJlcy53cml0ZUhlYWQoMjAwKTtcbiAgICAgIHJlcy5lbmQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocmVxLm1ldGhvZCA9PT0gXCJHRVRcIikge1xuICAgICAgaWYgKHBhdGggIT09IFwiL1wiKSB7XG4gICAgICAgIHJlcy53cml0ZUhlYWQoNDA0KTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGxldCBvayA9IHRydWU7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAoY29uc3QgaGVhbHRoQ2hlY2sgb2YgdGhpcy5oZWFsdGhDaGVja3MpIHtcbiAgICAgICAgICBpZiAoIW9rKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBvayA9IGF3YWl0IGhlYWx0aENoZWNrKCk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgb2sgPSBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgcmVzLnN0YXR1c0NvZGUgPSBvayA/IDIwMCA6IDUwMDtcbiAgICAgIHJlcy53cml0ZShKU09OLnN0cmluZ2lmeSh7IG9rIH0pKTtcbiAgICAgIHJlcy5lbmQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocmVxLm1ldGhvZCAhPT0gXCJQT1NUXCIpIHtcbiAgICAgIHJlcy53cml0ZUhlYWQoNDAwKTtcbiAgICAgIHJlcy5lbmQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjbGllbnRJcCA9IGdldENsaWVudElwKHJlcSk7XG5cbiAgICBpZiAoIWNsaWVudElwKSB7XG4gICAgICB0aGlzLndyaXRlUmVwbHkoXG4gICAgICAgIHJlcyxcbiAgICAgICAgbnVsbCxcbiAgICAgICAge1xuICAgICAgICAgIGVycm9yOiBuZXcgRmF0YWwoXCJDb3VsZG4ndCBkZXRlcm1pbmUgY2xpZW50IElQXCIpLFxuICAgICAgICB9LFxuICAgICAgICBoclN0YXJ0LFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXF1ZXN0ID0gdGhpcy5wYXJzZVJlcXVlc3QocmVxLCBib2R5LnRvU3RyaW5nKCksIGNsaWVudElwKTtcblxuICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgdGhpcy53cml0ZVJlcGx5KFxuICAgICAgICByZXMsXG4gICAgICAgIG51bGwsXG4gICAgICAgIHtcbiAgICAgICAgICBlcnJvcjogbmV3IEZhdGFsKFwiQ291bGRuJ3QgcGFyc2UgcmVxdWVzdFwiKSxcbiAgICAgICAgfSxcbiAgICAgICAgaHJTdGFydCxcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5leGVjdXRlUmVxdWVzdChyZXF1ZXN0LCAoY3R4LCByZXBseSkgPT4gdGhpcy53cml0ZVJlcGx5KHJlcywgY3R4LCByZXBseSwgaHJTdGFydCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlUmVxdWVzdChyZXF1ZXN0OiBDb250ZXh0UmVxdWVzdCwgd3JpdGVSZXBseTogKGN0eDogQ29udGV4dCB8IG51bGwsIHJlcGx5OiBDb250ZXh0UmVwbHkpID0+IHZvaWQpIHtcbiAgICBjb25zdCBjdHg6IENvbnRleHQgJiBFeHRyYUNvbnRleHRUID0ge1xuICAgICAgLi4udGhpcy5leHRyYUNvbnRleHQsXG4gICAgICByZXF1ZXN0LFxuICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgaGVhZGVyczogbmV3IE1hcCgpLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgd3JpdGVSZXBseShjdHgsIGF3YWl0IGV4ZWN1dGVSZXF1ZXN0KGN0eCwgdGhpcy5hcGlDb25maWcpKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VSZXF1ZXN0KHJlcTogSW5jb21pbmdNZXNzYWdlLCBib2R5OiBzdHJpbmcsIGlwOiBzdHJpbmcpOiBDb250ZXh0UmVxdWVzdCB8IG51bGwge1xuICAgIHN3aXRjaCAodGhpcy5pZGVudGlmeVJlcXVlc3RWZXJzaW9uKHJlcSwgYm9keSkpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VSZXF1ZXN0VjEocmVxLCBib2R5LCBpcCk7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIHJldHVybiB0aGlzLnBhcnNlUmVxdWVzdFYyKHJlcSwgYm9keSwgaXApO1xuICAgICAgY2FzZSAzOlxuICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVJlcXVlc3RWMyhyZXEsIGJvZHksIGlwKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkZhaWxlZCB0byB1bmRlcnN0YW5kIHJlcXVlc3RcIik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpZGVudGlmeVJlcXVlc3RWZXJzaW9uKF9yZXE6IEluY29taW5nTWVzc2FnZSwgYm9keTogc3RyaW5nKTogbnVtYmVyIHtcbiAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGJvZHkpIGFzIHVua25vd247XG5cbiAgICBpZiAodHlwZW9mIHBhcnNlZCA9PT0gXCJvYmplY3RcIiAmJiBwYXJzZWQgJiYgaGFzKHBhcnNlZCwgXCJ2ZXJzaW9uXCIpICYmIHR5cGVvZiBwYXJzZWQudmVyc2lvbiA9PT0gXCJudW1iZXJcIikge1xuICAgICAgcmV0dXJuIHBhcnNlZC52ZXJzaW9uO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBhcnNlZCA9PT0gXCJvYmplY3RcIiAmJiBwYXJzZWQgJiYgaGFzKHBhcnNlZCwgXCJyZXF1ZXN0SWRcIikpIHtcbiAgICAgIHJldHVybiAyO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBhcnNlZCA9PT0gXCJvYmplY3RcIiAmJiBwYXJzZWQgJiYgaGFzKHBhcnNlZCwgXCJkZXZpY2VcIikpIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cblxuICAgIHJldHVybiAzO1xuICB9XG5cbiAgLy8gT2xkIFNka2dlbiBmb3JtYXRcbiAgcHJpdmF0ZSBwYXJzZVJlcXVlc3RWMShyZXE6IEluY29taW5nTWVzc2FnZSwgYm9keTogc3RyaW5nLCBpcDogc3RyaW5nKTogQ29udGV4dFJlcXVlc3Qge1xuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZShcbiAgICAgIHtcbiAgICAgICAgUmVxdWVzdDoge1xuICAgICAgICAgIGFyZ3M6IFwianNvblwiLFxuICAgICAgICAgIGRldmljZTogXCJSZXF1ZXN0RGV2aWNlXCIsXG4gICAgICAgICAgaWQ6IFwic3RyaW5nXCIsXG4gICAgICAgICAgbmFtZTogXCJzdHJpbmdcIixcbiAgICAgICAgfSxcbiAgICAgICAgUmVxdWVzdERldmljZToge1xuICAgICAgICAgIGZpbmdlcnByaW50OiBcInN0cmluZz9cIixcbiAgICAgICAgICBpZDogXCJzdHJpbmc/XCIsXG4gICAgICAgICAgbGFuZ3VhZ2U6IFwic3RyaW5nP1wiLFxuICAgICAgICAgIHBsYXRmb3JtOiBcImpzb24/XCIsXG4gICAgICAgICAgdGltZXpvbmU6IFwic3RyaW5nP1wiLFxuICAgICAgICAgIHR5cGU6IFwic3RyaW5nP1wiLFxuICAgICAgICAgIHZlcnNpb246IFwic3RyaW5nP1wiLFxuICAgICAgICB9LFxuICAgICAgfSBhcyBjb25zdCxcbiAgICAgIFwicm9vdFwiLFxuICAgICAgXCJSZXF1ZXN0XCIsXG4gICAgICBKU09OLnBhcnNlKGJvZHkpLFxuICAgICk7XG5cbiAgICBjb25zdCBkZXZpY2VJZCA9IHBhcnNlZC5kZXZpY2UuaWQgPz8gcmFuZG9tQnl0ZXMoMjApLnRvU3RyaW5nKFwiaGV4XCIpO1xuXG4gICAgaWYgKCFwYXJzZWQuYXJncyB8fCBBcnJheS5pc0FycmF5KHBhcnNlZC5hcmdzKSB8fCB0eXBlb2YgcGFyc2VkLmFyZ3MgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkV4cGVjdGVkICdhcmdzJyB0byBiZSBhbiBvYmplY3RcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFyZ3M6IHBhcnNlZC5hcmdzLFxuICAgICAgZGV2aWNlSW5mbzoge1xuICAgICAgICBmaW5nZXJwcmludDogcGFyc2VkLmRldmljZS5maW5nZXJwcmludCxcbiAgICAgICAgaWQ6IGRldmljZUlkLFxuICAgICAgICBsYW5ndWFnZTogcGFyc2VkLmRldmljZS5sYW5ndWFnZSxcbiAgICAgICAgcGxhdGZvcm06IHBhcnNlZC5kZXZpY2UucGxhdGZvcm0sXG4gICAgICAgIHRpbWV6b25lOiBwYXJzZWQuZGV2aWNlLnRpbWV6b25lLFxuICAgICAgICB0eXBlOiBwYXJzZWQuZGV2aWNlLnR5cGUgPz8gKHR5cGVvZiBwYXJzZWQuZGV2aWNlLnBsYXRmb3JtID09PSBcInN0cmluZ1wiID8gcGFyc2VkLmRldmljZS5wbGF0Zm9ybSA6IFwiXCIpLFxuICAgICAgICB2ZXJzaW9uOiBwYXJzZWQuZGV2aWNlLnZlcnNpb24sXG4gICAgICB9LFxuICAgICAgZXh0cmE6IHt9LFxuICAgICAgZmlsZXM6IFtdLFxuICAgICAgaGVhZGVyczogcmVxLmhlYWRlcnMsXG4gICAgICBpZDogYCR7ZGV2aWNlSWR9LSR7cGFyc2VkLmlkfWAsXG4gICAgICBpcCxcbiAgICAgIG5hbWU6IHBhcnNlZC5uYW1lLFxuICAgICAgdmVyc2lvbjogMSxcbiAgICB9O1xuICB9XG5cbiAgLy8gTWF4aW1hIHNka2dlbiBmb3JtYXRcbiAgcHJpdmF0ZSBwYXJzZVJlcXVlc3RWMihyZXE6IEluY29taW5nTWVzc2FnZSwgYm9keTogc3RyaW5nLCBpcDogc3RyaW5nKTogQ29udGV4dFJlcXVlc3Qge1xuICAgIGNvbnN0IHBhcnNlZCA9IGRlY29kZShcbiAgICAgIHtcbiAgICAgICAgUmVxdWVzdDoge1xuICAgICAgICAgIGFyZ3M6IFwianNvblwiLFxuICAgICAgICAgIGRldmljZUZpbmdlcnByaW50OiBcInN0cmluZz9cIixcbiAgICAgICAgICBkZXZpY2VJZDogXCJzdHJpbmdcIixcbiAgICAgICAgICBpbmZvOiBcIlJlcXVlc3RJbmZvXCIsXG4gICAgICAgICAgbmFtZTogXCJzdHJpbmdcIixcbiAgICAgICAgICBwYXJ0bmVySWQ6IFwic3RyaW5nP1wiLFxuICAgICAgICAgIHJlcXVlc3RJZDogXCJzdHJpbmc/XCIsXG4gICAgICAgICAgc2Vzc2lvbklkOiBcInN0cmluZz9cIixcbiAgICAgICAgfSxcbiAgICAgICAgUmVxdWVzdEluZm86IHtcbiAgICAgICAgICBicm93c2VyVXNlckFnZW50OiBcInN0cmluZz9cIixcbiAgICAgICAgICBsYW5ndWFnZTogXCJzdHJpbmdcIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICB9LFxuICAgICAgfSBhcyBjb25zdCxcbiAgICAgIFwicm9vdFwiLFxuICAgICAgXCJSZXF1ZXN0XCIsXG4gICAgICBKU09OLnBhcnNlKGJvZHkpLFxuICAgICk7XG5cbiAgICBpZiAoIXBhcnNlZC5hcmdzIHx8IEFycmF5LmlzQXJyYXkocGFyc2VkLmFyZ3MpIHx8IHR5cGVvZiBwYXJzZWQuYXJncyAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgJ2FyZ3MnIHRvIGJlIGFuIG9iamVjdFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYXJnczogcGFyc2VkLmFyZ3MsXG4gICAgICBkZXZpY2VJbmZvOiB7XG4gICAgICAgIGZpbmdlcnByaW50OiBwYXJzZWQuZGV2aWNlRmluZ2VycHJpbnQsXG4gICAgICAgIGlkOiBwYXJzZWQuZGV2aWNlSWQsXG4gICAgICAgIGxhbmd1YWdlOiBwYXJzZWQuaW5mby5sYW5ndWFnZSxcbiAgICAgICAgcGxhdGZvcm06IHtcbiAgICAgICAgICBicm93c2VyVXNlckFnZW50OiBwYXJzZWQuaW5mby5icm93c2VyVXNlckFnZW50ID8/IG51bGwsXG4gICAgICAgIH0sXG4gICAgICAgIHRpbWV6b25lOiBudWxsLFxuICAgICAgICB0eXBlOiBwYXJzZWQuaW5mby50eXBlLFxuICAgICAgICB2ZXJzaW9uOiBcIlwiLFxuICAgICAgfSxcbiAgICAgIGV4dHJhOiB7XG4gICAgICAgIHBhcnRuZXJJZDogcGFyc2VkLnBhcnRuZXJJZCxcbiAgICAgICAgc2Vzc2lvbklkOiBwYXJzZWQuc2Vzc2lvbklkLFxuICAgICAgfSxcbiAgICAgIGZpbGVzOiBbXSxcbiAgICAgIGhlYWRlcnM6IHJlcS5oZWFkZXJzLFxuICAgICAgaWQ6IGAke3BhcnNlZC5kZXZpY2VJZH0tJHtwYXJzZWQucmVxdWVzdElkID8/IHJhbmRvbUJ5dGVzKDE2KS50b1N0cmluZyhcImhleFwiKX1gLFxuICAgICAgaXAsXG4gICAgICBuYW1lOiBwYXJzZWQubmFtZSxcbiAgICAgIHZlcnNpb246IDIsXG4gICAgfTtcbiAgfVxuXG4gIC8vIE5ldyBzZGtnZW4gZm9ybWF0XG4gIHByaXZhdGUgcGFyc2VSZXF1ZXN0VjMocmVxOiBJbmNvbWluZ01lc3NhZ2UsIGJvZHk6IHN0cmluZywgaXA6IHN0cmluZyk6IENvbnRleHRSZXF1ZXN0IHtcbiAgICBjb25zdCBwYXJzZWQgPSBkZWNvZGUoXG4gICAgICB7XG4gICAgICAgIERldmljZUluZm86IHtcbiAgICAgICAgICBmaW5nZXJwcmludDogXCJzdHJpbmc/XCIsXG4gICAgICAgICAgaWQ6IFwic3RyaW5nP1wiLFxuICAgICAgICAgIGxhbmd1YWdlOiBcInN0cmluZz9cIixcbiAgICAgICAgICBwbGF0Zm9ybTogXCJqc29uP1wiLFxuICAgICAgICAgIHRpbWV6b25lOiBcInN0cmluZz9cIixcbiAgICAgICAgICB0eXBlOiBcInN0cmluZz9cIixcbiAgICAgICAgICB2ZXJzaW9uOiBcInN0cmluZz9cIixcbiAgICAgICAgfSxcbiAgICAgICAgUmVxdWVzdDoge1xuICAgICAgICAgIGFyZ3M6IFwianNvblwiLFxuICAgICAgICAgIGRldmljZUluZm86IFwiRGV2aWNlSW5mbz9cIixcbiAgICAgICAgICBleHRyYTogXCJqc29uP1wiLFxuICAgICAgICAgIG5hbWU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgcmVxdWVzdElkOiBcInN0cmluZz9cIixcbiAgICAgICAgfSxcbiAgICAgIH0gYXMgY29uc3QsXG4gICAgICBcInJvb3RcIixcbiAgICAgIFwiUmVxdWVzdFwiLFxuICAgICAgSlNPTi5wYXJzZShib2R5KSxcbiAgICApO1xuXG4gICAgY29uc3QgZGV2aWNlSW5mbyA9IHBhcnNlZC5kZXZpY2VJbmZvID8/IHtcbiAgICAgIGZpbmdlcnByaW50OiBudWxsLFxuICAgICAgaWQ6IG51bGwsXG4gICAgICBsYW5ndWFnZTogbnVsbCxcbiAgICAgIHBsYXRmb3JtOiBudWxsLFxuICAgICAgdGltZXpvbmU6IG51bGwsXG4gICAgICB0eXBlOiBudWxsLFxuICAgICAgdmVyc2lvbjogbnVsbCxcbiAgICB9O1xuICAgIGNvbnN0IGRldmljZUlkID0gZGV2aWNlSW5mby5pZCA/PyByYW5kb21CeXRlcygxNikudG9TdHJpbmcoXCJoZXhcIik7XG5cbiAgICBpZiAoIXBhcnNlZC5hcmdzIHx8IEFycmF5LmlzQXJyYXkocGFyc2VkLmFyZ3MpIHx8IHR5cGVvZiBwYXJzZWQuYXJncyAhPT0gXCJvYmplY3RcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRXhwZWN0ZWQgJ2FyZ3MnIHRvIGJlIGFuIG9iamVjdFwiKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgYXJnczogcGFyc2VkLmFyZ3MsXG4gICAgICBkZXZpY2VJbmZvOiB7XG4gICAgICAgIGZpbmdlcnByaW50OiBkZXZpY2VJbmZvLmZpbmdlcnByaW50LFxuICAgICAgICBpZDogZGV2aWNlSWQsXG4gICAgICAgIGxhbmd1YWdlOiBkZXZpY2VJbmZvLmxhbmd1YWdlLFxuICAgICAgICBwbGF0Zm9ybTogdHlwZW9mIGRldmljZUluZm8ucGxhdGZvcm0gPT09IFwib2JqZWN0XCIgPyB7IC4uLmRldmljZUluZm8ucGxhdGZvcm0gfSA6IHt9LFxuICAgICAgICB0aW1lem9uZTogZGV2aWNlSW5mby50aW1lem9uZSxcbiAgICAgICAgdHlwZTogZGV2aWNlSW5mby50eXBlID8/IFwiYXBpXCIsXG4gICAgICAgIHZlcnNpb246IGRldmljZUluZm8udmVyc2lvbixcbiAgICAgIH0sXG4gICAgICBleHRyYTogdHlwZW9mIHBhcnNlZC5leHRyYSA9PT0gXCJvYmplY3RcIiA/IHsgLi4ucGFyc2VkLmV4dHJhIH0gOiB7fSxcbiAgICAgIGZpbGVzOiBbXSxcbiAgICAgIGhlYWRlcnM6IHJlcS5oZWFkZXJzLFxuICAgICAgaWQ6IGAke2RldmljZUlkfS0ke3BhcnNlZC5yZXF1ZXN0SWQgPz8gcmFuZG9tQnl0ZXMoMTYpLnRvU3RyaW5nKFwiaGV4XCIpfWAsXG4gICAgICBpcCxcbiAgICAgIG5hbWU6IHBhcnNlZC5uYW1lLFxuICAgICAgdmVyc2lvbjogMyxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBtYWtlUmVzcG9uc2VFcnJvcihlcnI6IHVua25vd24pOiB7IG1lc3NhZ2U6IHN0cmluZzsgdHlwZTogc3RyaW5nOyBkYXRhOiB1bmtub3duIH0ge1xuICAgIGxldCB0eXBlID0gXCJGYXRhbFwiO1xuXG4gICAgaWYgKHR5cGVvZiBlcnIgPT09IFwib2JqZWN0XCIgJiYgZXJyICE9PSBudWxsICYmIGhhcyhlcnIsIFwidHlwZVwiKSAmJiB0eXBlb2YgZXJyLnR5cGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICh7IHR5cGUgfSA9IGVycik7XG4gICAgfVxuXG4gICAgbGV0IG1lc3NhZ2U6IHN0cmluZztcblxuICAgIGlmICh0eXBlb2YgZXJyID09PSBcIm9iamVjdFwiICYmIGVyciAhPT0gbnVsbCAmJiBoYXMoZXJyLCBcIm1lc3NhZ2VcIikgJiYgdHlwZW9mIGVyci5tZXNzYWdlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAoeyBtZXNzYWdlIH0gPSBlcnIpO1xuICAgIH0gZWxzZSBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIG1lc3NhZ2UgPSBlcnIudG9TdHJpbmcoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBlcnIgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIG1lc3NhZ2UgPSBKU09OLnN0cmluZ2lmeShlcnIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtZXNzYWdlID0gYCR7ZXJyfWA7XG4gICAgfVxuXG4gICAgbGV0IGRhdGE6IHVua25vd247XG5cbiAgICBpZiAodHlwZW9mIGVyciA9PT0gXCJvYmplY3RcIiAmJiBlcnIgIT09IG51bGwgJiYgaGFzKGVyciwgXCJkYXRhXCIpKSB7XG4gICAgICAoeyBkYXRhIH0gPSBlcnIpO1xuICAgIH1cblxuICAgIGNvbnN0IGVycm9yID0gdGhpcy5hcGlDb25maWcuYXN0LmVycm9ycy5maW5kKHggPT4geC5uYW1lID09PSB0eXBlKTtcblxuICAgIGlmIChlcnJvcikge1xuICAgICAgaWYgKCEoZXJyb3IuZGF0YVR5cGUgaW5zdGFuY2VvZiBWb2lkUHJpbWl0aXZlVHlwZSkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkYXRhID0gZW5jb2RlKHRoaXMuYXBpQ29uZmlnLmFzdEpzb24udHlwZVRhYmxlLCBgZXJyb3IuJHt0eXBlfWAsIGVycm9yLmRhdGFUeXBlLm5hbWUsIGRhdGEpO1xuICAgICAgICB9IGNhdGNoIChlbmNvZGVFcnJvcikge1xuICAgICAgICAgIG1lc3NhZ2UgPSBgRmFpbGVkIHRvIGVuY29kZSBlcnJvciAke3R5cGV9IGJlY2F1c2U6ICR7ZW5jb2RlRXJyb3J9LiBPcmlnaW5hbCBtZXNzYWdlOiAke21lc3NhZ2V9YDtcbiAgICAgICAgICB0eXBlID0gXCJGYXRhbFwiO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHR5cGUgPSBcIkZhdGFsXCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZGF0YSwgbWVzc2FnZSwgdHlwZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSB3cml0ZVJlcGx5KHJlczogU2VydmVyUmVzcG9uc2UsIGN0eDogQ29udGV4dCB8IG51bGwsIHJlcGx5OiBDb250ZXh0UmVwbHksIGhyU3RhcnQ6IFtudW1iZXIsIG51bWJlcl0pIHtcbiAgICBpZiAoIWN0eCkge1xuICAgICAgcmVzLnN0YXR1c0NvZGUgPSA1MDA7XG4gICAgICByZXMud3JpdGUoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICBlcnJvcjogdGhpcy5tYWtlUmVzcG9uc2VFcnJvcihyZXBseS5lcnJvciA/PyBuZXcgRmF0YWwoXCJSZXNwb25zZSB3aXRob3V0IGNvbnRleHRcIikpLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICByZXMuZW5kKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGVsdGFUaW1lID0gcHJvY2Vzcy5ocnRpbWUoaHJTdGFydCk7XG4gICAgY29uc3QgZHVyYXRpb24gPSBkZWx0YVRpbWVbMF0gKyBkZWx0YVRpbWVbMV0gKiAxZS05O1xuXG4gICAgaWYgKHJlcGx5LmVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHJlcGx5LmVycm9yKTtcbiAgICB9XG5cbiAgICB0aGlzLmxvZyhgJHtjdHgucmVxdWVzdC5pZH0gWyR7ZHVyYXRpb24udG9GaXhlZCg2KX1zXSAke2N0eC5yZXF1ZXN0Lm5hbWV9KCkgLT4gJHtyZXBseS5lcnJvciA/IHRoaXMubWFrZVJlc3BvbnNlRXJyb3IocmVwbHkuZXJyb3IpLnR5cGUgOiBcIk9LXCJ9YCk7XG5cbiAgICBpZiAoY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGUpIHtcbiAgICAgIHJlcy5zdGF0dXNDb2RlID0gY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbaGVhZGVyS2V5LCBoZWFkZXJWYWx1ZV0gb2YgY3R4LnJlc3BvbnNlLmhlYWRlcnMuZW50cmllcygpKSB7XG4gICAgICByZXMuc2V0SGVhZGVyKGhlYWRlcktleSwgaGVhZGVyVmFsdWUpO1xuICAgIH1cblxuICAgIHN3aXRjaCAoY3R4LnJlcXVlc3QudmVyc2lvbikge1xuICAgICAgY2FzZSAxOiB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgICAgIGRldmljZUlkOiBjdHgucmVxdWVzdC5kZXZpY2VJbmZvLmlkLFxuICAgICAgICAgIGR1cmF0aW9uLFxuICAgICAgICAgIGVycm9yOiByZXBseS5lcnJvciA/IHRoaXMubWFrZVJlc3BvbnNlRXJyb3IocmVwbHkuZXJyb3IpIDogbnVsbCxcbiAgICAgICAgICBob3N0OiBob3N0bmFtZSgpLFxuICAgICAgICAgIGlkOiBjdHgucmVxdWVzdC5pZCxcbiAgICAgICAgICBvazogIXJlcGx5LmVycm9yLFxuICAgICAgICAgIHJlc3VsdDogcmVwbHkuZXJyb3IgPyBudWxsIDogcmVwbHkucmVzdWx0LFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChyZXNwb25zZS5lcnJvciAmJiAhY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGUpIHtcbiAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IHRoaXMubWFrZVJlc3BvbnNlRXJyb3IocmVzcG9uc2UuZXJyb3IpLnR5cGUgPT09IFwiRmF0YWxcIiA/IDUwMCA6IDQwMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy53cml0ZShKU09OLnN0cmluZ2lmeShyZXNwb25zZSkpO1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBjYXNlIDI6IHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB7XG4gICAgICAgICAgZGV2aWNlSWQ6IGN0eC5yZXF1ZXN0LmRldmljZUluZm8uaWQsXG4gICAgICAgICAgZXJyb3I6IHJlcGx5LmVycm9yID8gdGhpcy5tYWtlUmVzcG9uc2VFcnJvcihyZXBseS5lcnJvcikgOiBudWxsLFxuICAgICAgICAgIG9rOiAhcmVwbHkuZXJyb3IsXG4gICAgICAgICAgcmVxdWVzdElkOiBjdHgucmVxdWVzdC5pZCxcbiAgICAgICAgICByZXN1bHQ6IHJlcGx5LmVycm9yID8gbnVsbCA6IHJlcGx5LnJlc3VsdCxcbiAgICAgICAgICBzZXNzaW9uSWQ6IGN0eC5yZXF1ZXN0LmV4dHJhLnNlc3Npb25JZCxcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAocmVzcG9uc2UuZXJyb3IgJiYgIWN0eC5yZXNwb25zZS5zdGF0dXNDb2RlKSB7XG4gICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSB0aGlzLm1ha2VSZXNwb25zZUVycm9yKHJlc3BvbnNlLmVycm9yKS50eXBlID09PSBcIkZhdGFsXCIgPyA1MDAgOiA0MDA7XG4gICAgICAgIH1cblxuICAgICAgICByZXMud3JpdGUoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAzOiB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0ge1xuICAgICAgICAgIGR1cmF0aW9uLFxuICAgICAgICAgIGVycm9yOiByZXBseS5lcnJvciA/IHRoaXMubWFrZVJlc3BvbnNlRXJyb3IocmVwbHkuZXJyb3IpIDogbnVsbCxcbiAgICAgICAgICBob3N0OiBob3N0bmFtZSgpLFxuICAgICAgICAgIHJlc3VsdDogcmVwbHkuZXJyb3IgPyBudWxsIDogcmVwbHkucmVzdWx0LFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChyZXNwb25zZS5lcnJvciAmJiAhY3R4LnJlc3BvbnNlLnN0YXR1c0NvZGUpIHtcbiAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IHRoaXMubWFrZVJlc3BvbnNlRXJyb3IocmVzcG9uc2UuZXJyb3IpLnR5cGUgPT09IFwiRmF0YWxcIiA/IDUwMCA6IDQwMDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlcy5zZXRIZWFkZXIoXCJ4LXJlcXVlc3QtaWRcIiwgY3R4LnJlcXVlc3QuaWQpO1xuICAgICAgICByZXMud3JpdGUoSlNPTi5zdHJpbmdpZnkocmVzcG9uc2UpKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDUwMDtcbiAgICAgICAgcmVzLndyaXRlKFxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgIGVycm9yOiB0aGlzLm1ha2VSZXNwb25zZUVycm9yKHJlcGx5LmVycm9yID8/IG5ldyBGYXRhbChcIlVua25vd24gcmVxdWVzdCB2ZXJzaW9uXCIpKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmVzLmVuZCgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iXX0=