@sdkgen/node-runtime 0.0.0-dev.20230106165109 → 0.0.0-dev.20230109111624
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/spec/error.spec.js +3 -4
- package/dist/spec/rest/rest.spec.js +24 -24
- package/dist/spec/runtime/errors.spec.js +15 -14
- package/dist/spec/runtime/middleware.spec.js +15 -14
- package/dist/spec/simple/legacyNodeClient.js +6 -32
- package/dist/spec/simple/simple.spec.js +27 -28
- package/dist/spec/types.js +27 -28
- package/dist/spec/types.spec.js +54 -55
- package/dist/src/api-config.js +4 -8
- package/dist/src/context.js +2 -2
- package/dist/src/encode-decode.js +12 -50
- package/dist/src/error.js +4 -9
- package/dist/src/execute.js +12 -14
- package/dist/src/http-client.js +25 -27
- package/dist/src/http-server.js +160 -170
- package/dist/src/index.js +8 -18
- package/dist/src/new-interface.js +200 -0
- package/dist/src/swagger.js +126 -115
- package/dist/src/test-wrapper.js +25 -23
- package/dist/src/utils.js +2 -5
- package/package.json +26 -22
- package/dist/spec/error.spec.d.ts +0 -1
- package/dist/spec/rest/rest.spec.d.ts +0 -1
- package/dist/spec/runtime/errors.spec.d.ts +0 -1
- package/dist/spec/runtime/middleware.spec.d.ts +0 -1
- package/dist/spec/simple/legacyNodeClient.d.ts +0 -17
- package/dist/spec/simple/simple.spec.d.ts +0 -1
- package/dist/spec/types.d.ts +0 -1
- package/dist/spec/types.spec.d.ts +0 -1
- package/dist/src/api-config.d.ts +0 -15
- package/dist/src/context.d.ts +0 -38
- package/dist/src/encode-decode.d.ts +0 -32
- package/dist/src/error.d.ts +0 -18
- package/dist/src/execute.d.ts +0 -3
- package/dist/src/http-client.d.ts +0 -17
- package/dist/src/http-server.d.ts +0 -37
- package/dist/src/index.d.ts +0 -7
- package/dist/src/swagger.d.ts +0 -2
- package/dist/src/test-wrapper.d.ts +0 -3
- package/dist/src/utils.d.ts +0 -6
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/src/http-server.js
CHANGED
|
@@ -1,36 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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 (
|
|
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 = (
|
|
87
|
-
this.httpServer =
|
|
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) =>
|
|
92
|
-
["/targets/android/client_without_callbacks.kt", (ast) =>
|
|
93
|
-
["/targets/dotnet/api.cs",
|
|
94
|
-
["/targets/dotnet/api.fs",
|
|
95
|
-
["/targets/flutter/client.dart",
|
|
96
|
-
["/targets/ios/client.swift", (ast) =>
|
|
97
|
-
["/targets/ios/client-rx.swift", (ast) =>
|
|
98
|
-
["/targets/node/api.ts",
|
|
99
|
-
["/targets/node/client.ts",
|
|
100
|
-
["/targets/web/client.ts",
|
|
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
|
-
(
|
|
133
|
+
staticFilesHandler(req, res, {
|
|
141
134
|
cleanUrls: false,
|
|
142
135
|
directoryListing: false,
|
|
143
136
|
etag: true,
|
|
144
|
-
public:
|
|
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
|
|
164
|
-
if (addr ===
|
|
165
|
-
|
|
156
|
+
let urlHost;
|
|
157
|
+
if (addr.address === "::") {
|
|
158
|
+
urlHost = `localhost:${addr.port}`;
|
|
166
159
|
}
|
|
167
|
-
else if (
|
|
168
|
-
|
|
160
|
+
else if (addr.family === "ipv6") {
|
|
161
|
+
urlHost = `[${addr.address}]:${addr.port}`;
|
|
169
162
|
}
|
|
170
163
|
else {
|
|
171
|
-
|
|
164
|
+
urlHost = `${addr.address}:${addr.port}`;
|
|
172
165
|
}
|
|
173
|
-
if (
|
|
174
|
-
console.log(`
|
|
175
|
-
|
|
176
|
-
|
|
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(`
|
|
173
|
+
console.log(`Playground: http://${urlHost}/playground`);
|
|
181
174
|
}
|
|
182
175
|
if (this.hasSwagger) {
|
|
183
|
-
console.log(`
|
|
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
|
|
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
|
|
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
|
|
248
|
+
if (!(ann instanceof RestAnnotation)) {
|
|
256
249
|
continue;
|
|
257
250
|
}
|
|
258
251
|
if (!this.hasSwagger) {
|
|
259
|
-
|
|
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 } = (
|
|
281
|
-
const match = pathname
|
|
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 ? (
|
|
284
|
+
const parsedQuery = query ? parseQuerystring(query) : {};
|
|
293
285
|
for (const argName of ann.queryVariables) {
|
|
294
|
-
const argValue =
|
|
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 =
|
|
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 &&
|
|
308
|
-
const parsedBody = (
|
|
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 =
|
|
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 &&
|
|
318
|
-
const busboy = (
|
|
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 =
|
|
327
|
-
const writeStream =
|
|
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 =
|
|
323
|
+
const contents = createReadStream(tempName);
|
|
332
324
|
files.push({ contents, name: info.filename });
|
|
333
325
|
contents.on("open", () => {
|
|
334
|
-
|
|
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(
|
|
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
|
|
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
|
|
376
|
-
type instanceof
|
|
377
|
-
type instanceof
|
|
378
|
-
type instanceof
|
|
379
|
-
type instanceof
|
|
380
|
-
type instanceof
|
|
381
|
-
type instanceof
|
|
382
|
-
type instanceof
|
|
383
|
-
type instanceof
|
|
384
|
-
type instanceof
|
|
385
|
-
type instanceof
|
|
386
|
-
type instanceof
|
|
387
|
-
type instanceof
|
|
388
|
-
type instanceof
|
|
389
|
-
type instanceof
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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:
|
|
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:
|
|
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
|
|
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 (!
|
|
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
|
|
483
|
+
if (type instanceof OptionalType) {
|
|
492
484
|
if (reply.result === null) {
|
|
493
|
-
if (!
|
|
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
|
|
502
|
-
type instanceof
|
|
503
|
-
type instanceof
|
|
504
|
-
type instanceof
|
|
505
|
-
type instanceof
|
|
506
|
-
type instanceof
|
|
507
|
-
type instanceof
|
|
508
|
-
type instanceof
|
|
509
|
-
type instanceof
|
|
510
|
-
type instanceof
|
|
511
|
-
type instanceof
|
|
512
|
-
type instanceof
|
|
513
|
-
type instanceof
|
|
514
|
-
type instanceof
|
|
515
|
-
type instanceof
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
525
|
+
fileTypeFromBuffer(buffer)
|
|
534
526
|
.then(fileType => {
|
|
535
|
-
|
|
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
|
-
|
|
577
|
-
|
|
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 (!
|
|
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 =
|
|
614
|
+
const clientIp = getClientIp(req);
|
|
625
615
|
if (!clientIp) {
|
|
626
616
|
this.writeReply(res, null, {
|
|
627
|
-
error: new
|
|
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
|
|
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 =
|
|
631
|
+
const ctx = {
|
|
632
|
+
...this.extraContext,
|
|
633
|
+
request,
|
|
634
|
+
response: {
|
|
642
635
|
headers: new Map(),
|
|
643
|
-
}
|
|
644
|
-
|
|
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 &&
|
|
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 &&
|
|
657
|
+
else if (typeof parsed === "object" && parsed && has(parsed, "requestId")) {
|
|
664
658
|
return 2;
|
|
665
659
|
}
|
|
666
|
-
else if (typeof parsed === "object" && parsed &&
|
|
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
|
-
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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}-${
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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" ?
|
|
794
|
+
platform: typeof deviceInfo.platform === "object" ? { ...deviceInfo.platform } : {},
|
|
804
795
|
timezone: deviceInfo.timezone,
|
|
805
|
-
type:
|
|
796
|
+
type: deviceInfo.type ?? "api",
|
|
806
797
|
version: deviceInfo.version,
|
|
807
798
|
},
|
|
808
|
-
extra: typeof parsed.extra === "object" ?
|
|
799
|
+
extra: typeof parsed.extra === "object" ? { ...parsed.extra } : {},
|
|
809
800
|
files: [],
|
|
810
801
|
headers: req.headers,
|
|
811
|
-
id: `${deviceId}-${
|
|
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 &&
|
|
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 &&
|
|
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 &&
|
|
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
|
|
832
|
+
if (!(error.dataType instanceof VoidPrimitiveType)) {
|
|
842
833
|
try {
|
|
843
|
-
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(
|
|
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:
|
|
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:
|
|
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(
|
|
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=
|