every-plugin 0.4.14 → 0.4.15

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 (85) hide show
  1. package/dist/build/rspack/index.cjs +3 -3
  2. package/dist/build/rspack/index.cjs.map +1 -0
  3. package/dist/build/rspack/index.d.cts +1 -1
  4. package/dist/build/rspack/index.d.cts.map +1 -0
  5. package/dist/build/rspack/index.d.mts +1 -1
  6. package/dist/build/rspack/index.d.mts.map +1 -0
  7. package/dist/build/rspack/index.mjs +3 -3
  8. package/dist/build/rspack/index.mjs.map +1 -0
  9. package/dist/errors-9sNpYLv5.d.mts +1 -1
  10. package/dist/errors-9sNpYLv5.d.mts.map +1 -0
  11. package/dist/errors-CVnoPl9v.cjs +1 -1
  12. package/dist/errors-CVnoPl9v.cjs.map +1 -0
  13. package/dist/errors-D7keKf7a.mjs +1 -1
  14. package/dist/errors-D7keKf7a.mjs.map +1 -0
  15. package/dist/errors-DKPPPYYT.d.cts +1 -1
  16. package/dist/errors-DKPPPYYT.d.cts.map +1 -0
  17. package/dist/fetch-8DauUFDh.mjs +335 -0
  18. package/dist/fetch-8DauUFDh.mjs.map +1 -0
  19. package/dist/fetch-CrBvwsZ4.cjs +336 -0
  20. package/dist/fetch-CrBvwsZ4.cjs.map +1 -0
  21. package/dist/index-Coz54d1B.d.mts +387 -0
  22. package/dist/index-Coz54d1B.d.mts.map +1 -0
  23. package/dist/index-G63gBZIY.d.cts +386 -0
  24. package/dist/index-G63gBZIY.d.cts.map +1 -0
  25. package/dist/index.cjs +2 -2
  26. package/dist/index.cjs.map +1 -0
  27. package/dist/index.d.cts +1 -1
  28. package/dist/index.d.mts +1 -1
  29. package/dist/index.mjs +2 -2
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/normalize-BW7kk8Lk.d.cts +1 -1
  32. package/dist/normalize-BW7kk8Lk.d.cts.map +1 -0
  33. package/dist/normalize-D4Qh0wVk.cjs +1 -1
  34. package/dist/normalize-D4Qh0wVk.cjs.map +1 -0
  35. package/dist/normalize-D7nae0Hn.mjs +1 -1
  36. package/dist/normalize-D7nae0Hn.mjs.map +1 -0
  37. package/dist/normalize-eB_j86fm.d.mts +1 -1
  38. package/dist/normalize-eB_j86fm.d.mts.map +1 -0
  39. package/dist/package-BoyftHDo.mjs +1 -1
  40. package/dist/package-BoyftHDo.mjs.map +1 -0
  41. package/dist/package-CgNIVjVe.cjs +1 -1
  42. package/dist/package-CgNIVjVe.cjs.map +1 -0
  43. package/dist/plugins-C6MGKdD-.mjs +790 -0
  44. package/dist/plugins-C6MGKdD-.mjs.map +1 -0
  45. package/dist/plugins-DNaNtkG7.cjs +791 -0
  46. package/dist/plugins-DNaNtkG7.cjs.map +1 -0
  47. package/dist/runtime/index.cjs +1 -1
  48. package/dist/runtime/index.d.cts +1 -1
  49. package/dist/runtime/index.d.mts +1 -1
  50. package/dist/runtime/index.mjs +1 -1
  51. package/dist/runtime-60AkNpI0.mjs +476 -0
  52. package/dist/runtime-60AkNpI0.mjs.map +1 -0
  53. package/dist/runtime-BcksCIA1.cjs +541 -0
  54. package/dist/runtime-BcksCIA1.cjs.map +1 -0
  55. package/dist/standard-CkH8zNkx.mjs +584 -0
  56. package/dist/standard-CkH8zNkx.mjs.map +1 -0
  57. package/dist/standard-v75BC6Z5.cjs +685 -0
  58. package/dist/standard-v75BC6Z5.cjs.map +1 -0
  59. package/dist/testing/index.cjs +2 -2
  60. package/dist/testing/index.cjs.map +1 -0
  61. package/dist/testing/index.d.cts +2 -2
  62. package/dist/testing/index.d.cts.map +1 -0
  63. package/dist/testing/index.d.mts +2 -2
  64. package/dist/testing/index.d.mts.map +1 -0
  65. package/dist/testing/index.mjs +2 -2
  66. package/dist/testing/index.mjs.map +1 -0
  67. package/dist/zod-A7Pti5IV.d.cts +1 -1
  68. package/dist/zod-A7Pti5IV.d.cts.map +1 -0
  69. package/dist/zod-BVo51kgJ.mjs +1 -1
  70. package/dist/zod-BVo51kgJ.mjs.map +1 -0
  71. package/dist/zod-DYghWCz1.cjs +1 -1
  72. package/dist/zod-DYghWCz1.cjs.map +1 -0
  73. package/dist/zod-Zw8dlP3j.d.mts +1 -1
  74. package/dist/zod-Zw8dlP3j.d.mts.map +1 -0
  75. package/package.json +1 -1
  76. package/dist/fetch-CGzn1Uf7.cjs +0 -336
  77. package/dist/fetch-ycs0raYN.mjs +0 -335
  78. package/dist/index-DM9S53Bx.d.cts +0 -382
  79. package/dist/index-DrOou1Hc.d.mts +0 -383
  80. package/dist/plugins-Cmsm3gW1.cjs +0 -791
  81. package/dist/plugins-hpi2GlaX.mjs +0 -790
  82. package/dist/runtime-BYrdNAff.cjs +0 -524
  83. package/dist/runtime-BzkHRj0E.mjs +0 -459
  84. package/dist/standard-0wBehDUp.cjs +0 -685
  85. package/dist/standard-CYaRay89.mjs +0 -584
@@ -1,791 +0,0 @@
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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