every-plugin 0.4.10 → 0.4.11

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 (56) hide show
  1. package/dist/build/rspack/index.cjs +5 -5
  2. package/dist/build/rspack/index.mjs +4 -4
  3. package/dist/{errors-CVnoPl9v.cjs → errors-BEsEPXKG.cjs} +2 -2
  4. package/dist/errors-CpYzD_-M.d.cts +38 -0
  5. package/dist/errors-D2-thHKG.d.mts +38 -0
  6. package/dist/{errors-D7keKf7a.mjs → errors-DnigICIv.mjs} +2 -2
  7. package/dist/errors.cjs +2 -2
  8. package/dist/errors.d.cts +1 -2
  9. package/dist/errors.d.mts +1 -2
  10. package/dist/errors.mjs +2 -2
  11. package/dist/{fetch-Cc95-7kM.cjs → fetch-CGzn1Uf7.cjs} +2 -2
  12. package/dist/{fetch-KLktuWuM.mjs → fetch-ycs0raYN.mjs} +2 -2
  13. package/dist/{index-matrPV4m.d.cts → index-BXfi8DqC.d.cts} +1 -1
  14. package/dist/{index-bwAhA9ca.d.mts → index-DvIxKA8K.d.mts} +2 -2
  15. package/dist/index.cjs +4 -4
  16. package/dist/index.d.cts +3 -4
  17. package/dist/index.d.mts +3 -4
  18. package/dist/index.mjs +4 -4
  19. package/dist/{normalize-BLTyqFww.d.mts → normalize-BCE_FLe8.d.mts} +1 -1
  20. package/dist/{normalize-BW7kk8Lk.d.cts → normalize-Tt7I_RdD.d.cts} +1 -1
  21. package/dist/{package-J60H0cK8.cjs → package-C2Mp8qeD.cjs} +4 -3
  22. package/dist/{package-DVINhZcr.mjs → package-uEsV9Z-2.mjs} +4 -3
  23. package/dist/plugins-Cmsm3gW1.cjs +791 -0
  24. package/dist/plugins-hpi2GlaX.mjs +790 -0
  25. package/dist/runtime/index.cjs +2 -2
  26. package/dist/runtime/index.d.cts +3 -4
  27. package/dist/runtime/index.d.mts +3 -4
  28. package/dist/runtime/index.mjs +2 -2
  29. package/dist/runtime/services/normalize.d.cts +1 -1
  30. package/dist/runtime/services/normalize.d.mts +1 -1
  31. package/dist/{runtime-BShulKmh.mjs → runtime-BUQ0hy1J.mjs} +3 -3
  32. package/dist/{runtime-Yfumucan.cjs → runtime-LlP2xpdB.cjs} +3 -3
  33. package/dist/{standard-eUgUkWaf.cjs → standard-0wBehDUp.cjs} +1 -18
  34. package/dist/{standard-DaxKTFui.mjs → standard-CYaRay89.mjs} +2 -13
  35. package/dist/testing/index.cjs +2 -2
  36. package/dist/testing/index.d.cts +4 -5
  37. package/dist/testing/index.d.mts +4 -5
  38. package/dist/testing/index.mjs +2 -2
  39. package/dist/zod-BDDjyyHQ.mjs +10 -0
  40. package/dist/{zod-DYghWCz1.cjs → zod-CJY4vNLR.cjs} +2 -2
  41. package/dist/zod.cjs +4 -4
  42. package/dist/zod.d.cts +1 -2
  43. package/dist/zod.d.mts +1 -2
  44. package/dist/zod.mjs +2 -2
  45. package/package.json +3 -2
  46. package/dist/errors-Car4tFVP.d.mts +0 -75
  47. package/dist/errors-DKPPPYYT.d.cts +0 -75
  48. package/dist/openapi.DrTcell5-C6kyDyUK.mjs +0 -669
  49. package/dist/openapi.DrTcell5-DDf4D5V3.cjs +0 -687
  50. package/dist/plugins-C-7lh5gK.cjs +0 -128
  51. package/dist/plugins-Ps5Xxpk2.mjs +0 -128
  52. package/dist/zod-A7Pti5IV.d.cts +0 -4
  53. package/dist/zod-BVo51kgJ.mjs +0 -10
  54. package/dist/zod-D4CFw8d9.d.mts +0 -4
  55. package/dist/zod4-BXTBR1od.cjs +0 -318
  56. package/dist/zod4-VpXuwRO7.mjs +0 -317
@@ -0,0 +1,791 @@
1
+ const require_chunk = require('./chunk-zltIcp7o.cjs');
2
+ const require_standard = require('./standard-0wBehDUp.cjs');
3
+ let __orpc_server = require("@orpc/server");
4
+ let __orpc_contract = require("@orpc/contract");
5
+
6
+ //#region ../../node_modules/.bun/@orpc+interop@1.10.4/node_modules/@orpc/interop/dist/json-schema-typed/index.mjs
7
+ var ContentEncoding;
8
+ (function(ContentEncoding1) {
9
+ ContentEncoding1["7bit"] = "7bit";
10
+ ContentEncoding1["8bit"] = "8bit";
11
+ ContentEncoding1["Base64"] = "base64";
12
+ ContentEncoding1["Binary"] = "binary";
13
+ ContentEncoding1["IETFToken"] = "ietf-token";
14
+ ContentEncoding1["QuotedPrintable"] = "quoted-printable";
15
+ ContentEncoding1["XToken"] = "x-token";
16
+ })(ContentEncoding || (ContentEncoding = {}));
17
+ var Format;
18
+ (function(Format1) {
19
+ Format1["Date"] = "date";
20
+ Format1["DateTime"] = "date-time";
21
+ Format1["Duration"] = "duration";
22
+ Format1["Email"] = "email";
23
+ Format1["Hostname"] = "hostname";
24
+ Format1["IDNEmail"] = "idn-email";
25
+ Format1["IDNHostname"] = "idn-hostname";
26
+ Format1["IPv4"] = "ipv4";
27
+ Format1["IPv6"] = "ipv6";
28
+ Format1["IRI"] = "iri";
29
+ Format1["IRIReference"] = "iri-reference";
30
+ Format1["JSONPointer"] = "json-pointer";
31
+ Format1["JSONPointerURIFragment"] = "json-pointer-uri-fragment";
32
+ Format1["RegEx"] = "regex";
33
+ Format1["RelativeJSONPointer"] = "relative-json-pointer";
34
+ Format1["Time"] = "time";
35
+ Format1["URI"] = "uri";
36
+ Format1["URIReference"] = "uri-reference";
37
+ Format1["URITemplate"] = "uri-template";
38
+ Format1["UUID"] = "uuid";
39
+ })(Format || (Format = {}));
40
+ var TypeName;
41
+ (function(TypeName1) {
42
+ TypeName1["Array"] = "array";
43
+ TypeName1["Boolean"] = "boolean";
44
+ TypeName1["Integer"] = "integer";
45
+ TypeName1["Null"] = "null";
46
+ TypeName1["Number"] = "number";
47
+ TypeName1["Object"] = "object";
48
+ TypeName1["String"] = "string";
49
+ })(TypeName || (TypeName = {}));
50
+
51
+ //#endregion
52
+ //#region ../../node_modules/.bun/@orpc+openapi@1.10.4/node_modules/@orpc/openapi/dist/shared/openapi.DrTcell5.mjs
53
+ const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
54
+ function getCustomOpenAPIOperation(o) {
55
+ return o[OPERATION_EXTENDER_SYMBOL];
56
+ }
57
+ function applyCustomOpenAPIOperation(operation, contract) {
58
+ const operationCustoms = [];
59
+ for (const errorItem of Object.values(contract["~orpc"].errorMap)) {
60
+ const maybeExtender = errorItem ? getCustomOpenAPIOperation(errorItem) : void 0;
61
+ if (maybeExtender) operationCustoms.push(maybeExtender);
62
+ }
63
+ if ((0, __orpc_server.isProcedure)(contract)) for (const middleware of contract["~orpc"].middlewares) {
64
+ const maybeExtender = getCustomOpenAPIOperation(middleware);
65
+ if (maybeExtender) operationCustoms.push(maybeExtender);
66
+ }
67
+ let currentOperation = operation;
68
+ for (const custom of operationCustoms) if (typeof custom === "function") currentOperation = custom(currentOperation, contract);
69
+ else currentOperation = {
70
+ ...currentOperation,
71
+ ...custom
72
+ };
73
+ return currentOperation;
74
+ }
75
+ const LOGIC_KEYWORDS = [
76
+ "$dynamicRef",
77
+ "$ref",
78
+ "additionalItems",
79
+ "additionalProperties",
80
+ "allOf",
81
+ "anyOf",
82
+ "const",
83
+ "contains",
84
+ "contentEncoding",
85
+ "contentMediaType",
86
+ "contentSchema",
87
+ "dependencies",
88
+ "dependentRequired",
89
+ "dependentSchemas",
90
+ "else",
91
+ "enum",
92
+ "exclusiveMaximum",
93
+ "exclusiveMinimum",
94
+ "format",
95
+ "if",
96
+ "items",
97
+ "maxContains",
98
+ "maximum",
99
+ "maxItems",
100
+ "maxLength",
101
+ "maxProperties",
102
+ "minContains",
103
+ "minimum",
104
+ "minItems",
105
+ "minLength",
106
+ "minProperties",
107
+ "multipleOf",
108
+ "not",
109
+ "oneOf",
110
+ "pattern",
111
+ "patternProperties",
112
+ "prefixItems",
113
+ "properties",
114
+ "propertyNames",
115
+ "required",
116
+ "then",
117
+ "type",
118
+ "unevaluatedItems",
119
+ "unevaluatedProperties",
120
+ "uniqueItems"
121
+ ];
122
+ function isFileSchema(schema) {
123
+ return require_standard.isObject(schema) && schema.type === "string" && typeof schema.contentMediaType === "string";
124
+ }
125
+ function isObjectSchema(schema) {
126
+ return require_standard.isObject(schema) && schema.type === "object";
127
+ }
128
+ function isAnySchema(schema) {
129
+ if (schema === true) return true;
130
+ if (Object.keys(schema).every((k) => !LOGIC_KEYWORDS.includes(k))) return true;
131
+ return false;
132
+ }
133
+ function separateObjectSchema(schema, separatedProperties) {
134
+ if (Object.keys(schema).some((k) => ![
135
+ "type",
136
+ "properties",
137
+ "required",
138
+ "additionalProperties"
139
+ ].includes(k) && LOGIC_KEYWORDS.includes(k) && schema[k] !== void 0)) return [{ type: "object" }, schema];
140
+ const matched = { ...schema };
141
+ const rest = { ...schema };
142
+ matched.properties = separatedProperties.reduce((acc, key) => {
143
+ const keySchema = schema.properties?.[key] ?? schema.additionalProperties;
144
+ if (keySchema !== void 0) acc[key] = keySchema;
145
+ return acc;
146
+ }, {});
147
+ matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
148
+ matched.examples = schema.examples?.map((example) => {
149
+ if (!require_standard.isObject(example)) return example;
150
+ return Object.entries(example).reduce((acc, [key, value$1]) => {
151
+ if (separatedProperties.includes(key)) acc[key] = value$1;
152
+ return acc;
153
+ }, {});
154
+ });
155
+ rest.properties = schema.properties && Object.entries(schema.properties).filter(([key]) => !separatedProperties.includes(key)).reduce((acc, [key, value$1]) => {
156
+ acc[key] = value$1;
157
+ return acc;
158
+ }, {});
159
+ rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
160
+ rest.examples = schema.examples?.map((example) => {
161
+ if (!require_standard.isObject(example)) return example;
162
+ return Object.entries(example).reduce((acc, [key, value$1]) => {
163
+ if (!separatedProperties.includes(key)) acc[key] = value$1;
164
+ return acc;
165
+ }, {});
166
+ });
167
+ return [matched, rest];
168
+ }
169
+ function filterSchemaBranches(schema, check, matches = []) {
170
+ if (check(schema)) {
171
+ matches.push(schema);
172
+ return [matches, void 0];
173
+ }
174
+ if (require_standard.isObject(schema)) {
175
+ for (const keyword of ["anyOf", "oneOf"]) if (schema[keyword] && Object.keys(schema).every((k) => k === keyword || !LOGIC_KEYWORDS.includes(k))) {
176
+ const rest = schema[keyword].map((s) => filterSchemaBranches(s, check, matches)[1]).filter((v) => !!v);
177
+ if (rest.length === 1 && typeof rest[0] === "object") return [matches, {
178
+ ...schema,
179
+ [keyword]: void 0,
180
+ ...rest[0]
181
+ }];
182
+ return [matches, {
183
+ ...schema,
184
+ [keyword]: rest
185
+ }];
186
+ }
187
+ }
188
+ return [matches, schema];
189
+ }
190
+ function applySchemaOptionality(required, schema) {
191
+ if (required) return schema;
192
+ return { anyOf: [schema, { not: {} }] };
193
+ }
194
+ function expandUnionSchema(schema) {
195
+ if (typeof schema === "object") {
196
+ for (const keyword of ["anyOf", "oneOf"]) if (schema[keyword] && Object.keys(schema).every((k) => k === keyword || !LOGIC_KEYWORDS.includes(k))) return schema[keyword].flatMap((s) => expandUnionSchema(s));
197
+ }
198
+ return [schema];
199
+ }
200
+ function expandArrayableSchema(schema) {
201
+ const schemas = expandUnionSchema(schema);
202
+ if (schemas.length !== 2) return;
203
+ const arraySchema = schemas.find((s) => typeof s === "object" && s.type === "array" && Object.keys(s).filter((k) => LOGIC_KEYWORDS.includes(k)).every((k) => k === "type" || k === "items"));
204
+ if (arraySchema === void 0) return;
205
+ const items1 = arraySchema.items;
206
+ const items2 = schemas.find((s) => s !== arraySchema);
207
+ if (require_standard.stringifyJSON(items1) !== require_standard.stringifyJSON(items2)) return;
208
+ return [items2, arraySchema];
209
+ }
210
+ const PRIMITIVE_SCHEMA_TYPES = /* @__PURE__ */ new Set([
211
+ TypeName.String,
212
+ TypeName.Number,
213
+ TypeName.Integer,
214
+ TypeName.Boolean,
215
+ TypeName.Null
216
+ ]);
217
+ function isPrimitiveSchema(schema) {
218
+ return expandUnionSchema(schema).every((s) => {
219
+ if (typeof s === "boolean") return false;
220
+ if (typeof s.type === "string" && PRIMITIVE_SCHEMA_TYPES.has(s.type)) return true;
221
+ if (s.const !== void 0) return true;
222
+ return false;
223
+ });
224
+ }
225
+ function toOpenAPIPath(path) {
226
+ return require_standard.standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/{$1}");
227
+ }
228
+ function toOpenAPIMethod(method) {
229
+ return method.toLocaleLowerCase();
230
+ }
231
+ function toOpenAPIContent(schema) {
232
+ const content = {};
233
+ const [matches, restSchema] = filterSchemaBranches(schema, isFileSchema);
234
+ for (const file of matches) content[file.contentMediaType] = { schema: toOpenAPISchema(file) };
235
+ if (restSchema !== void 0) {
236
+ content["application/json"] = { schema: toOpenAPISchema(restSchema) };
237
+ if (require_standard.findDeepMatches((v) => require_standard.isObject(v) && isFileSchema(v), restSchema).values.length > 0) content["multipart/form-data"] = { schema: toOpenAPISchema(restSchema) };
238
+ }
239
+ return content;
240
+ }
241
+ function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema], [returnsRequired, returnsSchema]) {
242
+ return { "text/event-stream": { schema: toOpenAPISchema({ oneOf: [
243
+ {
244
+ type: "object",
245
+ properties: {
246
+ event: { const: "message" },
247
+ data: yieldsSchema,
248
+ id: { type: "string" },
249
+ retry: { type: "number" }
250
+ },
251
+ required: yieldsRequired ? ["event", "data"] : ["event"]
252
+ },
253
+ {
254
+ type: "object",
255
+ properties: {
256
+ event: { const: "done" },
257
+ data: returnsSchema,
258
+ id: { type: "string" },
259
+ retry: { type: "number" }
260
+ },
261
+ required: returnsRequired ? ["event", "data"] : ["event"]
262
+ },
263
+ {
264
+ type: "object",
265
+ properties: {
266
+ event: { const: "error" },
267
+ data: {},
268
+ id: { type: "string" },
269
+ retry: { type: "number" }
270
+ },
271
+ required: ["event"]
272
+ }
273
+ ] }) } };
274
+ }
275
+ function toOpenAPIParameters(schema, parameterIn) {
276
+ const parameters = [];
277
+ for (const key in schema.properties) {
278
+ const keySchema = schema.properties[key];
279
+ let isDeepObjectStyle = true;
280
+ if (parameterIn !== "query") isDeepObjectStyle = false;
281
+ else if (isPrimitiveSchema(keySchema)) isDeepObjectStyle = false;
282
+ else {
283
+ const [item] = expandArrayableSchema(keySchema) ?? [];
284
+ if (item !== void 0 && isPrimitiveSchema(item)) isDeepObjectStyle = false;
285
+ }
286
+ parameters.push({
287
+ name: key,
288
+ in: parameterIn,
289
+ required: schema.required?.includes(key),
290
+ schema: toOpenAPISchema(keySchema),
291
+ style: isDeepObjectStyle ? "deepObject" : void 0,
292
+ explode: isDeepObjectStyle ? true : void 0,
293
+ allowEmptyValue: parameterIn === "query" ? true : void 0,
294
+ allowReserved: parameterIn === "query" ? true : void 0
295
+ });
296
+ }
297
+ return parameters;
298
+ }
299
+ function checkParamsSchema(schema, params) {
300
+ const properties = Object.keys(schema.properties ?? {});
301
+ const required = schema.required ?? [];
302
+ if (properties.length !== params.length || properties.some((v) => !params.includes(v))) return false;
303
+ if (required.length !== params.length || required.some((v) => !params.includes(v))) return false;
304
+ return true;
305
+ }
306
+ function toOpenAPISchema(schema) {
307
+ return schema === true ? {} : schema === false ? { not: {} } : schema;
308
+ }
309
+ const OPENAPI_JSON_SCHEMA_REF_PREFIX = "#/components/schemas/";
310
+ function resolveOpenAPIJsonSchemaRef(doc, schema) {
311
+ if (typeof schema !== "object" || !schema.$ref?.startsWith(OPENAPI_JSON_SCHEMA_REF_PREFIX)) return schema;
312
+ const name = schema.$ref.slice(21);
313
+ return doc.components?.schemas?.[name] ?? schema;
314
+ }
315
+ var CompositeSchemaConverter = class {
316
+ converters;
317
+ constructor(converters) {
318
+ this.converters = converters;
319
+ }
320
+ async convert(schema, options) {
321
+ for (const converter of this.converters) if (await converter.condition(schema, options)) return converter.convert(schema, options);
322
+ return [false, {}];
323
+ }
324
+ };
325
+ var OpenAPIGeneratorError = class extends Error {};
326
+ var OpenAPIGenerator = class {
327
+ serializer;
328
+ converter;
329
+ constructor(options = {}) {
330
+ this.serializer = new require_standard.StandardOpenAPIJsonSerializer(options);
331
+ this.converter = new CompositeSchemaConverter(require_standard.toArray(options.schemaConverters));
332
+ }
333
+ /**
334
+ * Generates OpenAPI specifications from oRPC routers/contracts.
335
+ *
336
+ * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
337
+ */
338
+ async generate(router, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude,...baseDoc } = {}) {
339
+ const filter = baseFilter ?? (({ contract, path }) => {
340
+ return !(exclude?.(contract, path) ?? false);
341
+ });
342
+ const doc = {
343
+ ...require_standard.clone(baseDoc),
344
+ info: baseDoc.info ?? {
345
+ title: "API Reference",
346
+ version: "0.0.0"
347
+ },
348
+ openapi: "3.1.1"
349
+ };
350
+ const { baseSchemaConvertOptions, undefinedErrorJsonSchema } = await this.#resolveCommonSchemas(doc, commonSchemas);
351
+ const contracts = [];
352
+ await (0, __orpc_server.resolveContractProcedures)({
353
+ path: [],
354
+ router
355
+ }, (traverseOptions) => {
356
+ if (!require_standard.value(filter, traverseOptions)) return;
357
+ contracts.push(traverseOptions);
358
+ });
359
+ const errors = [];
360
+ for (const { contract, path } of contracts) {
361
+ const stringPath = path.join(".");
362
+ try {
363
+ const def = contract["~orpc"];
364
+ const method = toOpenAPIMethod((0, __orpc_contract.fallbackContractConfig)("defaultMethod", def.route.method));
365
+ const httpPath = toOpenAPIPath(def.route.path ?? require_standard.toHttpPath(path));
366
+ let operationObjectRef;
367
+ if (def.route.spec !== void 0 && typeof def.route.spec !== "function") operationObjectRef = def.route.spec;
368
+ else {
369
+ operationObjectRef = {
370
+ operationId: def.route.operationId ?? stringPath,
371
+ summary: def.route.summary,
372
+ description: def.route.description,
373
+ deprecated: def.route.deprecated,
374
+ tags: def.route.tags?.map((tag) => tag)
375
+ };
376
+ await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
377
+ await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
378
+ await this.#errorResponse(operationObjectRef, def, baseSchemaConvertOptions, undefinedErrorJsonSchema, customErrorResponseBodySchema);
379
+ }
380
+ if (typeof def.route.spec === "function") operationObjectRef = def.route.spec(operationObjectRef);
381
+ doc.paths ??= {};
382
+ doc.paths[httpPath] ??= {};
383
+ doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
384
+ } catch (e) {
385
+ if (!(e instanceof OpenAPIGeneratorError)) throw e;
386
+ errors.push(`[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
387
+ ${e.message}`);
388
+ }
389
+ }
390
+ if (errors.length) throw new OpenAPIGeneratorError(`Some error occurred during OpenAPI generation:
391
+
392
+ ${errors.join("\n\n")}`);
393
+ return this.serializer.serialize(doc)[0];
394
+ }
395
+ async #resolveCommonSchemas(doc, commonSchemas) {
396
+ let undefinedErrorJsonSchema = {
397
+ type: "object",
398
+ properties: {
399
+ defined: { const: false },
400
+ code: { type: "string" },
401
+ status: { type: "number" },
402
+ message: { type: "string" },
403
+ data: {}
404
+ },
405
+ required: [
406
+ "defined",
407
+ "code",
408
+ "status",
409
+ "message"
410
+ ]
411
+ };
412
+ const baseSchemaConvertOptions = {};
413
+ if (commonSchemas) {
414
+ baseSchemaConvertOptions.components = [];
415
+ for (const key in commonSchemas) {
416
+ const options = commonSchemas[key];
417
+ if (options.schema === void 0) continue;
418
+ const { schema, strategy = "input" } = options;
419
+ const [required, json] = await this.converter.convert(schema, { strategy });
420
+ const allowedStrategies = [strategy];
421
+ if (strategy === "input") {
422
+ const [outputRequired, outputJson] = await this.converter.convert(schema, { strategy: "output" });
423
+ if (outputRequired === required && require_standard.stringifyJSON(outputJson) === require_standard.stringifyJSON(json)) allowedStrategies.push("output");
424
+ } else if (strategy === "output") {
425
+ const [inputRequired, inputJson] = await this.converter.convert(schema, { strategy: "input" });
426
+ if (inputRequired === required && require_standard.stringifyJSON(inputJson) === require_standard.stringifyJSON(json)) allowedStrategies.push("input");
427
+ }
428
+ baseSchemaConvertOptions.components.push({
429
+ schema,
430
+ required,
431
+ ref: `#/components/schemas/${key}`,
432
+ allowedStrategies
433
+ });
434
+ }
435
+ doc.components ??= {};
436
+ doc.components.schemas ??= {};
437
+ for (const key in commonSchemas) {
438
+ const options = commonSchemas[key];
439
+ if (options.schema === void 0) {
440
+ if (options.error === "UndefinedError") {
441
+ doc.components.schemas[key] = toOpenAPISchema(undefinedErrorJsonSchema);
442
+ undefinedErrorJsonSchema = { $ref: `#/components/schemas/${key}` };
443
+ }
444
+ continue;
445
+ }
446
+ const { schema, strategy = "input" } = options;
447
+ const [, json] = await this.converter.convert(schema, {
448
+ ...baseSchemaConvertOptions,
449
+ strategy,
450
+ minStructureDepthForRef: 1
451
+ });
452
+ doc.components.schemas[key] = toOpenAPISchema(json);
453
+ }
454
+ }
455
+ return {
456
+ baseSchemaConvertOptions,
457
+ undefinedErrorJsonSchema
458
+ };
459
+ }
460
+ async #request(doc, ref, def, baseSchemaConvertOptions) {
461
+ const method = (0, __orpc_contract.fallbackContractConfig)("defaultMethod", def.route.method);
462
+ const details = (0, __orpc_contract.getEventIteratorSchemaDetails)(def.inputSchema);
463
+ if (details) {
464
+ ref.requestBody = {
465
+ required: true,
466
+ content: toOpenAPIEventIteratorContent(await this.converter.convert(details.yields, {
467
+ ...baseSchemaConvertOptions,
468
+ strategy: "input"
469
+ }), await this.converter.convert(details.returns, {
470
+ ...baseSchemaConvertOptions,
471
+ strategy: "input"
472
+ }))
473
+ };
474
+ return;
475
+ }
476
+ const dynamicParams = require_standard.getDynamicParams(def.route.path)?.map((v) => v.name);
477
+ const inputStructure = (0, __orpc_contract.fallbackContractConfig)("defaultInputStructure", def.route.inputStructure);
478
+ let [required, schema] = await this.converter.convert(def.inputSchema, {
479
+ ...baseSchemaConvertOptions,
480
+ strategy: "input",
481
+ minStructureDepthForRef: dynamicParams?.length || inputStructure === "detailed" ? 1 : 0
482
+ });
483
+ if (isAnySchema(schema) && !dynamicParams?.length) return;
484
+ if (inputStructure === "compact") {
485
+ if (dynamicParams?.length) {
486
+ const error2 = new OpenAPIGeneratorError("When input structure is \"compact\", and path has dynamic params, input schema must be an object with all dynamic params as required.");
487
+ if (!isObjectSchema(schema)) throw error2;
488
+ const [paramsSchema, rest] = separateObjectSchema(schema, dynamicParams);
489
+ schema = rest;
490
+ required = rest.required ? rest.required.length !== 0 : false;
491
+ if (!checkParamsSchema(paramsSchema, dynamicParams)) throw error2;
492
+ ref.parameters ??= [];
493
+ ref.parameters.push(...toOpenAPIParameters(paramsSchema, "path"));
494
+ }
495
+ if (method === "GET") {
496
+ const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, schema);
497
+ if (!isObjectSchema(resolvedSchema)) throw new OpenAPIGeneratorError("When method is \"GET\", input schema must satisfy: object | any | unknown");
498
+ ref.parameters ??= [];
499
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
500
+ } else ref.requestBody = {
501
+ required,
502
+ content: toOpenAPIContent(schema)
503
+ };
504
+ return;
505
+ }
506
+ const error = new OpenAPIGeneratorError("When input structure is \"detailed\", input schema must satisfy: { params?: Record<string, unknown>, query?: Record<string, unknown>, headers?: Record<string, unknown>, body?: unknown }");
507
+ if (!isObjectSchema(schema)) throw error;
508
+ const resolvedParamSchema = schema.properties?.params !== void 0 ? resolveOpenAPIJsonSchemaRef(doc, schema.properties.params) : void 0;
509
+ if (dynamicParams?.length && (resolvedParamSchema === void 0 || !isObjectSchema(resolvedParamSchema) || !checkParamsSchema(resolvedParamSchema, dynamicParams))) throw new OpenAPIGeneratorError("When input structure is \"detailed\" and path has dynamic params, the \"params\" schema must be an object with all dynamic params as required.");
510
+ for (const from of [
511
+ "params",
512
+ "query",
513
+ "headers"
514
+ ]) {
515
+ const fromSchema = schema.properties?.[from];
516
+ if (fromSchema !== void 0) {
517
+ const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, fromSchema);
518
+ if (!isObjectSchema(resolvedSchema)) throw error;
519
+ const parameterIn = from === "params" ? "path" : from === "headers" ? "header" : "query";
520
+ ref.parameters ??= [];
521
+ ref.parameters.push(...toOpenAPIParameters(resolvedSchema, parameterIn));
522
+ }
523
+ }
524
+ if (schema.properties?.body !== void 0) ref.requestBody = {
525
+ required: schema.required?.includes("body"),
526
+ content: toOpenAPIContent(schema.properties.body)
527
+ };
528
+ }
529
+ async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
530
+ const outputSchema = def.outputSchema;
531
+ const status = (0, __orpc_contract.fallbackContractConfig)("defaultSuccessStatus", def.route.successStatus);
532
+ const description = (0, __orpc_contract.fallbackContractConfig)("defaultSuccessDescription", def.route?.successDescription);
533
+ const eventIteratorSchemaDetails = (0, __orpc_contract.getEventIteratorSchemaDetails)(outputSchema);
534
+ const outputStructure = (0, __orpc_contract.fallbackContractConfig)("defaultOutputStructure", def.route.outputStructure);
535
+ if (eventIteratorSchemaDetails) {
536
+ ref.responses ??= {};
537
+ ref.responses[status] = {
538
+ description,
539
+ content: toOpenAPIEventIteratorContent(await this.converter.convert(eventIteratorSchemaDetails.yields, {
540
+ ...baseSchemaConvertOptions,
541
+ strategy: "output"
542
+ }), await this.converter.convert(eventIteratorSchemaDetails.returns, {
543
+ ...baseSchemaConvertOptions,
544
+ strategy: "output"
545
+ }))
546
+ };
547
+ return;
548
+ }
549
+ const [required, json] = await this.converter.convert(outputSchema, {
550
+ ...baseSchemaConvertOptions,
551
+ strategy: "output",
552
+ minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
553
+ });
554
+ if (outputStructure === "compact") {
555
+ ref.responses ??= {};
556
+ ref.responses[status] = { description };
557
+ ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
558
+ return;
559
+ }
560
+ const handledStatuses = /* @__PURE__ */ new Set();
561
+ for (const item of expandUnionSchema(json)) {
562
+ const error = new OpenAPIGeneratorError(`
563
+ When output structure is "detailed", output schema must satisfy:
564
+ {
565
+ status?: number, // must be a literal number and in the range of 200-399
566
+ headers?: Record<string, unknown>,
567
+ body?: unknown
568
+ }
569
+
570
+ But got: ${require_standard.stringifyJSON(item)}
571
+ `);
572
+ if (!isObjectSchema(item)) throw error;
573
+ let schemaStatus;
574
+ let schemaDescription;
575
+ if (item.properties?.status !== void 0) {
576
+ const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
577
+ if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || require_standard.isORPCErrorStatus(statusSchema.const)) throw error;
578
+ schemaStatus = statusSchema.const;
579
+ schemaDescription = statusSchema.description;
580
+ }
581
+ const itemStatus = schemaStatus ?? status;
582
+ const itemDescription = schemaDescription ?? description;
583
+ if (handledStatuses.has(itemStatus)) throw new OpenAPIGeneratorError(`
584
+ When output structure is "detailed", each success status must be unique.
585
+ But got status: ${itemStatus} used more than once.
586
+ `);
587
+ handledStatuses.add(itemStatus);
588
+ ref.responses ??= {};
589
+ ref.responses[itemStatus] = { description: itemDescription };
590
+ if (item.properties?.headers !== void 0) {
591
+ const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
592
+ if (!isObjectSchema(headersSchema)) throw error;
593
+ for (const key in headersSchema.properties) {
594
+ const headerSchema = headersSchema.properties[key];
595
+ if (headerSchema !== void 0) {
596
+ ref.responses[itemStatus].headers ??= {};
597
+ ref.responses[itemStatus].headers[key] = {
598
+ schema: toOpenAPISchema(headerSchema),
599
+ required: item.required?.includes("headers") && headersSchema.required?.includes(key)
600
+ };
601
+ }
602
+ }
603
+ }
604
+ if (item.properties?.body !== void 0) ref.responses[itemStatus].content = toOpenAPIContent(applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body));
605
+ }
606
+ }
607
+ async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema, customErrorResponseBodySchema) {
608
+ const errorMap = def.errorMap;
609
+ const errorResponsesByStatus = {};
610
+ for (const code in errorMap) {
611
+ const config = errorMap[code];
612
+ if (!config) continue;
613
+ const status = require_standard.fallbackORPCErrorStatus(code, config.status);
614
+ const defaultMessage = require_standard.fallbackORPCErrorMessage(code, config.message);
615
+ errorResponsesByStatus[status] ??= {
616
+ status,
617
+ definedErrorDefinitions: [],
618
+ errorSchemaVariants: []
619
+ };
620
+ const [dataRequired, dataSchema] = await this.converter.convert(config.data, {
621
+ ...baseSchemaConvertOptions,
622
+ strategy: "output"
623
+ });
624
+ errorResponsesByStatus[status].definedErrorDefinitions.push([
625
+ code,
626
+ defaultMessage,
627
+ dataRequired,
628
+ dataSchema
629
+ ]);
630
+ errorResponsesByStatus[status].errorSchemaVariants.push({
631
+ type: "object",
632
+ properties: {
633
+ defined: { const: true },
634
+ code: { const: code },
635
+ status: { const: status },
636
+ message: {
637
+ type: "string",
638
+ default: defaultMessage
639
+ },
640
+ data: dataSchema
641
+ },
642
+ required: dataRequired ? [
643
+ "defined",
644
+ "code",
645
+ "status",
646
+ "message",
647
+ "data"
648
+ ] : [
649
+ "defined",
650
+ "code",
651
+ "status",
652
+ "message"
653
+ ]
654
+ });
655
+ }
656
+ ref.responses ??= {};
657
+ for (const statusString in errorResponsesByStatus) {
658
+ const errorResponse = errorResponsesByStatus[statusString];
659
+ const customBodySchema = require_standard.value(customErrorResponseBodySchema, errorResponse.definedErrorDefinitions, errorResponse.status);
660
+ ref.responses[statusString] = {
661
+ description: statusString,
662
+ content: toOpenAPIContent(customBodySchema ?? { oneOf: [...errorResponse.errorSchemaVariants, undefinedErrorSchema] })
663
+ };
664
+ }
665
+ }
666
+ };
667
+
668
+ //#endregion
669
+ //#region ../../node_modules/.bun/@orpc+openapi@1.10.4/node_modules/@orpc/openapi/dist/plugins/index.mjs
670
+ var OpenAPIReferencePlugin = class {
671
+ generator;
672
+ specGenerateOptions;
673
+ specPath;
674
+ docsPath;
675
+ docsTitle;
676
+ docsHead;
677
+ docsProvider;
678
+ docsScriptUrl;
679
+ docsCssUrl;
680
+ docsConfig;
681
+ renderDocsHtml;
682
+ constructor(options = {}) {
683
+ this.specGenerateOptions = options.specGenerateOptions;
684
+ this.docsPath = options.docsPath ?? "/";
685
+ this.docsTitle = options.docsTitle ?? "API Reference";
686
+ this.docsConfig = options.docsConfig ?? void 0;
687
+ this.docsProvider = options.docsProvider ?? "scalar";
688
+ this.docsScriptUrl = options.docsScriptUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" : "https://cdn.jsdelivr.net/npm/@scalar/api-reference");
689
+ this.docsCssUrl = options.docsCssUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui.css" : void 0);
690
+ this.docsHead = options.docsHead ?? "";
691
+ this.specPath = options.specPath ?? "/spec.json";
692
+ this.generator = new OpenAPIGenerator(options);
693
+ const esc = (s) => s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
694
+ this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config, spec, docsProvider, cssUrl) => {
695
+ let body;
696
+ if (docsProvider === "swagger") {
697
+ const swaggerConfig = {
698
+ dom_id: "#app",
699
+ spec,
700
+ deepLinking: true,
701
+ presets: ["SwaggerUIBundle.presets.apis", "SwaggerUIBundle.presets.standalone"],
702
+ plugins: ["SwaggerUIBundle.plugins.DownloadUrl"],
703
+ ...config
704
+ };
705
+ body = `
706
+ <body>
707
+ <div id="app"></div>
708
+
709
+ <script src="${esc(scriptUrl)}"><\/script>
710
+
711
+ <script>
712
+ window.onload = () => {
713
+ window.ui = SwaggerUIBundle(${require_standard.stringifyJSON(swaggerConfig).replace(/"(SwaggerUIBundle\.[^"]+)"/g, "$1")})
714
+ }
715
+ <\/script>
716
+ </body>
717
+ `;
718
+ } else body = `
719
+ <body>
720
+ <div id="app" data-config="${esc(require_standard.stringifyJSON({
721
+ content: require_standard.stringifyJSON(spec),
722
+ ...config
723
+ }))}"></div>
724
+
725
+ <script src="${esc(scriptUrl)}"><\/script>
726
+
727
+ <script>
728
+ Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
729
+ <\/script>
730
+ </body>
731
+ `;
732
+ return `
733
+ <!doctype html>
734
+ <html>
735
+ <head>
736
+ <meta charset="utf-8" />
737
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
738
+ <title>${esc(title)}</title>
739
+ ${cssUrl ? `<link rel="stylesheet" type="text/css" href="${esc(cssUrl)}" />` : ""}
740
+ ${head}
741
+ </head>
742
+ ${body}
743
+ </html>
744
+ `;
745
+ });
746
+ }
747
+ init(options, router) {
748
+ options.interceptors ??= [];
749
+ options.interceptors.push(async (options2) => {
750
+ const res = await options2.next();
751
+ if (res.matched || options2.request.method !== "GET") return res;
752
+ const prefix = options2.prefix ?? "";
753
+ const requestPathname = options2.request.url.pathname.replace(/\/$/, "") || "/";
754
+ const docsUrl = new URL(`${prefix}${this.docsPath}`.replace(/\/$/, ""), options2.request.url.origin);
755
+ const specUrl = new URL(`${prefix}${this.specPath}`.replace(/\/$/, ""), options2.request.url.origin);
756
+ const generateSpec = require_standard.once(async () => {
757
+ return await this.generator.generate(router, {
758
+ servers: [{ url: new URL(prefix, options2.request.url.origin).toString() }],
759
+ ...await require_standard.value(this.specGenerateOptions, options2)
760
+ });
761
+ });
762
+ if (requestPathname === specUrl.pathname) {
763
+ const spec = await generateSpec();
764
+ return {
765
+ matched: true,
766
+ response: {
767
+ status: 200,
768
+ headers: {},
769
+ body: new File([require_standard.stringifyJSON(spec)], "spec.json", { type: "application/json" })
770
+ }
771
+ };
772
+ }
773
+ if (requestPathname === docsUrl.pathname) {
774
+ const html = this.renderDocsHtml(specUrl.toString(), await require_standard.value(this.docsTitle, options2), await require_standard.value(this.docsHead, options2), await require_standard.value(this.docsScriptUrl, options2), await require_standard.value(this.docsConfig, options2), await generateSpec(), this.docsProvider, await require_standard.value(this.docsCssUrl, options2));
775
+ return {
776
+ matched: true,
777
+ response: {
778
+ status: 200,
779
+ headers: {},
780
+ body: new File([html], "api-reference.html", { type: "text/html" })
781
+ }
782
+ };
783
+ }
784
+ return res;
785
+ });
786
+ }
787
+ };
788
+
789
+ //#endregion
790
+ exports.OpenAPIReferencePlugin = OpenAPIReferencePlugin;
791
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy1DbXNtM2dXMS5janMiLCJuYW1lcyI6WyJpc09iamVjdCIsInZhbHVlIiwic3RyaW5naWZ5SlNPTiIsInN0YW5kYXJkaXplSFRUUFBhdGgiLCJmaW5kRGVlcE1hdGNoZXMiLCJTdGFuZGFyZE9wZW5BUElKc29uU2VyaWFsaXplciIsInRvQXJyYXkiLCJjbG9uZSIsIiNyZXNvbHZlQ29tbW9uU2NoZW1hcyIsInRvSHR0cFBhdGgiLCIjcmVxdWVzdCIsIiNzdWNjZXNzUmVzcG9uc2UiLCIjZXJyb3JSZXNwb25zZSIsImdldER5bmFtaWNQYXJhbXMiLCJpc09SUENFcnJvclN0YXR1cyIsImZhbGxiYWNrT1JQQ0Vycm9yU3RhdHVzIiwiZmFsbGJhY2tPUlBDRXJyb3JNZXNzYWdlIiwic3RyaW5naWZ5SlNPTiIsIm9uY2UiLCJ2YWx1ZSJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8uYnVuL0BvcnBjK2ludGVyb3BAMS4xMC40L25vZGVfbW9kdWxlcy9Ab3JwYy9pbnRlcm9wL2Rpc3QvanNvbi1zY2hlbWEtdHlwZWQvaW5kZXgubWpzIiwiLi4vLi4vLi4vbm9kZV9tb2R1bGVzLy5idW4vQG9ycGMrb3BlbmFwaUAxLjEwLjQvbm9kZV9tb2R1bGVzL0BvcnBjL29wZW5hcGkvZGlzdC9zaGFyZWQvb3BlbmFwaS5EclRjZWxsNS5tanMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLmJ1bi9Ab3JwYytvcGVuYXBpQDEuMTAuNC9ub2RlX21vZHVsZXMvQG9ycGMvb3BlbmFwaS9kaXN0L3BsdWdpbnMvaW5kZXgubWpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHR5cGVzPVwiLi9kcmFmdC0yMDIwLTEyLnRzXCIgLz5cbi8vIEBnZW5lcmF0ZWRcbi8vIGRlbm8tZm10LWlnbm9yZS1maWxlXG4vLyBkZW5vLWxpbnQtaWdub3JlLWZpbGVcbi8vIFRoaXMgY29kZSB3YXMgYnVuZGxlZCB1c2luZyBgZGVubyBidW5kbGVgIGFuZCBpdCdzIG5vdCByZWNvbW1lbmRlZCB0byBlZGl0IGl0IG1hbnVhbGx5XG5cbmNvbnN0IGRyYWZ0ID0gXCIyMDIwLTEyXCI7XG5jb25zdCAkc2NoZW1hID0gXCJodHRwczovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC8yMDIwLTEyL3NjaGVtYVwiO1xudmFyIENvbnRlbnRFbmNvZGluZztcbihmdW5jdGlvbihDb250ZW50RW5jb2RpbmcxKSB7XG4gICAgQ29udGVudEVuY29kaW5nMVtcIjdiaXRcIl0gPSBcIjdiaXRcIjtcbiAgICBDb250ZW50RW5jb2RpbmcxW1wiOGJpdFwiXSA9IFwiOGJpdFwiO1xuICAgIENvbnRlbnRFbmNvZGluZzFbXCJCYXNlNjRcIl0gPSBcImJhc2U2NFwiO1xuICAgIENvbnRlbnRFbmNvZGluZzFbXCJCaW5hcnlcIl0gPSBcImJpbmFyeVwiO1xuICAgIENvbnRlbnRFbmNvZGluZzFbXCJJRVRGVG9rZW5cIl0gPSBcImlldGYtdG9rZW5cIjtcbiAgICBDb250ZW50RW5jb2RpbmcxW1wiUXVvdGVkUHJpbnRhYmxlXCJdID0gXCJxdW90ZWQtcHJpbnRhYmxlXCI7XG4gICAgQ29udGVudEVuY29kaW5nMVtcIlhUb2tlblwiXSA9IFwieC10b2tlblwiO1xufSkoQ29udGVudEVuY29kaW5nIHx8IChDb250ZW50RW5jb2RpbmcgPSB7fSkpO1xudmFyIEZvcm1hdDtcbihmdW5jdGlvbihGb3JtYXQxKSB7XG4gICAgRm9ybWF0MVtcIkRhdGVcIl0gPSBcImRhdGVcIjtcbiAgICBGb3JtYXQxW1wiRGF0ZVRpbWVcIl0gPSBcImRhdGUtdGltZVwiO1xuICAgIEZvcm1hdDFbXCJEdXJhdGlvblwiXSA9IFwiZHVyYXRpb25cIjtcbiAgICBGb3JtYXQxW1wiRW1haWxcIl0gPSBcImVtYWlsXCI7XG4gICAgRm9ybWF0MVtcIkhvc3RuYW1lXCJdID0gXCJob3N0bmFtZVwiO1xuICAgIEZvcm1hdDFbXCJJRE5FbWFpbFwiXSA9IFwiaWRuLWVtYWlsXCI7XG4gICAgRm9ybWF0MVtcIklETkhvc3RuYW1lXCJdID0gXCJpZG4taG9zdG5hbWVcIjtcbiAgICBGb3JtYXQxW1wiSVB2NFwiXSA9IFwiaXB2NFwiO1xuICAgIEZvcm1hdDFbXCJJUHY2XCJdID0gXCJpcHY2XCI7XG4gICAgRm9ybWF0MVtcIklSSVwiXSA9IFwiaXJpXCI7XG4gICAgRm9ybWF0MVtcIklSSVJlZmVyZW5jZVwiXSA9IFwiaXJpLXJlZmVyZW5jZVwiO1xuICAgIEZvcm1hdDFbXCJKU09OUG9pbnRlclwiXSA9IFwianNvbi1wb2ludGVyXCI7XG4gICAgRm9ybWF0MVtcIkpTT05Qb2ludGVyVVJJRnJhZ21lbnRcIl0gPSBcImpzb24tcG9pbnRlci11cmktZnJhZ21lbnRcIjtcbiAgICBGb3JtYXQxW1wiUmVnRXhcIl0gPSBcInJlZ2V4XCI7XG4gICAgRm9ybWF0MVtcIlJlbGF0aXZlSlNPTlBvaW50ZXJcIl0gPSBcInJlbGF0aXZlLWpzb24tcG9pbnRlclwiO1xuICAgIEZvcm1hdDFbXCJUaW1lXCJdID0gXCJ0aW1lXCI7XG4gICAgRm9ybWF0MVtcIlVSSVwiXSA9IFwidXJpXCI7XG4gICAgRm9ybWF0MVtcIlVSSVJlZmVyZW5jZVwiXSA9IFwidXJpLXJlZmVyZW5jZVwiO1xuICAgIEZvcm1hdDFbXCJVUklUZW1wbGF0ZVwiXSA9IFwidXJpLXRlbXBsYXRlXCI7XG4gICAgRm9ybWF0MVtcIlVVSURcIl0gPSBcInV1aWRcIjtcbn0pKEZvcm1hdCB8fCAoRm9ybWF0ID0ge30pKTtcbnZhciBUeXBlTmFtZTtcbihmdW5jdGlvbihUeXBlTmFtZTEpIHtcbiAgICBUeXBlTmFtZTFbXCJBcnJheVwiXSA9IFwiYXJyYXlcIjtcbiAgICBUeXBlTmFtZTFbXCJCb29sZWFuXCJdID0gXCJib29sZWFuXCI7XG4gICAgVHlwZU5hbWUxW1wiSW50ZWdlclwiXSA9IFwiaW50ZWdlclwiO1xuICAgIFR5cGVOYW1lMVtcIk51bGxcIl0gPSBcIm51bGxcIjtcbiAgICBUeXBlTmFtZTFbXCJOdW1iZXJcIl0gPSBcIm51bWJlclwiO1xuICAgIFR5cGVOYW1lMVtcIk9iamVjdFwiXSA9IFwib2JqZWN0XCI7XG4gICAgVHlwZU5hbWUxW1wiU3RyaW5nXCJdID0gXCJzdHJpbmdcIjtcbn0pKFR5cGVOYW1lIHx8IChUeXBlTmFtZSA9IHt9KSk7XG5jb25zdCBrZXl3b3JkcyA9IFtcbiAgICBcIiRhbmNob3JcIixcbiAgICBcIiRjb21tZW50XCIsXG4gICAgXCIkZGVmc1wiLFxuICAgIFwiJGR5bmFtaWNBbmNob3JcIixcbiAgICBcIiRkeW5hbWljUmVmXCIsXG4gICAgXCIkaWRcIixcbiAgICBcIiRyZWZcIixcbiAgICBcIiRzY2hlbWFcIixcbiAgICBcIiR2b2NhYnVsYXJ5XCIsXG4gICAgXCJhZGRpdGlvbmFsSXRlbXNcIixcbiAgICBcImFkZGl0aW9uYWxQcm9wZXJ0aWVzXCIsXG4gICAgXCJhbGxPZlwiLFxuICAgIFwiYW55T2ZcIixcbiAgICBcImNvbnN0XCIsXG4gICAgXCJjb250YWluc1wiLFxuICAgIFwiY29udGVudEVuY29kaW5nXCIsXG4gICAgXCJjb250ZW50TWVkaWFUeXBlXCIsXG4gICAgXCJjb250ZW50U2NoZW1hXCIsXG4gICAgXCJkZWZhdWx0XCIsXG4gICAgXCJkZWZpbml0aW9uc1wiLFxuICAgIFwiZGVwZW5kZW5jaWVzXCIsXG4gICAgXCJkZXBlbmRlbnRSZXF1aXJlZFwiLFxuICAgIFwiZGVwZW5kZW50U2NoZW1hc1wiLFxuICAgIFwiZGVwcmVjYXRlZFwiLFxuICAgIFwiZGVzY3JpcHRpb25cIixcbiAgICBcImVsc2VcIixcbiAgICBcImVudW1cIixcbiAgICBcImV4YW1wbGVzXCIsXG4gICAgXCJleGNsdXNpdmVNYXhpbXVtXCIsXG4gICAgXCJleGNsdXNpdmVNaW5pbXVtXCIsXG4gICAgXCJmb3JtYXRcIixcbiAgICBcImlmXCIsXG4gICAgXCJpdGVtc1wiLFxuICAgIFwibWF4Q29udGFpbnNcIixcbiAgICBcIm1heGltdW1cIixcbiAgICBcIm1heEl0ZW1zXCIsXG4gICAgXCJtYXhMZW5ndGhcIixcbiAgICBcIm1heFByb3BlcnRpZXNcIixcbiAgICBcIm1pbkNvbnRhaW5zXCIsXG4gICAgXCJtaW5pbXVtXCIsXG4gICAgXCJtaW5JdGVtc1wiLFxuICAgIFwibWluTGVuZ3RoXCIsXG4gICAgXCJtaW5Qcm9wZXJ0aWVzXCIsXG4gICAgXCJtdWx0aXBsZU9mXCIsXG4gICAgXCJub3RcIixcbiAgICBcIm9uZU9mXCIsXG4gICAgXCJwYXR0ZXJuXCIsXG4gICAgXCJwYXR0ZXJuUHJvcGVydGllc1wiLFxuICAgIFwicHJlZml4SXRlbXNcIixcbiAgICBcInByb3BlcnRpZXNcIixcbiAgICBcInByb3BlcnR5TmFtZXNcIixcbiAgICBcInJlYWRPbmx5XCIsXG4gICAgXCJyZXF1aXJlZFwiLFxuICAgIFwidGhlblwiLFxuICAgIFwidGl0bGVcIixcbiAgICBcInR5cGVcIixcbiAgICBcInVuZXZhbHVhdGVkSXRlbXNcIixcbiAgICBcInVuZXZhbHVhdGVkUHJvcGVydGllc1wiLFxuICAgIFwidW5pcXVlSXRlbXNcIixcbiAgICBcIndyaXRlT25seVwiLCBcbl07XG5cbmV4cG9ydCB7ICRzY2hlbWEsIENvbnRlbnRFbmNvZGluZywgRm9ybWF0LCBUeXBlTmFtZSwgZHJhZnQsIGtleXdvcmRzIH07XG4iLCJpbXBvcnQgeyBpc09SUENFcnJvclN0YXR1cywgZmFsbGJhY2tPUlBDRXJyb3JTdGF0dXMsIGZhbGxiYWNrT1JQQ0Vycm9yTWVzc2FnZSB9IGZyb20gJ0BvcnBjL2NsaWVudCc7XG5pbXBvcnQgeyB0b0h0dHBQYXRoIH0gZnJvbSAnQG9ycGMvY2xpZW50L3N0YW5kYXJkJztcbmltcG9ydCB7IGZhbGxiYWNrQ29udHJhY3RDb25maWcsIGdldEV2ZW50SXRlcmF0b3JTY2hlbWFEZXRhaWxzIH0gZnJvbSAnQG9ycGMvY29udHJhY3QnO1xuaW1wb3J0IHsgc3RhbmRhcmRpemVIVFRQUGF0aCwgU3RhbmRhcmRPcGVuQVBJSnNvblNlcmlhbGl6ZXIsIGdldER5bmFtaWNQYXJhbXMgfSBmcm9tICdAb3JwYy9vcGVuYXBpLWNsaWVudC9zdGFuZGFyZCc7XG5pbXBvcnQgeyBpc1Byb2NlZHVyZSwgcmVzb2x2ZUNvbnRyYWN0UHJvY2VkdXJlcyB9IGZyb20gJ0BvcnBjL3NlcnZlcic7XG5pbXBvcnQgeyBpc09iamVjdCwgc3RyaW5naWZ5SlNPTiwgZmluZERlZXBNYXRjaGVzLCB0b0FycmF5LCBjbG9uZSwgdmFsdWUgfSBmcm9tICdAb3JwYy9zaGFyZWQnO1xuaW1wb3J0IHsgVHlwZU5hbWUgfSBmcm9tICdAb3JwYy9pbnRlcm9wL2pzb24tc2NoZW1hLXR5cGVkL2RyYWZ0LTIwMjAtMTInO1xuXG5jb25zdCBPUEVSQVRJT05fRVhURU5ERVJfU1lNQk9MID0gU3ltYm9sKFwiT1JQQ19PUEVSQVRJT05fRVhURU5ERVJcIik7XG5mdW5jdGlvbiBjdXN0b21PcGVuQVBJT3BlcmF0aW9uKG8sIGV4dGVuZCkge1xuICByZXR1cm4gbmV3IFByb3h5KG8sIHtcbiAgICBnZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcikge1xuICAgICAgaWYgKHByb3AgPT09IE9QRVJBVElPTl9FWFRFTkRFUl9TWU1CT0wpIHtcbiAgICAgICAgcmV0dXJuIGV4dGVuZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBSZWZsZWN0LmdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKTtcbiAgICB9XG4gIH0pO1xufVxuZnVuY3Rpb24gZ2V0Q3VzdG9tT3BlbkFQSU9wZXJhdGlvbihvKSB7XG4gIHJldHVybiBvW09QRVJBVElPTl9FWFRFTkRFUl9TWU1CT0xdO1xufVxuZnVuY3Rpb24gYXBwbHlDdXN0b21PcGVuQVBJT3BlcmF0aW9uKG9wZXJhdGlvbiwgY29udHJhY3QpIHtcbiAgY29uc3Qgb3BlcmF0aW9uQ3VzdG9tcyA9IFtdO1xuICBmb3IgKGNvbnN0IGVycm9ySXRlbSBvZiBPYmplY3QudmFsdWVzKGNvbnRyYWN0W1wifm9ycGNcIl0uZXJyb3JNYXApKSB7XG4gICAgY29uc3QgbWF5YmVFeHRlbmRlciA9IGVycm9ySXRlbSA/IGdldEN1c3RvbU9wZW5BUElPcGVyYXRpb24oZXJyb3JJdGVtKSA6IHZvaWQgMDtcbiAgICBpZiAobWF5YmVFeHRlbmRlcikge1xuICAgICAgb3BlcmF0aW9uQ3VzdG9tcy5wdXNoKG1heWJlRXh0ZW5kZXIpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNQcm9jZWR1cmUoY29udHJhY3QpKSB7XG4gICAgZm9yIChjb25zdCBtaWRkbGV3YXJlIG9mIGNvbnRyYWN0W1wifm9ycGNcIl0ubWlkZGxld2FyZXMpIHtcbiAgICAgIGNvbnN0IG1heWJlRXh0ZW5kZXIgPSBnZXRDdXN0b21PcGVuQVBJT3BlcmF0aW9uKG1pZGRsZXdhcmUpO1xuICAgICAgaWYgKG1heWJlRXh0ZW5kZXIpIHtcbiAgICAgICAgb3BlcmF0aW9uQ3VzdG9tcy5wdXNoKG1heWJlRXh0ZW5kZXIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBsZXQgY3VycmVudE9wZXJhdGlvbiA9IG9wZXJhdGlvbjtcbiAgZm9yIChjb25zdCBjdXN0b20gb2Ygb3BlcmF0aW9uQ3VzdG9tcykge1xuICAgIGlmICh0eXBlb2YgY3VzdG9tID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGN1cnJlbnRPcGVyYXRpb24gPSBjdXN0b20oY3VycmVudE9wZXJhdGlvbiwgY29udHJhY3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50T3BlcmF0aW9uID0ge1xuICAgICAgICAuLi5jdXJyZW50T3BlcmF0aW9uLFxuICAgICAgICAuLi5jdXN0b21cbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiBjdXJyZW50T3BlcmF0aW9uO1xufVxuXG5jb25zdCBMT0dJQ19LRVlXT1JEUyA9IFtcbiAgXCIkZHluYW1pY1JlZlwiLFxuICBcIiRyZWZcIixcbiAgXCJhZGRpdGlvbmFsSXRlbXNcIixcbiAgXCJhZGRpdGlvbmFsUHJvcGVydGllc1wiLFxuICBcImFsbE9mXCIsXG4gIFwiYW55T2ZcIixcbiAgXCJjb25zdFwiLFxuICBcImNvbnRhaW5zXCIsXG4gIFwiY29udGVudEVuY29kaW5nXCIsXG4gIFwiY29udGVudE1lZGlhVHlwZVwiLFxuICBcImNvbnRlbnRTY2hlbWFcIixcbiAgXCJkZXBlbmRlbmNpZXNcIixcbiAgXCJkZXBlbmRlbnRSZXF1aXJlZFwiLFxuICBcImRlcGVuZGVudFNjaGVtYXNcIixcbiAgXCJlbHNlXCIsXG4gIFwiZW51bVwiLFxuICBcImV4Y2x1c2l2ZU1heGltdW1cIixcbiAgXCJleGNsdXNpdmVNaW5pbXVtXCIsXG4gIFwiZm9ybWF0XCIsXG4gIFwiaWZcIixcbiAgXCJpdGVtc1wiLFxuICBcIm1heENvbnRhaW5zXCIsXG4gIFwibWF4aW11bVwiLFxuICBcIm1heEl0ZW1zXCIsXG4gIFwibWF4TGVuZ3RoXCIsXG4gIFwibWF4UHJvcGVydGllc1wiLFxuICBcIm1pbkNvbnRhaW5zXCIsXG4gIFwibWluaW11bVwiLFxuICBcIm1pbkl0ZW1zXCIsXG4gIFwibWluTGVuZ3RoXCIsXG4gIFwibWluUHJvcGVydGllc1wiLFxuICBcIm11bHRpcGxlT2ZcIixcbiAgXCJub3RcIixcbiAgXCJvbmVPZlwiLFxuICBcInBhdHRlcm5cIixcbiAgXCJwYXR0ZXJuUHJvcGVydGllc1wiLFxuICBcInByZWZpeEl0ZW1zXCIsXG4gIFwicHJvcGVydGllc1wiLFxuICBcInByb3BlcnR5TmFtZXNcIixcbiAgXCJyZXF1aXJlZFwiLFxuICBcInRoZW5cIixcbiAgXCJ0eXBlXCIsXG4gIFwidW5ldmFsdWF0ZWRJdGVtc1wiLFxuICBcInVuZXZhbHVhdGVkUHJvcGVydGllc1wiLFxuICBcInVuaXF1ZUl0ZW1zXCJcbl07XG5cbmZ1bmN0aW9uIGlzRmlsZVNjaGVtYShzY2hlbWEpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHNjaGVtYSkgJiYgc2NoZW1hLnR5cGUgPT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIHNjaGVtYS5jb250ZW50TWVkaWFUeXBlID09PSBcInN0cmluZ1wiO1xufVxuZnVuY3Rpb24gaXNPYmplY3RTY2hlbWEoc2NoZW1hKSB7XG4gIHJldHVybiBpc09iamVjdChzY2hlbWEpICYmIHNjaGVtYS50eXBlID09PSBcIm9iamVjdFwiO1xufVxuZnVuY3Rpb24gaXNBbnlTY2hlbWEoc2NoZW1hKSB7XG4gIGlmIChzY2hlbWEgPT09IHRydWUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMoc2NoZW1hKS5ldmVyeSgoaykgPT4gIUxPR0lDX0tFWVdPUkRTLmluY2x1ZGVzKGspKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHNlcGFyYXRlT2JqZWN0U2NoZW1hKHNjaGVtYSwgc2VwYXJhdGVkUHJvcGVydGllcykge1xuICBpZiAoT2JqZWN0LmtleXMoc2NoZW1hKS5zb21lKFxuICAgIChrKSA9PiAhW1widHlwZVwiLCBcInByb3BlcnRpZXNcIiwgXCJyZXF1aXJlZFwiLCBcImFkZGl0aW9uYWxQcm9wZXJ0aWVzXCJdLmluY2x1ZGVzKGspICYmIExPR0lDX0tFWVdPUkRTLmluY2x1ZGVzKGspICYmIHNjaGVtYVtrXSAhPT0gdm9pZCAwXG4gICkpIHtcbiAgICByZXR1cm4gW3sgdHlwZTogXCJvYmplY3RcIiB9LCBzY2hlbWFdO1xuICB9XG4gIGNvbnN0IG1hdGNoZWQgPSB7IC4uLnNjaGVtYSB9O1xuICBjb25zdCByZXN0ID0geyAuLi5zY2hlbWEgfTtcbiAgbWF0Y2hlZC5wcm9wZXJ0aWVzID0gc2VwYXJhdGVkUHJvcGVydGllcy5yZWR1Y2UoKGFjYywga2V5KSA9PiB7XG4gICAgY29uc3Qga2V5U2NoZW1hID0gc2NoZW1hLnByb3BlcnRpZXM/LltrZXldID8/IHNjaGVtYS5hZGRpdGlvbmFsUHJvcGVydGllcztcbiAgICBpZiAoa2V5U2NoZW1hICE9PSB2b2lkIDApIHtcbiAgICAgIGFjY1trZXldID0ga2V5U2NoZW1hO1xuICAgIH1cbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSk7XG4gIG1hdGNoZWQucmVxdWlyZWQgPSBzY2hlbWEucmVxdWlyZWQ/LmZpbHRlcigoa2V5KSA9PiBzZXBhcmF0ZWRQcm9wZXJ0aWVzLmluY2x1ZGVzKGtleSkpO1xuICBtYXRjaGVkLmV4YW1wbGVzID0gc2NoZW1hLmV4YW1wbGVzPy5tYXAoKGV4YW1wbGUpID0+IHtcbiAgICBpZiAoIWlzT2JqZWN0KGV4YW1wbGUpKSB7XG4gICAgICByZXR1cm4gZXhhbXBsZTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGV4YW1wbGUpLnJlZHVjZSgoYWNjLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGlmIChzZXBhcmF0ZWRQcm9wZXJ0aWVzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgYWNjW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuICB9KTtcbiAgcmVzdC5wcm9wZXJ0aWVzID0gc2NoZW1hLnByb3BlcnRpZXMgJiYgT2JqZWN0LmVudHJpZXMoc2NoZW1hLnByb3BlcnRpZXMpLmZpbHRlcigoW2tleV0pID0+ICFzZXBhcmF0ZWRQcm9wZXJ0aWVzLmluY2x1ZGVzKGtleSkpLnJlZHVjZSgoYWNjLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICBhY2Nba2V5XSA9IHZhbHVlO1xuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbiAgcmVzdC5yZXF1aXJlZCA9IHNjaGVtYS5yZXF1aXJlZD8uZmlsdGVyKChrZXkpID0+ICFzZXBhcmF0ZWRQcm9wZXJ0aWVzLmluY2x1ZGVzKGtleSkpO1xuICByZXN0LmV4YW1wbGVzID0gc2NoZW1hLmV4YW1wbGVzPy5tYXAoKGV4YW1wbGUpID0+IHtcbiAgICBpZiAoIWlzT2JqZWN0KGV4YW1wbGUpKSB7XG4gICAgICByZXR1cm4gZXhhbXBsZTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGV4YW1wbGUpLnJlZHVjZSgoYWNjLCBba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGlmICghc2VwYXJhdGVkUHJvcGVydGllcy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcbiAgfSk7XG4gIHJldHVybiBbbWF0Y2hlZCwgcmVzdF07XG59XG5mdW5jdGlvbiBmaWx0ZXJTY2hlbWFCcmFuY2hlcyhzY2hlbWEsIGNoZWNrLCBtYXRjaGVzID0gW10pIHtcbiAgaWYgKGNoZWNrKHNjaGVtYSkpIHtcbiAgICBtYXRjaGVzLnB1c2goc2NoZW1hKTtcbiAgICByZXR1cm4gW21hdGNoZXMsIHZvaWQgMF07XG4gIH1cbiAgaWYgKGlzT2JqZWN0KHNjaGVtYSkpIHtcbiAgICBmb3IgKGNvbnN0IGtleXdvcmQgb2YgW1wiYW55T2ZcIiwgXCJvbmVPZlwiXSkge1xuICAgICAgaWYgKHNjaGVtYVtrZXl3b3JkXSAmJiBPYmplY3Qua2V5cyhzY2hlbWEpLmV2ZXJ5KFxuICAgICAgICAoaykgPT4gayA9PT0ga2V5d29yZCB8fCAhTE9HSUNfS0VZV09SRFMuaW5jbHVkZXMoaylcbiAgICAgICkpIHtcbiAgICAgICAgY29uc3QgcmVzdCA9IHNjaGVtYVtrZXl3b3JkXS5tYXAoKHMpID0+IGZpbHRlclNjaGVtYUJyYW5jaGVzKHMsIGNoZWNrLCBtYXRjaGVzKVsxXSkuZmlsdGVyKCh2KSA9PiAhIXYpO1xuICAgICAgICBpZiAocmVzdC5sZW5ndGggPT09IDEgJiYgdHlwZW9mIHJlc3RbMF0gPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICByZXR1cm4gW21hdGNoZXMsIHsgLi4uc2NoZW1hLCBba2V5d29yZF06IHZvaWQgMCwgLi4ucmVzdFswXSB9XTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW21hdGNoZXMsIHsgLi4uc2NoZW1hLCBba2V5d29yZF06IHJlc3QgfV07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBbbWF0Y2hlcywgc2NoZW1hXTtcbn1cbmZ1bmN0aW9uIGFwcGx5U2NoZW1hT3B0aW9uYWxpdHkocmVxdWlyZWQsIHNjaGVtYSkge1xuICBpZiAocmVxdWlyZWQpIHtcbiAgICByZXR1cm4gc2NoZW1hO1xuICB9XG4gIHJldHVybiB7XG4gICAgYW55T2Y6IFtcbiAgICAgIHNjaGVtYSxcbiAgICAgIHsgbm90OiB7fSB9XG4gICAgXVxuICB9O1xufVxuZnVuY3Rpb24gZXhwYW5kVW5pb25TY2hlbWEoc2NoZW1hKSB7XG4gIGlmICh0eXBlb2Ygc2NoZW1hID09PSBcIm9iamVjdFwiKSB7XG4gICAgZm9yIChjb25zdCBrZXl3b3JkIG9mIFtcImFueU9mXCIsIFwib25lT2ZcIl0pIHtcbiAgICAgIGlmIChzY2hlbWFba2V5d29yZF0gJiYgT2JqZWN0LmtleXMoc2NoZW1hKS5ldmVyeShcbiAgICAgICAgKGspID0+IGsgPT09IGtleXdvcmQgfHwgIUxPR0lDX0tFWVdPUkRTLmluY2x1ZGVzKGspXG4gICAgICApKSB7XG4gICAgICAgIHJldHVybiBzY2hlbWFba2V5d29yZF0uZmxhdE1hcCgocykgPT4gZXhwYW5kVW5pb25TY2hlbWEocykpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gW3NjaGVtYV07XG59XG5mdW5jdGlvbiBleHBhbmRBcnJheWFibGVTY2hlbWEoc2NoZW1hKSB7XG4gIGNvbnN0IHNjaGVtYXMgPSBleHBhbmRVbmlvblNjaGVtYShzY2hlbWEpO1xuICBpZiAoc2NoZW1hcy5sZW5ndGggIT09IDIpIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG4gIGNvbnN0IGFycmF5U2NoZW1hID0gc2NoZW1hcy5maW5kKFxuICAgIChzKSA9PiB0eXBlb2YgcyA9PT0gXCJvYmplY3RcIiAmJiBzLnR5cGUgPT09IFwiYXJyYXlcIiAmJiBPYmplY3Qua2V5cyhzKS5maWx0ZXIoKGspID0+IExPR0lDX0tFWVdPUkRTLmluY2x1ZGVzKGspKS5ldmVyeSgoaykgPT4gayA9PT0gXCJ0eXBlXCIgfHwgayA9PT0gXCJpdGVtc1wiKVxuICApO1xuICBpZiAoYXJyYXlTY2hlbWEgPT09IHZvaWQgMCkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cbiAgY29uc3QgaXRlbXMxID0gYXJyYXlTY2hlbWEuaXRlbXM7XG4gIGNvbnN0IGl0ZW1zMiA9IHNjaGVtYXMuZmluZCgocykgPT4gcyAhPT0gYXJyYXlTY2hlbWEpO1xuICBpZiAoc3RyaW5naWZ5SlNPTihpdGVtczEpICE9PSBzdHJpbmdpZnlKU09OKGl0ZW1zMikpIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG4gIHJldHVybiBbaXRlbXMyLCBhcnJheVNjaGVtYV07XG59XG5jb25zdCBQUklNSVRJVkVfU0NIRU1BX1RZUEVTID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoW1xuICBUeXBlTmFtZS5TdHJpbmcsXG4gIFR5cGVOYW1lLk51bWJlcixcbiAgVHlwZU5hbWUuSW50ZWdlcixcbiAgVHlwZU5hbWUuQm9vbGVhbixcbiAgVHlwZU5hbWUuTnVsbFxuXSk7XG5mdW5jdGlvbiBpc1ByaW1pdGl2ZVNjaGVtYShzY2hlbWEpIHtcbiAgcmV0dXJuIGV4cGFuZFVuaW9uU2NoZW1hKHNjaGVtYSkuZXZlcnkoKHMpID0+IHtcbiAgICBpZiAodHlwZW9mIHMgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygcy50eXBlID09PSBcInN0cmluZ1wiICYmIFBSSU1JVElWRV9TQ0hFTUFfVFlQRVMuaGFzKHMudHlwZSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAocy5jb25zdCAhPT0gdm9pZCAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gdG9PcGVuQVBJUGF0aChwYXRoKSB7XG4gIHJldHVybiBzdGFuZGFyZGl6ZUhUVFBQYXRoKHBhdGgpLnJlcGxhY2UoL1xcL1xce1xcKyhbXn1dKylcXH0vZywgXCIveyQxfVwiKTtcbn1cbmZ1bmN0aW9uIHRvT3BlbkFQSU1ldGhvZChtZXRob2QpIHtcbiAgcmV0dXJuIG1ldGhvZC50b0xvY2FsZUxvd2VyQ2FzZSgpO1xufVxuZnVuY3Rpb24gdG9PcGVuQVBJQ29udGVudChzY2hlbWEpIHtcbiAgY29uc3QgY29udGVudCA9IHt9O1xuICBjb25zdCBbbWF0Y2hlcywgcmVzdFNjaGVtYV0gPSBmaWx0ZXJTY2hlbWFCcmFuY2hlcyhzY2hlbWEsIGlzRmlsZVNjaGVtYSk7XG4gIGZvciAoY29uc3QgZmlsZSBvZiBtYXRjaGVzKSB7XG4gICAgY29udGVudFtmaWxlLmNvbnRlbnRNZWRpYVR5cGVdID0ge1xuICAgICAgc2NoZW1hOiB0b09wZW5BUElTY2hlbWEoZmlsZSlcbiAgICB9O1xuICB9XG4gIGlmIChyZXN0U2NoZW1hICE9PSB2b2lkIDApIHtcbiAgICBjb250ZW50W1wiYXBwbGljYXRpb24vanNvblwiXSA9IHtcbiAgICAgIHNjaGVtYTogdG9PcGVuQVBJU2NoZW1hKHJlc3RTY2hlbWEpXG4gICAgfTtcbiAgICBjb25zdCBpc1N0aWxsSGFzRmlsZVNjaGVtYSA9IGZpbmREZWVwTWF0Y2hlcygodikgPT4gaXNPYmplY3QodikgJiYgaXNGaWxlU2NoZW1hKHYpLCByZXN0U2NoZW1hKS52YWx1ZXMubGVuZ3RoID4gMDtcbiAgICBpZiAoaXNTdGlsbEhhc0ZpbGVTY2hlbWEpIHtcbiAgICAgIGNvbnRlbnRbXCJtdWx0aXBhcnQvZm9ybS1kYXRhXCJdID0ge1xuICAgICAgICBzY2hlbWE6IHRvT3BlbkFQSVNjaGVtYShyZXN0U2NoZW1hKVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5mdW5jdGlvbiB0b09wZW5BUElFdmVudEl0ZXJhdG9yQ29udGVudChbeWllbGRzUmVxdWlyZWQsIHlpZWxkc1NjaGVtYV0sIFtyZXR1cm5zUmVxdWlyZWQsIHJldHVybnNTY2hlbWFdKSB7XG4gIHJldHVybiB7XG4gICAgXCJ0ZXh0L2V2ZW50LXN0cmVhbVwiOiB7XG4gICAgICBzY2hlbWE6IHRvT3BlbkFQSVNjaGVtYSh7XG4gICAgICAgIG9uZU9mOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgZXZlbnQ6IHsgY29uc3Q6IFwibWVzc2FnZVwiIH0sXG4gICAgICAgICAgICAgIGRhdGE6IHlpZWxkc1NjaGVtYSxcbiAgICAgICAgICAgICAgaWQ6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICAgICAgICByZXRyeTogeyB0eXBlOiBcIm51bWJlclwiIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZXF1aXJlZDogeWllbGRzUmVxdWlyZWQgPyBbXCJldmVudFwiLCBcImRhdGFcIl0gOiBbXCJldmVudFwiXVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgZXZlbnQ6IHsgY29uc3Q6IFwiZG9uZVwiIH0sXG4gICAgICAgICAgICAgIGRhdGE6IHJldHVybnNTY2hlbWEsXG4gICAgICAgICAgICAgIGlkOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAgcmV0cnk6IHsgdHlwZTogXCJudW1iZXJcIiB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVxdWlyZWQ6IHJldHVybnNSZXF1aXJlZCA/IFtcImV2ZW50XCIsIFwiZGF0YVwiXSA6IFtcImV2ZW50XCJdXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICBldmVudDogeyBjb25zdDogXCJlcnJvclwiIH0sXG4gICAgICAgICAgICAgIGRhdGE6IHt9LFxuICAgICAgICAgICAgICBpZDogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgICAgICAgIHJldHJ5OiB7IHR5cGU6IFwibnVtYmVyXCIgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlcXVpcmVkOiBbXCJldmVudFwiXVxuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfSlcbiAgICB9XG4gIH07XG59XG5mdW5jdGlvbiB0b09wZW5BUElQYXJhbWV0ZXJzKHNjaGVtYSwgcGFyYW1ldGVySW4pIHtcbiAgY29uc3QgcGFyYW1ldGVycyA9IFtdO1xuICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEucHJvcGVydGllcykge1xuICAgIGNvbnN0IGtleVNjaGVtYSA9IHNjaGVtYS5wcm9wZXJ0aWVzW2tleV07XG4gICAgbGV0IGlzRGVlcE9iamVjdFN0eWxlID0gdHJ1ZTtcbiAgICBpZiAocGFyYW1ldGVySW4gIT09IFwicXVlcnlcIikge1xuICAgICAgaXNEZWVwT2JqZWN0U3R5bGUgPSBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKGlzUHJpbWl0aXZlU2NoZW1hKGtleVNjaGVtYSkpIHtcbiAgICAgIGlzRGVlcE9iamVjdFN0eWxlID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IFtpdGVtXSA9IGV4cGFuZEFycmF5YWJsZVNjaGVtYShrZXlTY2hlbWEpID8/IFtdO1xuICAgICAgaWYgKGl0ZW0gIT09IHZvaWQgMCAmJiBpc1ByaW1pdGl2ZVNjaGVtYShpdGVtKSkge1xuICAgICAgICBpc0RlZXBPYmplY3RTdHlsZSA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBwYXJhbWV0ZXJzLnB1c2goe1xuICAgICAgbmFtZToga2V5LFxuICAgICAgaW46IHBhcmFtZXRlckluLFxuICAgICAgcmVxdWlyZWQ6IHNjaGVtYS5yZXF1aXJlZD8uaW5jbHVkZXMoa2V5KSxcbiAgICAgIHNjaGVtYTogdG9PcGVuQVBJU2NoZW1hKGtleVNjaGVtYSksXG4gICAgICBzdHlsZTogaXNEZWVwT2JqZWN0U3R5bGUgPyBcImRlZXBPYmplY3RcIiA6IHZvaWQgMCxcbiAgICAgIGV4cGxvZGU6IGlzRGVlcE9iamVjdFN0eWxlID8gdHJ1ZSA6IHZvaWQgMCxcbiAgICAgIGFsbG93RW1wdHlWYWx1ZTogcGFyYW1ldGVySW4gPT09IFwicXVlcnlcIiA/IHRydWUgOiB2b2lkIDAsXG4gICAgICBhbGxvd1Jlc2VydmVkOiBwYXJhbWV0ZXJJbiA9PT0gXCJxdWVyeVwiID8gdHJ1ZSA6IHZvaWQgMFxuICAgIH0pO1xuICB9XG4gIHJldHVybiBwYXJhbWV0ZXJzO1xufVxuZnVuY3Rpb24gY2hlY2tQYXJhbXNTY2hlbWEoc2NoZW1hLCBwYXJhbXMpIHtcbiAgY29uc3QgcHJvcGVydGllcyA9IE9iamVjdC5rZXlzKHNjaGVtYS5wcm9wZXJ0aWVzID8/IHt9KTtcbiAgY29uc3QgcmVxdWlyZWQgPSBzY2hlbWEucmVxdWlyZWQgPz8gW107XG4gIGlmIChwcm9wZXJ0aWVzLmxlbmd0aCAhPT0gcGFyYW1zLmxlbmd0aCB8fCBwcm9wZXJ0aWVzLnNvbWUoKHYpID0+ICFwYXJhbXMuaW5jbHVkZXModikpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChyZXF1aXJlZC5sZW5ndGggIT09IHBhcmFtcy5sZW5ndGggfHwgcmVxdWlyZWQuc29tZSgodikgPT4gIXBhcmFtcy5pbmNsdWRlcyh2KSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiB0b09wZW5BUElTY2hlbWEoc2NoZW1hKSB7XG4gIHJldHVybiBzY2hlbWEgPT09IHRydWUgPyB7fSA6IHNjaGVtYSA9PT0gZmFsc2UgPyB7IG5vdDoge30gfSA6IHNjaGVtYTtcbn1cbmNvbnN0IE9QRU5BUElfSlNPTl9TQ0hFTUFfUkVGX1BSRUZJWCA9IFwiIy9jb21wb25lbnRzL3NjaGVtYXMvXCI7XG5mdW5jdGlvbiByZXNvbHZlT3BlbkFQSUpzb25TY2hlbWFSZWYoZG9jLCBzY2hlbWEpIHtcbiAgaWYgKHR5cGVvZiBzY2hlbWEgIT09IFwib2JqZWN0XCIgfHwgIXNjaGVtYS4kcmVmPy5zdGFydHNXaXRoKE9QRU5BUElfSlNPTl9TQ0hFTUFfUkVGX1BSRUZJWCkpIHtcbiAgICByZXR1cm4gc2NoZW1hO1xuICB9XG4gIGNvbnN0IG5hbWUgPSBzY2hlbWEuJHJlZi5zbGljZShPUEVOQVBJX0pTT05fU0NIRU1BX1JFRl9QUkVGSVgubGVuZ3RoKTtcbiAgY29uc3QgcmVzb2x2ZWQgPSBkb2MuY29tcG9uZW50cz8uc2NoZW1hcz8uW25hbWVdO1xuICByZXR1cm4gcmVzb2x2ZWQgPz8gc2NoZW1hO1xufVxuXG5jbGFzcyBDb21wb3NpdGVTY2hlbWFDb252ZXJ0ZXIge1xuICBjb252ZXJ0ZXJzO1xuICBjb25zdHJ1Y3Rvcihjb252ZXJ0ZXJzKSB7XG4gICAgdGhpcy5jb252ZXJ0ZXJzID0gY29udmVydGVycztcbiAgfVxuICBhc3luYyBjb252ZXJ0KHNjaGVtYSwgb3B0aW9ucykge1xuICAgIGZvciAoY29uc3QgY29udmVydGVyIG9mIHRoaXMuY29udmVydGVycykge1xuICAgICAgaWYgKGF3YWl0IGNvbnZlcnRlci5jb25kaXRpb24oc2NoZW1hLCBvcHRpb25zKSkge1xuICAgICAgICByZXR1cm4gY29udmVydGVyLmNvbnZlcnQoc2NoZW1hLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFtmYWxzZSwge31dO1xuICB9XG59XG5cbmNsYXNzIE9wZW5BUElHZW5lcmF0b3JFcnJvciBleHRlbmRzIEVycm9yIHtcbn1cbmNsYXNzIE9wZW5BUElHZW5lcmF0b3Ige1xuICBzZXJpYWxpemVyO1xuICBjb252ZXJ0ZXI7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuc2VyaWFsaXplciA9IG5ldyBTdGFuZGFyZE9wZW5BUElKc29uU2VyaWFsaXplcihvcHRpb25zKTtcbiAgICB0aGlzLmNvbnZlcnRlciA9IG5ldyBDb21wb3NpdGVTY2hlbWFDb252ZXJ0ZXIodG9BcnJheShvcHRpb25zLnNjaGVtYUNvbnZlcnRlcnMpKTtcbiAgfVxuICAvKipcbiAgICogR2VuZXJhdGVzIE9wZW5BUEkgc3BlY2lmaWNhdGlvbnMgZnJvbSBvUlBDIHJvdXRlcnMvY29udHJhY3RzLlxuICAgKlxuICAgKiBAc2VlIHtAbGluayBodHRwczovL29ycGMudW5ub3EuY29tL2RvY3Mvb3BlbmFwaS9vcGVuYXBpLXNwZWNpZmljYXRpb24gT3BlbkFQSSBTcGVjaWZpY2F0aW9uIERvY3N9XG4gICAqL1xuICBhc3luYyBnZW5lcmF0ZShyb3V0ZXIsIHsgY3VzdG9tRXJyb3JSZXNwb25zZUJvZHlTY2hlbWEsIGNvbW1vblNjaGVtYXMsIGZpbHRlcjogYmFzZUZpbHRlciwgZXhjbHVkZSwgLi4uYmFzZURvYyB9ID0ge30pIHtcbiAgICBjb25zdCBmaWx0ZXIgPSBiYXNlRmlsdGVyID8/ICgoeyBjb250cmFjdCwgcGF0aCB9KSA9PiB7XG4gICAgICByZXR1cm4gIShleGNsdWRlPy4oY29udHJhY3QsIHBhdGgpID8/IGZhbHNlKTtcbiAgICB9KTtcbiAgICBjb25zdCBkb2MgPSB7XG4gICAgICAuLi5jbG9uZShiYXNlRG9jKSxcbiAgICAgIGluZm86IGJhc2VEb2MuaW5mbyA/PyB7IHRpdGxlOiBcIkFQSSBSZWZlcmVuY2VcIiwgdmVyc2lvbjogXCIwLjAuMFwiIH0sXG4gICAgICBvcGVuYXBpOiBcIjMuMS4xXCJcbiAgICB9O1xuICAgIGNvbnN0IHsgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCB1bmRlZmluZWRFcnJvckpzb25TY2hlbWEgfSA9IGF3YWl0IHRoaXMuI3Jlc29sdmVDb21tb25TY2hlbWFzKGRvYywgY29tbW9uU2NoZW1hcyk7XG4gICAgY29uc3QgY29udHJhY3RzID0gW107XG4gICAgYXdhaXQgcmVzb2x2ZUNvbnRyYWN0UHJvY2VkdXJlcyh7IHBhdGg6IFtdLCByb3V0ZXIgfSwgKHRyYXZlcnNlT3B0aW9ucykgPT4ge1xuICAgICAgaWYgKCF2YWx1ZShmaWx0ZXIsIHRyYXZlcnNlT3B0aW9ucykpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29udHJhY3RzLnB1c2godHJhdmVyc2VPcHRpb25zKTtcbiAgICB9KTtcbiAgICBjb25zdCBlcnJvcnMgPSBbXTtcbiAgICBmb3IgKGNvbnN0IHsgY29udHJhY3QsIHBhdGggfSBvZiBjb250cmFjdHMpIHtcbiAgICAgIGNvbnN0IHN0cmluZ1BhdGggPSBwYXRoLmpvaW4oXCIuXCIpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgZGVmID0gY29udHJhY3RbXCJ+b3JwY1wiXTtcbiAgICAgICAgY29uc3QgbWV0aG9kID0gdG9PcGVuQVBJTWV0aG9kKGZhbGxiYWNrQ29udHJhY3RDb25maWcoXCJkZWZhdWx0TWV0aG9kXCIsIGRlZi5yb3V0ZS5tZXRob2QpKTtcbiAgICAgICAgY29uc3QgaHR0cFBhdGggPSB0b09wZW5BUElQYXRoKGRlZi5yb3V0ZS5wYXRoID8/IHRvSHR0cFBhdGgocGF0aCkpO1xuICAgICAgICBsZXQgb3BlcmF0aW9uT2JqZWN0UmVmO1xuICAgICAgICBpZiAoZGVmLnJvdXRlLnNwZWMgIT09IHZvaWQgMCAmJiB0eXBlb2YgZGVmLnJvdXRlLnNwZWMgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIG9wZXJhdGlvbk9iamVjdFJlZiA9IGRlZi5yb3V0ZS5zcGVjO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wZXJhdGlvbk9iamVjdFJlZiA9IHtcbiAgICAgICAgICAgIG9wZXJhdGlvbklkOiBkZWYucm91dGUub3BlcmF0aW9uSWQgPz8gc3RyaW5nUGF0aCxcbiAgICAgICAgICAgIHN1bW1hcnk6IGRlZi5yb3V0ZS5zdW1tYXJ5LFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IGRlZi5yb3V0ZS5kZXNjcmlwdGlvbixcbiAgICAgICAgICAgIGRlcHJlY2F0ZWQ6IGRlZi5yb3V0ZS5kZXByZWNhdGVkLFxuICAgICAgICAgICAgdGFnczogZGVmLnJvdXRlLnRhZ3M/Lm1hcCgodGFnKSA9PiB0YWcpXG4gICAgICAgICAgfTtcbiAgICAgICAgICBhd2FpdCB0aGlzLiNyZXF1ZXN0KGRvYywgb3BlcmF0aW9uT2JqZWN0UmVmLCBkZWYsIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucyk7XG4gICAgICAgICAgYXdhaXQgdGhpcy4jc3VjY2Vzc1Jlc3BvbnNlKGRvYywgb3BlcmF0aW9uT2JqZWN0UmVmLCBkZWYsIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucyk7XG4gICAgICAgICAgYXdhaXQgdGhpcy4jZXJyb3JSZXNwb25zZShvcGVyYXRpb25PYmplY3RSZWYsIGRlZiwgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCB1bmRlZmluZWRFcnJvckpzb25TY2hlbWEsIGN1c3RvbUVycm9yUmVzcG9uc2VCb2R5U2NoZW1hKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGRlZi5yb3V0ZS5zcGVjID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICBvcGVyYXRpb25PYmplY3RSZWYgPSBkZWYucm91dGUuc3BlYyhvcGVyYXRpb25PYmplY3RSZWYpO1xuICAgICAgICB9XG4gICAgICAgIGRvYy5wYXRocyA/Pz0ge307XG4gICAgICAgIGRvYy5wYXRoc1todHRwUGF0aF0gPz89IHt9O1xuICAgICAgICBkb2MucGF0aHNbaHR0cFBhdGhdW21ldGhvZF0gPSBhcHBseUN1c3RvbU9wZW5BUElPcGVyYXRpb24ob3BlcmF0aW9uT2JqZWN0UmVmLCBjb250cmFjdCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBPcGVuQVBJR2VuZXJhdG9yRXJyb3IpKSB7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgICBlcnJvcnMucHVzaChcbiAgICAgICAgICBgW09wZW5BUElHZW5lcmF0b3JdIEVycm9yIG9jY3VycmVkIHdoaWxlIGdlbmVyYXRpbmcgT3BlbkFQSSBmb3IgcHJvY2VkdXJlIGF0IHBhdGg6ICR7c3RyaW5nUGF0aH1cbiR7ZS5tZXNzYWdlfWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVycm9ycy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IoXG4gICAgICAgIGBTb21lIGVycm9yIG9jY3VycmVkIGR1cmluZyBPcGVuQVBJIGdlbmVyYXRpb246XG5cbiR7ZXJyb3JzLmpvaW4oXCJcXG5cXG5cIil9YFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2VyaWFsaXplci5zZXJpYWxpemUoZG9jKVswXTtcbiAgfVxuICBhc3luYyAjcmVzb2x2ZUNvbW1vblNjaGVtYXMoZG9jLCBjb21tb25TY2hlbWFzKSB7XG4gICAgbGV0IHVuZGVmaW5lZEVycm9ySnNvblNjaGVtYSA9IHtcbiAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgIGRlZmluZWQ6IHsgY29uc3Q6IGZhbHNlIH0sXG4gICAgICAgIGNvZGU6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICBzdGF0dXM6IHsgdHlwZTogXCJudW1iZXJcIiB9LFxuICAgICAgICBtZXNzYWdlOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgZGF0YToge31cbiAgICAgIH0sXG4gICAgICByZXF1aXJlZDogW1wiZGVmaW5lZFwiLCBcImNvZGVcIiwgXCJzdGF0dXNcIiwgXCJtZXNzYWdlXCJdXG4gICAgfTtcbiAgICBjb25zdCBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMgPSB7fTtcbiAgICBpZiAoY29tbW9uU2NoZW1hcykge1xuICAgICAgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLmNvbXBvbmVudHMgPSBbXTtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGNvbW1vblNjaGVtYXMpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbW1vblNjaGVtYXNba2V5XTtcbiAgICAgICAgaWYgKG9wdGlvbnMuc2NoZW1hID09PSB2b2lkIDApIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHNjaGVtYSwgc3RyYXRlZ3kgPSBcImlucHV0XCIgfSA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IFtyZXF1aXJlZCwganNvbl0gPSBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KHNjaGVtYSwgeyBzdHJhdGVneSB9KTtcbiAgICAgICAgY29uc3QgYWxsb3dlZFN0cmF0ZWdpZXMgPSBbc3RyYXRlZ3ldO1xuICAgICAgICBpZiAoc3RyYXRlZ3kgPT09IFwiaW5wdXRcIikge1xuICAgICAgICAgIGNvbnN0IFtvdXRwdXRSZXF1aXJlZCwgb3V0cHV0SnNvbl0gPSBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KHNjaGVtYSwgeyBzdHJhdGVneTogXCJvdXRwdXRcIiB9KTtcbiAgICAgICAgICBpZiAob3V0cHV0UmVxdWlyZWQgPT09IHJlcXVpcmVkICYmIHN0cmluZ2lmeUpTT04ob3V0cHV0SnNvbikgPT09IHN0cmluZ2lmeUpTT04oanNvbikpIHtcbiAgICAgICAgICAgIGFsbG93ZWRTdHJhdGVnaWVzLnB1c2goXCJvdXRwdXRcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKHN0cmF0ZWd5ID09PSBcIm91dHB1dFwiKSB7XG4gICAgICAgICAgY29uc3QgW2lucHV0UmVxdWlyZWQsIGlucHV0SnNvbl0gPSBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KHNjaGVtYSwgeyBzdHJhdGVneTogXCJpbnB1dFwiIH0pO1xuICAgICAgICAgIGlmIChpbnB1dFJlcXVpcmVkID09PSByZXF1aXJlZCAmJiBzdHJpbmdpZnlKU09OKGlucHV0SnNvbikgPT09IHN0cmluZ2lmeUpTT04oanNvbikpIHtcbiAgICAgICAgICAgIGFsbG93ZWRTdHJhdGVnaWVzLnB1c2goXCJpbnB1dFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLmNvbXBvbmVudHMucHVzaCh7XG4gICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgIHJlcXVpcmVkLFxuICAgICAgICAgIHJlZjogYCMvY29tcG9uZW50cy9zY2hlbWFzLyR7a2V5fWAsXG4gICAgICAgICAgYWxsb3dlZFN0cmF0ZWdpZXNcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBkb2MuY29tcG9uZW50cyA/Pz0ge307XG4gICAgICBkb2MuY29tcG9uZW50cy5zY2hlbWFzID8/PSB7fTtcbiAgICAgIGZvciAoY29uc3Qga2V5IGluIGNvbW1vblNjaGVtYXMpIHtcbiAgICAgICAgY29uc3Qgb3B0aW9ucyA9IGNvbW1vblNjaGVtYXNba2V5XTtcbiAgICAgICAgaWYgKG9wdGlvbnMuc2NoZW1hID09PSB2b2lkIDApIHtcbiAgICAgICAgICBpZiAob3B0aW9ucy5lcnJvciA9PT0gXCJVbmRlZmluZWRFcnJvclwiKSB7XG4gICAgICAgICAgICBkb2MuY29tcG9uZW50cy5zY2hlbWFzW2tleV0gPSB0b09wZW5BUElTY2hlbWEodW5kZWZpbmVkRXJyb3JKc29uU2NoZW1hKTtcbiAgICAgICAgICAgIHVuZGVmaW5lZEVycm9ySnNvblNjaGVtYSA9IHsgJHJlZjogYCMvY29tcG9uZW50cy9zY2hlbWFzLyR7a2V5fWAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBzY2hlbWEsIHN0cmF0ZWd5ID0gXCJpbnB1dFwiIH0gPSBvcHRpb25zO1xuICAgICAgICBjb25zdCBbLCBqc29uXSA9IGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoXG4gICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucyxcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgbWluU3RydWN0dXJlRGVwdGhGb3JSZWY6IDFcbiAgICAgICAgICAgIC8vIG5vdCBhbGxvdyB1c2UgJHJlZiBmb3Igcm9vdCBzY2hlbWFzXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBkb2MuY29tcG9uZW50cy5zY2hlbWFzW2tleV0gPSB0b09wZW5BUElTY2hlbWEoanNvbik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgdW5kZWZpbmVkRXJyb3JKc29uU2NoZW1hIH07XG4gIH1cbiAgYXN5bmMgI3JlcXVlc3QoZG9jLCByZWYsIGRlZiwgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zKSB7XG4gICAgY29uc3QgbWV0aG9kID0gZmFsbGJhY2tDb250cmFjdENvbmZpZyhcImRlZmF1bHRNZXRob2RcIiwgZGVmLnJvdXRlLm1ldGhvZCk7XG4gICAgY29uc3QgZGV0YWlscyA9IGdldEV2ZW50SXRlcmF0b3JTY2hlbWFEZXRhaWxzKGRlZi5pbnB1dFNjaGVtYSk7XG4gICAgaWYgKGRldGFpbHMpIHtcbiAgICAgIHJlZi5yZXF1ZXN0Qm9keSA9IHtcbiAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIGNvbnRlbnQ6IHRvT3BlbkFQSUV2ZW50SXRlcmF0b3JDb250ZW50KFxuICAgICAgICAgIGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoZGV0YWlscy55aWVsZHMsIHsgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCBzdHJhdGVneTogXCJpbnB1dFwiIH0pLFxuICAgICAgICAgIGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoZGV0YWlscy5yZXR1cm5zLCB7IC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgc3RyYXRlZ3k6IFwiaW5wdXRcIiB9KVxuICAgICAgICApXG4gICAgICB9O1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBkeW5hbWljUGFyYW1zID0gZ2V0RHluYW1pY1BhcmFtcyhkZWYucm91dGUucGF0aCk/Lm1hcCgodikgPT4gdi5uYW1lKTtcbiAgICBjb25zdCBpbnB1dFN0cnVjdHVyZSA9IGZhbGxiYWNrQ29udHJhY3RDb25maWcoXCJkZWZhdWx0SW5wdXRTdHJ1Y3R1cmVcIiwgZGVmLnJvdXRlLmlucHV0U3RydWN0dXJlKTtcbiAgICBsZXQgW3JlcXVpcmVkLCBzY2hlbWFdID0gYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChcbiAgICAgIGRlZi5pbnB1dFNjaGVtYSxcbiAgICAgIHtcbiAgICAgICAgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLFxuICAgICAgICBzdHJhdGVneTogXCJpbnB1dFwiLFxuICAgICAgICBtaW5TdHJ1Y3R1cmVEZXB0aEZvclJlZjogZHluYW1pY1BhcmFtcz8ubGVuZ3RoIHx8IGlucHV0U3RydWN0dXJlID09PSBcImRldGFpbGVkXCIgPyAxIDogMFxuICAgICAgfVxuICAgICk7XG4gICAgaWYgKGlzQW55U2NoZW1hKHNjaGVtYSkgJiYgIWR5bmFtaWNQYXJhbXM/Lmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaW5wdXRTdHJ1Y3R1cmUgPT09IFwiY29tcGFjdFwiKSB7XG4gICAgICBpZiAoZHluYW1pY1BhcmFtcz8ubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IGVycm9yMiA9IG5ldyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IoXG4gICAgICAgICAgJ1doZW4gaW5wdXQgc3RydWN0dXJlIGlzIFwiY29tcGFjdFwiLCBhbmQgcGF0aCBoYXMgZHluYW1pYyBwYXJhbXMsIGlucHV0IHNjaGVtYSBtdXN0IGJlIGFuIG9iamVjdCB3aXRoIGFsbCBkeW5hbWljIHBhcmFtcyBhcyByZXF1aXJlZC4nXG4gICAgICAgICk7XG4gICAgICAgIGlmICghaXNPYmplY3RTY2hlbWEoc2NoZW1hKSkge1xuICAgICAgICAgIHRocm93IGVycm9yMjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBbcGFyYW1zU2NoZW1hLCByZXN0XSA9IHNlcGFyYXRlT2JqZWN0U2NoZW1hKHNjaGVtYSwgZHluYW1pY1BhcmFtcyk7XG4gICAgICAgIHNjaGVtYSA9IHJlc3Q7XG4gICAgICAgIHJlcXVpcmVkID0gcmVzdC5yZXF1aXJlZCA/IHJlc3QucmVxdWlyZWQubGVuZ3RoICE9PSAwIDogZmFsc2U7XG4gICAgICAgIGlmICghY2hlY2tQYXJhbXNTY2hlbWEocGFyYW1zU2NoZW1hLCBkeW5hbWljUGFyYW1zKSkge1xuICAgICAgICAgIHRocm93IGVycm9yMjtcbiAgICAgICAgfVxuICAgICAgICByZWYucGFyYW1ldGVycyA/Pz0gW107XG4gICAgICAgIHJlZi5wYXJhbWV0ZXJzLnB1c2goLi4udG9PcGVuQVBJUGFyYW1ldGVycyhwYXJhbXNTY2hlbWEsIFwicGF0aFwiKSk7XG4gICAgICB9XG4gICAgICBpZiAobWV0aG9kID09PSBcIkdFVFwiKSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkU2NoZW1hID0gcmVzb2x2ZU9wZW5BUElKc29uU2NoZW1hUmVmKGRvYywgc2NoZW1hKTtcbiAgICAgICAgaWYgKCFpc09iamVjdFNjaGVtYShyZXNvbHZlZFNjaGVtYSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgT3BlbkFQSUdlbmVyYXRvckVycm9yKFxuICAgICAgICAgICAgJ1doZW4gbWV0aG9kIGlzIFwiR0VUXCIsIGlucHV0IHNjaGVtYSBtdXN0IHNhdGlzZnk6IG9iamVjdCB8IGFueSB8IHVua25vd24nXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZWYucGFyYW1ldGVycyA/Pz0gW107XG4gICAgICAgIHJlZi5wYXJhbWV0ZXJzLnB1c2goLi4udG9PcGVuQVBJUGFyYW1ldGVycyhyZXNvbHZlZFNjaGVtYSwgXCJxdWVyeVwiKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWYucmVxdWVzdEJvZHkgPSB7XG4gICAgICAgICAgcmVxdWlyZWQsXG4gICAgICAgICAgY29udGVudDogdG9PcGVuQVBJQ29udGVudChzY2hlbWEpXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5BUElHZW5lcmF0b3JFcnJvcihcbiAgICAgICdXaGVuIGlucHV0IHN0cnVjdHVyZSBpcyBcImRldGFpbGVkXCIsIGlucHV0IHNjaGVtYSBtdXN0IHNhdGlzZnk6IHsgcGFyYW1zPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIHF1ZXJ5PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgYm9keT86IHVua25vd24gfSdcbiAgICApO1xuICAgIGlmICghaXNPYmplY3RTY2hlbWEoc2NoZW1hKSkge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIGNvbnN0IHJlc29sdmVkUGFyYW1TY2hlbWEgPSBzY2hlbWEucHJvcGVydGllcz8ucGFyYW1zICE9PSB2b2lkIDAgPyByZXNvbHZlT3BlbkFQSUpzb25TY2hlbWFSZWYoZG9jLCBzY2hlbWEucHJvcGVydGllcy5wYXJhbXMpIDogdm9pZCAwO1xuICAgIGlmIChkeW5hbWljUGFyYW1zPy5sZW5ndGggJiYgKHJlc29sdmVkUGFyYW1TY2hlbWEgPT09IHZvaWQgMCB8fCAhaXNPYmplY3RTY2hlbWEocmVzb2x2ZWRQYXJhbVNjaGVtYSkgfHwgIWNoZWNrUGFyYW1zU2NoZW1hKHJlc29sdmVkUGFyYW1TY2hlbWEsIGR5bmFtaWNQYXJhbXMpKSkge1xuICAgICAgdGhyb3cgbmV3IE9wZW5BUElHZW5lcmF0b3JFcnJvcihcbiAgICAgICAgJ1doZW4gaW5wdXQgc3RydWN0dXJlIGlzIFwiZGV0YWlsZWRcIiBhbmQgcGF0aCBoYXMgZHluYW1pYyBwYXJhbXMsIHRoZSBcInBhcmFtc1wiIHNjaGVtYSBtdXN0IGJlIGFuIG9iamVjdCB3aXRoIGFsbCBkeW5hbWljIHBhcmFtcyBhcyByZXF1aXJlZC4nXG4gICAgICApO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZyb20gb2YgW1wicGFyYW1zXCIsIFwicXVlcnlcIiwgXCJoZWFkZXJzXCJdKSB7XG4gICAgICBjb25zdCBmcm9tU2NoZW1hID0gc2NoZW1hLnByb3BlcnRpZXM/Lltmcm9tXTtcbiAgICAgIGlmIChmcm9tU2NoZW1hICE9PSB2b2lkIDApIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRTY2hlbWEgPSByZXNvbHZlT3BlbkFQSUpzb25TY2hlbWFSZWYoZG9jLCBmcm9tU2NoZW1hKTtcbiAgICAgICAgaWYgKCFpc09iamVjdFNjaGVtYShyZXNvbHZlZFNjaGVtYSkpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXJhbWV0ZXJJbiA9IGZyb20gPT09IFwicGFyYW1zXCIgPyBcInBhdGhcIiA6IGZyb20gPT09IFwiaGVhZGVyc1wiID8gXCJoZWFkZXJcIiA6IFwicXVlcnlcIjtcbiAgICAgICAgcmVmLnBhcmFtZXRlcnMgPz89IFtdO1xuICAgICAgICByZWYucGFyYW1ldGVycy5wdXNoKC4uLnRvT3BlbkFQSVBhcmFtZXRlcnMocmVzb2x2ZWRTY2hlbWEsIHBhcmFtZXRlckluKSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzY2hlbWEucHJvcGVydGllcz8uYm9keSAhPT0gdm9pZCAwKSB7XG4gICAgICByZWYucmVxdWVzdEJvZHkgPSB7XG4gICAgICAgIHJlcXVpcmVkOiBzY2hlbWEucmVxdWlyZWQ/LmluY2x1ZGVzKFwiYm9keVwiKSxcbiAgICAgICAgY29udGVudDogdG9PcGVuQVBJQ29udGVudChzY2hlbWEucHJvcGVydGllcy5ib2R5KVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgYXN5bmMgI3N1Y2Nlc3NSZXNwb25zZShkb2MsIHJlZiwgZGVmLCBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMpIHtcbiAgICBjb25zdCBvdXRwdXRTY2hlbWEgPSBkZWYub3V0cHV0U2NoZW1hO1xuICAgIGNvbnN0IHN0YXR1cyA9IGZhbGxiYWNrQ29udHJhY3RDb25maWcoXCJkZWZhdWx0U3VjY2Vzc1N0YXR1c1wiLCBkZWYucm91dGUuc3VjY2Vzc1N0YXR1cyk7XG4gICAgY29uc3QgZGVzY3JpcHRpb24gPSBmYWxsYmFja0NvbnRyYWN0Q29uZmlnKFwiZGVmYXVsdFN1Y2Nlc3NEZXNjcmlwdGlvblwiLCBkZWYucm91dGU/LnN1Y2Nlc3NEZXNjcmlwdGlvbik7XG4gICAgY29uc3QgZXZlbnRJdGVyYXRvclNjaGVtYURldGFpbHMgPSBnZXRFdmVudEl0ZXJhdG9yU2NoZW1hRGV0YWlscyhvdXRwdXRTY2hlbWEpO1xuICAgIGNvbnN0IG91dHB1dFN0cnVjdHVyZSA9IGZhbGxiYWNrQ29udHJhY3RDb25maWcoXCJkZWZhdWx0T3V0cHV0U3RydWN0dXJlXCIsIGRlZi5yb3V0ZS5vdXRwdXRTdHJ1Y3R1cmUpO1xuICAgIGlmIChldmVudEl0ZXJhdG9yU2NoZW1hRGV0YWlscykge1xuICAgICAgcmVmLnJlc3BvbnNlcyA/Pz0ge307XG4gICAgICByZWYucmVzcG9uc2VzW3N0YXR1c10gPSB7XG4gICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICBjb250ZW50OiB0b09wZW5BUElFdmVudEl0ZXJhdG9yQ29udGVudChcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KGV2ZW50SXRlcmF0b3JTY2hlbWFEZXRhaWxzLnlpZWxkcywgeyAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHN0cmF0ZWd5OiBcIm91dHB1dFwiIH0pLFxuICAgICAgICAgIGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoZXZlbnRJdGVyYXRvclNjaGVtYURldGFpbHMucmV0dXJucywgeyAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHN0cmF0ZWd5OiBcIm91dHB1dFwiIH0pXG4gICAgICAgIClcbiAgICAgIH07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtyZXF1aXJlZCwganNvbl0gPSBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KFxuICAgICAgb3V0cHV0U2NoZW1hLFxuICAgICAge1xuICAgICAgICAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsXG4gICAgICAgIHN0cmF0ZWd5OiBcIm91dHB1dFwiLFxuICAgICAgICBtaW5TdHJ1Y3R1cmVEZXB0aEZvclJlZjogb3V0cHV0U3RydWN0dXJlID09PSBcImRldGFpbGVkXCIgPyAxIDogMFxuICAgICAgfVxuICAgICk7XG4gICAgaWYgKG91dHB1dFN0cnVjdHVyZSA9PT0gXCJjb21wYWN0XCIpIHtcbiAgICAgIHJlZi5yZXNwb25zZXMgPz89IHt9O1xuICAgICAgcmVmLnJlc3BvbnNlc1tzdGF0dXNdID0ge1xuICAgICAgICBkZXNjcmlwdGlvblxuICAgICAgfTtcbiAgICAgIHJlZi5yZXNwb25zZXNbc3RhdHVzXS5jb250ZW50ID0gdG9PcGVuQVBJQ29udGVudChhcHBseVNjaGVtYU9wdGlvbmFsaXR5KHJlcXVpcmVkLCBqc29uKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhhbmRsZWRTdGF0dXNlcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGV4cGFuZFVuaW9uU2NoZW1hKGpzb24pKSB7XG4gICAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IoYFxuICAgICAgICBXaGVuIG91dHB1dCBzdHJ1Y3R1cmUgaXMgXCJkZXRhaWxlZFwiLCBvdXRwdXQgc2NoZW1hIG11c3Qgc2F0aXNmeTpcbiAgICAgICAgeyBcbiAgICAgICAgICBzdGF0dXM/OiBudW1iZXIsIC8vIG11c3QgYmUgYSBsaXRlcmFsIG51bWJlciBhbmQgaW4gdGhlIHJhbmdlIG9mIDIwMC0zOTlcbiAgICAgICAgICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIFxuICAgICAgICAgIGJvZHk/OiB1bmtub3duIFxuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBCdXQgZ290OiAke3N0cmluZ2lmeUpTT04oaXRlbSl9XG4gICAgICBgKTtcbiAgICAgIGlmICghaXNPYmplY3RTY2hlbWEoaXRlbSkpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICBsZXQgc2NoZW1hU3RhdHVzO1xuICAgICAgbGV0IHNjaGVtYURlc2NyaXB0aW9uO1xuICAgICAgaWYgKGl0ZW0ucHJvcGVydGllcz8uc3RhdHVzICE9PSB2b2lkIDApIHtcbiAgICAgICAgY29uc3Qgc3RhdHVzU2NoZW1hID0gcmVzb2x2ZU9wZW5BUElKc29uU2NoZW1hUmVmKGRvYywgaXRlbS5wcm9wZXJ0aWVzLnN0YXR1cyk7XG4gICAgICAgIGlmICh0eXBlb2Ygc3RhdHVzU2NoZW1hICE9PSBcIm9iamVjdFwiIHx8IHN0YXR1c1NjaGVtYS5jb25zdCA9PT0gdm9pZCAwIHx8IHR5cGVvZiBzdGF0dXNTY2hlbWEuY29uc3QgIT09IFwibnVtYmVyXCIgfHwgIU51bWJlci5pc0ludGVnZXIoc3RhdHVzU2NoZW1hLmNvbnN0KSB8fCBpc09SUENFcnJvclN0YXR1cyhzdGF0dXNTY2hlbWEuY29uc3QpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgc2NoZW1hU3RhdHVzID0gc3RhdHVzU2NoZW1hLmNvbnN0O1xuICAgICAgICBzY2hlbWFEZXNjcmlwdGlvbiA9IHN0YXR1c1NjaGVtYS5kZXNjcmlwdGlvbjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGl0ZW1TdGF0dXMgPSBzY2hlbWFTdGF0dXMgPz8gc3RhdHVzO1xuICAgICAgY29uc3QgaXRlbURlc2NyaXB0aW9uID0gc2NoZW1hRGVzY3JpcHRpb24gPz8gZGVzY3JpcHRpb247XG4gICAgICBpZiAoaGFuZGxlZFN0YXR1c2VzLmhhcyhpdGVtU3RhdHVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgT3BlbkFQSUdlbmVyYXRvckVycm9yKGBcbiAgICAgICAgICBXaGVuIG91dHB1dCBzdHJ1Y3R1cmUgaXMgXCJkZXRhaWxlZFwiLCBlYWNoIHN1Y2Nlc3Mgc3RhdHVzIG11c3QgYmUgdW5pcXVlLlxuICAgICAgICAgIEJ1dCBnb3Qgc3RhdHVzOiAke2l0ZW1TdGF0dXN9IHVzZWQgbW9yZSB0aGFuIG9uY2UuXG4gICAgICAgIGApO1xuICAgICAgfVxuICAgICAgaGFuZGxlZFN0YXR1c2VzLmFkZChpdGVtU3RhdHVzKTtcbiAgICAgIHJlZi5yZXNwb25zZXMgPz89IHt9O1xuICAgICAgcmVmLnJlc3BvbnNlc1tpdGVtU3RhdHVzXSA9IHtcbiAgICAgICAgZGVzY3JpcHRpb246IGl0ZW1EZXNjcmlwdGlvblxuICAgICAgfTtcbiAgICAgIGlmIChpdGVtLnByb3BlcnRpZXM/LmhlYWRlcnMgIT09IHZvaWQgMCkge1xuICAgICAgICBjb25zdCBoZWFkZXJzU2NoZW1hID0gcmVzb2x2ZU9wZW5BUElKc29uU2NoZW1hUmVmKGRvYywgaXRlbS5wcm9wZXJ0aWVzLmhlYWRlcnMpO1xuICAgICAgICBpZiAoIWlzT2JqZWN0U2NoZW1hKGhlYWRlcnNTY2hlbWEpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gaGVhZGVyc1NjaGVtYS5wcm9wZXJ0aWVzKSB7XG4gICAgICAgICAgY29uc3QgaGVhZGVyU2NoZW1hID0gaGVhZGVyc1NjaGVtYS5wcm9wZXJ0aWVzW2tleV07XG4gICAgICAgICAgaWYgKGhlYWRlclNjaGVtYSAhPT0gdm9pZCAwKSB7XG4gICAgICAgICAgICByZWYucmVzcG9uc2VzW2l0ZW1TdGF0dXNdLmhlYWRlcnMgPz89IHt9O1xuICAgICAgICAgICAgcmVmLnJlc3BvbnNlc1tpdGVtU3RhdHVzXS5oZWFkZXJzW2tleV0gPSB7XG4gICAgICAgICAgICAgIHNjaGVtYTogdG9PcGVuQVBJU2NoZW1hKGhlYWRlclNjaGVtYSksXG4gICAgICAgICAgICAgIHJlcXVpcmVkOiBpdGVtLnJlcXVpcmVkPy5pbmNsdWRlcyhcImhlYWRlcnNcIikgJiYgaGVhZGVyc1NjaGVtYS5yZXF1aXJlZD8uaW5jbHVkZXMoa2V5KVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpdGVtLnByb3BlcnRpZXM/LmJvZHkgIT09IHZvaWQgMCkge1xuICAgICAgICByZWYucmVzcG9uc2VzW2l0ZW1TdGF0dXNdLmNvbnRlbnQgPSB0b09wZW5BUElDb250ZW50KFxuICAgICAgICAgIGFwcGx5U2NoZW1hT3B0aW9uYWxpdHkoaXRlbS5yZXF1aXJlZD8uaW5jbHVkZXMoXCJib2R5XCIpID8/IGZhbHNlLCBpdGVtLnByb3BlcnRpZXMuYm9keSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgYXN5bmMgI2Vycm9yUmVzcG9uc2UocmVmLCBkZWYsIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgdW5kZWZpbmVkRXJyb3JTY2hlbWEsIGN1c3RvbUVycm9yUmVzcG9uc2VCb2R5U2NoZW1hKSB7XG4gICAgY29uc3QgZXJyb3JNYXAgPSBkZWYuZXJyb3JNYXA7XG4gICAgY29uc3QgZXJyb3JSZXNwb25zZXNCeVN0YXR1cyA9IHt9O1xuICAgIGZvciAoY29uc3QgY29kZSBpbiBlcnJvck1hcCkge1xuICAgICAgY29uc3QgY29uZmlnID0gZXJyb3JNYXBbY29kZV07XG4gICAgICBpZiAoIWNvbmZpZykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXR1cyA9IGZhbGxiYWNrT1JQQ0Vycm9yU3RhdHVzKGNvZGUsIGNvbmZpZy5zdGF0dXMpO1xuICAgICAgY29uc3QgZGVmYXVsdE1lc3NhZ2UgPSBmYWxsYmFja09SUENFcnJvck1lc3NhZ2UoY29kZSwgY29uZmlnLm1lc3NhZ2UpO1xuICAgICAgZXJyb3JSZXNwb25zZXNCeVN0YXR1c1tzdGF0dXNdID8/PSB7IHN0YXR1cywgZGVmaW5lZEVycm9yRGVmaW5pdGlvbnM6IFtdLCBlcnJvclNjaGVtYVZhcmlhbnRzOiBbXSB9O1xuICAgICAgY29uc3QgW2RhdGFSZXF1aXJlZCwgZGF0YVNjaGVtYV0gPSBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KGNvbmZpZy5kYXRhLCB7IC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgc3RyYXRlZ3k6IFwib3V0cHV0XCIgfSk7XG4gICAgICBlcnJvclJlc3BvbnNlc0J5U3RhdHVzW3N0YXR1c10uZGVmaW5lZEVycm9yRGVmaW5pdGlvbnMucHVzaChbY29kZSwgZGVmYXVsdE1lc3NhZ2UsIGRhdGFSZXF1aXJlZCwgZGF0YVNjaGVtYV0pO1xuICAgICAgZXJyb3JSZXNwb25zZXNCeVN0YXR1c1tzdGF0dXNdLmVycm9yU2NoZW1hVmFyaWFudHMucHVzaCh7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBkZWZpbmVkOiB7IGNvbnN0OiB0cnVlIH0sXG4gICAgICAgICAgY29kZTogeyBjb25zdDogY29kZSB9LFxuICAgICAgICAgIHN0YXR1czogeyBjb25zdDogc3RhdHVzIH0sXG4gICAgICAgICAgbWVzc2FnZTogeyB0eXBlOiBcInN0cmluZ1wiLCBkZWZhdWx0OiBkZWZhdWx0TWVzc2FnZSB9LFxuICAgICAgICAgIGRhdGE6IGRhdGFTY2hlbWFcbiAgICAgICAgfSxcbiAgICAgICAgcmVxdWlyZWQ6IGRhdGFSZXF1aXJlZCA/IFtcImRlZmluZWRcIiwgXCJjb2RlXCIsIFwic3RhdHVzXCIsIFwibWVzc2FnZVwiLCBcImRhdGFcIl0gOiBbXCJkZWZpbmVkXCIsIFwiY29kZVwiLCBcInN0YXR1c1wiLCBcIm1lc3NhZ2VcIl1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZWYucmVzcG9uc2VzID8/PSB7fTtcbiAgICBmb3IgKGNvbnN0IHN0YXR1c1N0cmluZyBpbiBlcnJvclJlc3BvbnNlc0J5U3RhdHVzKSB7XG4gICAgICBjb25zdCBlcnJvclJlc3BvbnNlID0gZXJyb3JSZXNwb25zZXNCeVN0YXR1c1tzdGF0dXNTdHJpbmddO1xuICAgICAgY29uc3QgY3VzdG9tQm9keVNjaGVtYSA9IHZhbHVlKGN1c3RvbUVycm9yUmVzcG9uc2VCb2R5U2NoZW1hLCBlcnJvclJlc3BvbnNlLmRlZmluZWRFcnJvckRlZmluaXRpb25zLCBlcnJvclJlc3BvbnNlLnN0YXR1cyk7XG4gICAgICByZWYucmVzcG9uc2VzW3N0YXR1c1N0cmluZ10gPSB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBzdGF0dXNTdHJpbmcsXG4gICAgICAgIGNvbnRlbnQ6IHRvT3BlbkFQSUNvbnRlbnQoY3VzdG9tQm9keVNjaGVtYSA/PyB7XG4gICAgICAgICAgb25lT2Y6IFtcbiAgICAgICAgICAgIC4uLmVycm9yUmVzcG9uc2UuZXJyb3JTY2hlbWFWYXJpYW50cyxcbiAgICAgICAgICAgIHVuZGVmaW5lZEVycm9yU2NoZW1hXG4gICAgICAgICAgXVxuICAgICAgICB9KVxuICAgICAgfTtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IHsgQ29tcG9zaXRlU2NoZW1hQ29udmVydGVyIGFzIEMsIExPR0lDX0tFWVdPUkRTIGFzIEwsIE9wZW5BUElHZW5lcmF0b3IgYXMgTywgYXBwbHlDdXN0b21PcGVuQVBJT3BlcmF0aW9uIGFzIGEsIHRvT3BlbkFQSU1ldGhvZCBhcyBiLCBjdXN0b21PcGVuQVBJT3BlcmF0aW9uIGFzIGMsIHRvT3BlbkFQSUNvbnRlbnQgYXMgZCwgdG9PcGVuQVBJRXZlbnRJdGVyYXRvckNvbnRlbnQgYXMgZSwgdG9PcGVuQVBJUGFyYW1ldGVycyBhcyBmLCBnZXRDdXN0b21PcGVuQVBJT3BlcmF0aW9uIGFzIGcsIGNoZWNrUGFyYW1zU2NoZW1hIGFzIGgsIHRvT3BlbkFQSVNjaGVtYSBhcyBpLCBpc0ZpbGVTY2hlbWEgYXMgaiwgaXNPYmplY3RTY2hlbWEgYXMgaywgaXNBbnlTY2hlbWEgYXMgbCwgZmlsdGVyU2NoZW1hQnJhbmNoZXMgYXMgbSwgYXBwbHlTY2hlbWFPcHRpb25hbGl0eSBhcyBuLCBleHBhbmRVbmlvblNjaGVtYSBhcyBvLCBleHBhbmRBcnJheWFibGVTY2hlbWEgYXMgcCwgaXNQcmltaXRpdmVTY2hlbWEgYXMgcSwgcmVzb2x2ZU9wZW5BUElKc29uU2NoZW1hUmVmIGFzIHIsIHNlcGFyYXRlT2JqZWN0U2NoZW1hIGFzIHMsIHRvT3BlbkFQSVBhdGggYXMgdCB9O1xuIiwiaW1wb3J0IHsgc3RyaW5naWZ5SlNPTiwgb25jZSwgdmFsdWUgfSBmcm9tICdAb3JwYy9zaGFyZWQnO1xuaW1wb3J0IHsgTyBhcyBPcGVuQVBJR2VuZXJhdG9yIH0gZnJvbSAnLi4vc2hhcmVkL29wZW5hcGkuRHJUY2VsbDUubWpzJztcbmltcG9ydCAnQG9ycGMvY2xpZW50JztcbmltcG9ydCAnQG9ycGMvY2xpZW50L3N0YW5kYXJkJztcbmltcG9ydCAnQG9ycGMvY29udHJhY3QnO1xuaW1wb3J0ICdAb3JwYy9vcGVuYXBpLWNsaWVudC9zdGFuZGFyZCc7XG5pbXBvcnQgJ0BvcnBjL3NlcnZlcic7XG5pbXBvcnQgJ0BvcnBjL2ludGVyb3AvanNvbi1zY2hlbWEtdHlwZWQvZHJhZnQtMjAyMC0xMic7XG5cbmNsYXNzIE9wZW5BUElSZWZlcmVuY2VQbHVnaW4ge1xuICBnZW5lcmF0b3I7XG4gIHNwZWNHZW5lcmF0ZU9wdGlvbnM7XG4gIHNwZWNQYXRoO1xuICBkb2NzUGF0aDtcbiAgZG9jc1RpdGxlO1xuICBkb2NzSGVhZDtcbiAgZG9jc1Byb3ZpZGVyO1xuICBkb2NzU2NyaXB0VXJsO1xuICBkb2NzQ3NzVXJsO1xuICBkb2NzQ29uZmlnO1xuICByZW5kZXJEb2NzSHRtbDtcbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5zcGVjR2VuZXJhdGVPcHRpb25zID0gb3B0aW9ucy5zcGVjR2VuZXJhdGVPcHRpb25zO1xuICAgIHRoaXMuZG9jc1BhdGggPSBvcHRpb25zLmRvY3NQYXRoID8/IFwiL1wiO1xuICAgIHRoaXMuZG9jc1RpdGxlID0gb3B0aW9ucy5kb2NzVGl0bGUgPz8gXCJBUEkgUmVmZXJlbmNlXCI7XG4gICAgdGhpcy5kb2NzQ29uZmlnID0gb3B0aW9ucy5kb2NzQ29uZmlnID8/IHZvaWQgMDtcbiAgICB0aGlzLmRvY3NQcm92aWRlciA9IG9wdGlvbnMuZG9jc1Byb3ZpZGVyID8/IFwic2NhbGFyXCI7XG4gICAgdGhpcy5kb2NzU2NyaXB0VXJsID0gb3B0aW9ucy5kb2NzU2NyaXB0VXJsID8/ICh0aGlzLmRvY3NQcm92aWRlciA9PT0gXCJzd2FnZ2VyXCIgPyBcImh0dHBzOi8vdW5wa2cuY29tL3N3YWdnZXItdWktZGlzdC9zd2FnZ2VyLXVpLWJ1bmRsZS5qc1wiIDogXCJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BzY2FsYXIvYXBpLXJlZmVyZW5jZVwiKTtcbiAgICB0aGlzLmRvY3NDc3NVcmwgPSBvcHRpb25zLmRvY3NDc3NVcmwgPz8gKHRoaXMuZG9jc1Byb3ZpZGVyID09PSBcInN3YWdnZXJcIiA/IFwiaHR0cHM6Ly91bnBrZy5jb20vc3dhZ2dlci11aS1kaXN0L3N3YWdnZXItdWkuY3NzXCIgOiB2b2lkIDApO1xuICAgIHRoaXMuZG9jc0hlYWQgPSBvcHRpb25zLmRvY3NIZWFkID8/IFwiXCI7XG4gICAgdGhpcy5zcGVjUGF0aCA9IG9wdGlvbnMuc3BlY1BhdGggPz8gXCIvc3BlYy5qc29uXCI7XG4gICAgdGhpcy5nZW5lcmF0b3IgPSBuZXcgT3BlbkFQSUdlbmVyYXRvcihvcHRpb25zKTtcbiAgICBjb25zdCBlc2MgPSAocykgPT4gcy5yZXBsYWNlKC8mL2csIFwiJmFtcDtcIikucmVwbGFjZSgvXCIvZywgXCImcXVvdDtcIikucmVwbGFjZSgvPC9nLCBcIiZsdDtcIikucmVwbGFjZSgvPi9nLCBcIiZndDtcIik7XG4gICAgdGhpcy5yZW5kZXJEb2NzSHRtbCA9IG9wdGlvbnMucmVuZGVyRG9jc0h0bWwgPz8gKChzcGVjVXJsLCB0aXRsZSwgaGVhZCwgc2NyaXB0VXJsLCBjb25maWcsIHNwZWMsIGRvY3NQcm92aWRlciwgY3NzVXJsKSA9PiB7XG4gICAgICBsZXQgYm9keTtcbiAgICAgIGlmIChkb2NzUHJvdmlkZXIgPT09IFwic3dhZ2dlclwiKSB7XG4gICAgICAgIGNvbnN0IHN3YWdnZXJDb25maWcgPSB7XG4gICAgICAgICAgZG9tX2lkOiBcIiNhcHBcIixcbiAgICAgICAgICBzcGVjLFxuICAgICAgICAgIGRlZXBMaW5raW5nOiB0cnVlLFxuICAgICAgICAgIHByZXNldHM6IFtcbiAgICAgICAgICAgIFwiU3dhZ2dlclVJQnVuZGxlLnByZXNldHMuYXBpc1wiLFxuICAgICAgICAgICAgXCJTd2FnZ2VyVUlCdW5kbGUucHJlc2V0cy5zdGFuZGFsb25lXCJcbiAgICAgICAgICBdLFxuICAgICAgICAgIHBsdWdpbnM6IFtcbiAgICAgICAgICAgIFwiU3dhZ2dlclVJQnVuZGxlLnBsdWdpbnMuRG93bmxvYWRVcmxcIlxuICAgICAgICAgIF0sXG4gICAgICAgICAgLi4uY29uZmlnXG4gICAgICAgIH07XG4gICAgICAgIGJvZHkgPSBgXG4gICAgICAgIDxib2R5PlxuICAgICAgICAgIDxkaXYgaWQ9XCJhcHBcIj48L2Rpdj5cblxuICAgICAgICAgIDxzY3JpcHQgc3JjPVwiJHtlc2Moc2NyaXB0VXJsKX1cIj48XFwvc2NyaXB0PlxuXG4gICAgICAgICAgPHNjcmlwdD5cbiAgICAgICAgICAgIHdpbmRvdy5vbmxvYWQgPSAoKSA9PiB7XG4gICAgICAgICAgICAgIHdpbmRvdy51aSA9IFN3YWdnZXJVSUJ1bmRsZSgke3N0cmluZ2lmeUpTT04oc3dhZ2dlckNvbmZpZykucmVwbGFjZSgvXCIoU3dhZ2dlclVJQnVuZGxlXFwuW15cIl0rKVwiL2csIFwiJDFcIil9KVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDxcXC9zY3JpcHQ+XG4gICAgICAgIDwvYm9keT5cbiAgICAgICAgYDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHNjYWxhckNvbmZpZyA9IHtcbiAgICAgICAgICBjb250ZW50OiBzdHJpbmdpZnlKU09OKHNwZWMpLFxuICAgICAgICAgIC4uLmNvbmZpZ1xuICAgICAgICB9O1xuICAgICAgICBib2R5ID0gYFxuICAgICAgICA8Ym9keT5cbiAgICAgICAgICA8ZGl2IGlkPVwiYXBwXCIgZGF0YS1jb25maWc9XCIke2VzYyhzdHJpbmdpZnlKU09OKHNjYWxhckNvbmZpZykpfVwiPjwvZGl2PlxuXG4gICAgICAgICAgPHNjcmlwdCBzcmM9XCIke2VzYyhzY3JpcHRVcmwpfVwiPjxcXC9zY3JpcHQ+XG5cbiAgICAgICAgICA8c2NyaXB0PlxuICAgICAgICAgICAgU2NhbGFyLmNyZWF0ZUFwaVJlZmVyZW5jZSgnI2FwcCcsIEpTT04ucGFyc2UoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2FwcCcpLmRhdGFzZXQuY29uZmlnKSlcbiAgICAgICAgICA8XFwvc2NyaXB0PlxuICAgICAgICA8L2JvZHk+XG4gICAgICAgIGA7XG4gICAgICB9XG4gICAgICByZXR1cm4gYFxuICAgICAgICA8IWRvY3R5cGUgaHRtbD5cbiAgICAgICAgPGh0bWw+XG4gICAgICAgICAgPGhlYWQ+XG4gICAgICAgICAgICA8bWV0YSBjaGFyc2V0PVwidXRmLThcIiAvPlxuICAgICAgICAgICAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xXCIgLz5cbiAgICAgICAgICAgIDx0aXRsZT4ke2VzYyh0aXRsZSl9PC90aXRsZT5cbiAgICAgICAgICAgICR7Y3NzVXJsID8gYDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiB0eXBlPVwidGV4dC9jc3NcIiBocmVmPVwiJHtlc2MoY3NzVXJsKX1cIiAvPmAgOiBcIlwifVxuICAgICAgICAgICAgJHtoZWFkfVxuICAgICAgICAgIDwvaGVhZD5cbiAgICAgICAgICAke2JvZHl9XG4gICAgICAgIDwvaHRtbD5cbiAgICAgICAgYDtcbiAgICB9KTtcbiAgfVxuICBpbml0KG9wdGlvbnMsIHJvdXRlcikge1xuICAgIG9wdGlvbnMuaW50ZXJjZXB0b3JzID8/PSBbXTtcbiAgICBvcHRpb25zLmludGVyY2VwdG9ycy5wdXNoKGFzeW5jIChvcHRpb25zMikgPT4ge1xuICAgICAgY29uc3QgcmVzID0gYXdhaXQgb3B0aW9uczIubmV4dCgpO1xuICAgICAgaWYgKHJlcy5tYXRjaGVkIHx8IG9wdGlvbnMyLnJlcXVlc3QubWV0aG9kICE9PSBcIkdFVFwiKSB7XG4gICAgICAgIHJldHVybiByZXM7XG4gICAgICB9XG4gICAgICBjb25zdCBwcmVmaXggPSBvcHRpb25zMi5wcmVmaXggPz8gXCJcIjtcbiAgICAgIGNvbnN0IHJlcXVlc3RQYXRobmFtZSA9IG9wdGlvbnMyLnJlcXVlc3QudXJsLnBhdGhuYW1lLnJlcGxhY2UoL1xcLyQvLCBcIlwiKSB8fCBcIi9cIjtcbiAgICAgIGNvbnN0IGRvY3NVcmwgPSBuZXcgVVJMKGAke3ByZWZpeH0ke3RoaXMuZG9jc1BhdGh9YC5yZXBsYWNlKC9cXC8kLywgXCJcIiksIG9wdGlvbnMyLnJlcXVlc3QudXJsLm9yaWdpbik7XG4gICAgICBjb25zdCBzcGVjVXJsID0gbmV3IFVSTChgJHtwcmVmaXh9JHt0aGlzLnNwZWNQYXRofWAucmVwbGFjZSgvXFwvJC8sIFwiXCIpLCBvcHRpb25zMi5yZXF1ZXN0LnVybC5vcmlnaW4pO1xuICAgICAgY29uc3QgZ2VuZXJhdGVTcGVjID0gb25jZShhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmdlbmVyYXRvci5nZW5lcmF0ZShyb3V0ZXIsIHtcbiAgICAgICAgICBzZXJ2ZXJzOiBbeyB1cmw6IG5ldyBVUkwocHJlZml4LCBvcHRpb25zMi5yZXF1ZXN0LnVybC5vcmlnaW4pLnRvU3RyaW5nKCkgfV0sXG4gICAgICAgICAgLi4uYXdhaXQgdmFsdWUodGhpcy5zcGVjR2VuZXJhdGVPcHRpb25zLCBvcHRpb25zMilcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGlmIChyZXF1ZXN0UGF0aG5hbWUgPT09IHNwZWNVcmwucGF0aG5hbWUpIHtcbiAgICAgICAgY29uc3Qgc3BlYyA9IGF3YWl0IGdlbmVyYXRlU3BlYygpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG1hdGNoZWQ6IHRydWUsXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgICAgICBib2R5OiBuZXcgRmlsZShbc3RyaW5naWZ5SlNPTihzcGVjKV0sIFwic3BlYy5qc29uXCIsIHsgdHlwZTogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICBpZiAocmVxdWVzdFBhdGhuYW1lID09PSBkb2NzVXJsLnBhdGhuYW1lKSB7XG4gICAgICAgIGNvbnN0IGh0bWwgPSB0aGlzLnJlbmRlckRvY3NIdG1sKFxuICAgICAgICAgIHNwZWNVcmwudG9TdHJpbmcoKSxcbiAgICAgICAgICBhd2FpdCB2YWx1ZSh0aGlzLmRvY3NUaXRsZSwgb3B0aW9uczIpLFxuICAgICAgICAgIGF3YWl0IHZhbHVlKHRoaXMuZG9jc0hlYWQsIG9wdGlvbnMyKSxcbiAgICAgICAgICBhd2FpdCB2YWx1ZSh0aGlzLmRvY3NTY3JpcHRVcmwsIG9wdGlvbnMyKSxcbiAgICAgICAgICBhd2FpdCB2YWx1ZSh0aGlzLmRvY3NDb25maWcsIG9wdGlvbnMyKSxcbiAgICAgICAgICBhd2FpdCBnZW5lcmF0ZVNwZWMoKSxcbiAgICAgICAgICB0aGlzLmRvY3NQcm92aWRlcixcbiAgICAgICAgICBhd2FpdCB2YWx1ZSh0aGlzLmRvY3NDc3NVcmwsIG9wdGlvbnMyKVxuICAgICAgICApO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG1hdGNoZWQ6IHRydWUsXG4gICAgICAgICAgcmVzcG9uc2U6IHtcbiAgICAgICAgICAgIHN0YXR1czogMjAwLFxuICAgICAgICAgICAgaGVhZGVyczoge30sXG4gICAgICAgICAgICBib2R5OiBuZXcgRmlsZShbaHRtbF0sIFwiYXBpLXJlZmVyZW5jZS5odG1sXCIsIHsgdHlwZTogXCJ0ZXh0L2h0bWxcIiB9KVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXM7XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0IHsgT3BlbkFQSVJlZmVyZW5jZVBsdWdpbiB9O1xuIl0sInhfZ29vZ2xlX2lnbm9yZUxpc3QiOlswLDEsMl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUFRQSxJQUFJO0NBQ0gsU0FBUyxrQkFBa0I7QUFDeEIsa0JBQWlCLFVBQVU7QUFDM0Isa0JBQWlCLFVBQVU7QUFDM0Isa0JBQWlCLFlB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