every-plugin 0.4.9 → 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.
- package/dist/build/rspack/index.cjs +45 -7
- package/dist/build/rspack/index.mjs +45 -7
- package/dist/{errors-CVnoPl9v.cjs → errors-BEsEPXKG.cjs} +2 -2
- package/dist/errors-CpYzD_-M.d.cts +38 -0
- package/dist/errors-D2-thHKG.d.mts +38 -0
- package/dist/{errors-D7keKf7a.mjs → errors-DnigICIv.mjs} +2 -2
- package/dist/errors.cjs +2 -2
- package/dist/errors.d.cts +1 -2
- package/dist/errors.d.mts +1 -2
- package/dist/errors.mjs +2 -2
- package/dist/{fetch-Cc95-7kM.cjs → fetch-CGzn1Uf7.cjs} +2 -2
- package/dist/{fetch-KLktuWuM.mjs → fetch-ycs0raYN.mjs} +2 -2
- package/dist/{index-matrPV4m.d.cts → index-BXfi8DqC.d.cts} +1 -1
- package/dist/{index-bwAhA9ca.d.mts → index-DvIxKA8K.d.mts} +2 -2
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +3 -4
- package/dist/index.d.mts +3 -4
- package/dist/index.mjs +4 -4
- package/dist/{normalize-BLTyqFww.d.mts → normalize-BCE_FLe8.d.mts} +1 -1
- package/dist/{normalize-BW7kk8Lk.d.cts → normalize-Tt7I_RdD.d.cts} +1 -1
- package/dist/package-C2Mp8qeD.cjs +155 -0
- package/dist/package-uEsV9Z-2.mjs +150 -0
- package/dist/plugins-Cmsm3gW1.cjs +791 -0
- package/dist/plugins-hpi2GlaX.mjs +790 -0
- package/dist/runtime/index.cjs +2 -2
- package/dist/runtime/index.d.cts +3 -4
- package/dist/runtime/index.d.mts +3 -4
- package/dist/runtime/index.mjs +2 -2
- package/dist/runtime/services/normalize.d.cts +1 -1
- package/dist/runtime/services/normalize.d.mts +1 -1
- package/dist/{runtime-Daw9Tlz6.mjs → runtime-BUQ0hy1J.mjs} +3 -3
- package/dist/{runtime-CWCl3EIz.cjs → runtime-LlP2xpdB.cjs} +3 -3
- package/dist/{standard-eUgUkWaf.cjs → standard-0wBehDUp.cjs} +1 -18
- package/dist/{standard-DaxKTFui.mjs → standard-CYaRay89.mjs} +2 -13
- package/dist/testing/index.cjs +2 -2
- package/dist/testing/index.d.cts +4 -5
- package/dist/testing/index.d.mts +4 -5
- package/dist/testing/index.mjs +2 -2
- package/dist/zod-BDDjyyHQ.mjs +10 -0
- package/dist/{zod-DYghWCz1.cjs → zod-CJY4vNLR.cjs} +2 -2
- package/dist/zod.cjs +4 -4
- package/dist/zod.d.cts +1 -2
- package/dist/zod.d.mts +1 -2
- package/dist/zod.mjs +2 -2
- package/package.json +3 -2
- package/dist/errors-Car4tFVP.d.mts +0 -75
- package/dist/errors-DKPPPYYT.d.cts +0 -75
- package/dist/openapi.DrTcell5-C6kyDyUK.mjs +0 -669
- package/dist/openapi.DrTcell5-DDf4D5V3.cjs +0 -687
- package/dist/package-BwFfsvZZ.mjs +0 -149
- package/dist/package-CSi-6ikY.cjs +0 -154
- package/dist/plugins-C-7lh5gK.cjs +0 -128
- package/dist/plugins-Ps5Xxpk2.mjs +0 -128
- package/dist/zod-A7Pti5IV.d.cts +0 -4
- package/dist/zod-BVo51kgJ.mjs +0 -10
- package/dist/zod-D4CFw8d9.d.mts +0 -4
- package/dist/zod4-BXTBR1od.cjs +0 -318
- 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, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
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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
|