@sdkgen/node-runtime 0.0.0-dev.20230106165109 → 0.0.0-dev.20230109134521
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/spec/error.spec.js +3 -4
- package/dist/spec/rest/rest.spec.js +24 -24
- package/dist/spec/runtime/errors.spec.js +15 -14
- package/dist/spec/runtime/middleware.spec.js +15 -14
- package/dist/spec/simple/legacyNodeClient.js +6 -32
- package/dist/spec/simple/simple.spec.js +27 -28
- package/dist/spec/types.js +27 -28
- package/dist/spec/types.spec.js +54 -55
- package/dist/src/api-config.js +4 -8
- package/dist/src/context.js +2 -2
- package/dist/src/encode-decode.js +12 -50
- package/dist/src/error.js +4 -9
- package/dist/src/execute.js +12 -14
- package/dist/src/http-client.js +25 -27
- package/dist/src/http-server.js +160 -170
- package/dist/src/index.js +8 -18
- package/dist/src/new-interface.js +200 -0
- package/dist/src/swagger.js +126 -115
- package/dist/src/test-wrapper.js +25 -23
- package/dist/src/utils.js +2 -5
- package/package.json +27 -22
- package/dist/spec/error.spec.d.ts +0 -1
- package/dist/spec/rest/rest.spec.d.ts +0 -1
- package/dist/spec/runtime/errors.spec.d.ts +0 -1
- package/dist/spec/runtime/middleware.spec.d.ts +0 -1
- package/dist/spec/simple/legacyNodeClient.d.ts +0 -17
- package/dist/spec/simple/simple.spec.d.ts +0 -1
- package/dist/spec/types.d.ts +0 -1
- package/dist/spec/types.spec.d.ts +0 -1
- package/dist/src/api-config.d.ts +0 -15
- package/dist/src/context.d.ts +0 -38
- package/dist/src/encode-decode.d.ts +0 -32
- package/dist/src/error.d.ts +0 -18
- package/dist/src/execute.d.ts +0 -3
- package/dist/src/http-client.d.ts +0 -17
- package/dist/src/http-server.d.ts +0 -37
- package/dist/src/index.d.ts +0 -7
- package/dist/src/swagger.d.ts +0 -2
- package/dist/src/test-wrapper.d.ts +0 -3
- package/dist/src/utils.d.ts +0 -6
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/src/index.js
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var error_1 = require("./error");
|
|
10
|
-
Object.defineProperty(exports, "Fatal", { enumerable: true, get: function () { return error_1.Fatal; } });
|
|
11
|
-
Object.defineProperty(exports, "SdkgenError", { enumerable: true, get: function () { return error_1.SdkgenError; } });
|
|
12
|
-
Object.defineProperty(exports, "SdkgenErrorWithData", { enumerable: true, get: function () { return error_1.SdkgenErrorWithData; } });
|
|
13
|
-
var http_client_1 = require("./http-client");
|
|
14
|
-
Object.defineProperty(exports, "SdkgenHttpClient", { enumerable: true, get: function () { return http_client_1.SdkgenHttpClient; } });
|
|
15
|
-
var http_server_1 = require("./http-server");
|
|
16
|
-
Object.defineProperty(exports, "SdkgenHttpServer", { enumerable: true, get: function () { return http_server_1.SdkgenHttpServer; } });
|
|
17
|
-
var test_wrapper_1 = require("./test-wrapper");
|
|
18
|
-
Object.defineProperty(exports, "apiTestWrapper", { enumerable: true, get: function () { return test_wrapper_1.apiTestWrapper; } });
|
|
1
|
+
export { BaseApiConfig } from "./api-config.js";
|
|
2
|
+
export { decode, encode } from "./encode-decode.js";
|
|
3
|
+
export { Fatal, SdkgenError, SdkgenErrorWithData } from "./error.js";
|
|
4
|
+
export { SdkgenHttpClient } from "./http-client.js";
|
|
5
|
+
export { SdkgenHttpServer } from "./http-server.js";
|
|
6
|
+
export { apiTestWrapper } from "./test-wrapper.js";
|
|
7
|
+
export { startSdkgenServer, createSdkgenEndpoint, createSdkgenType, createSdkgenTestClient, Uuid, Int, UInt, encodeValue, decodeValue, } from "./new-interface.js";
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBR2hELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDcEQsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ25ELE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsb0JBQW9CLEVBQ3BCLGdCQUFnQixFQUNoQixzQkFBc0IsRUFDdEIsSUFBSSxFQUNKLEdBQUcsRUFDSCxJQUFJLEVBQ0osV0FBVyxFQUNYLFdBQVcsR0FJWixNQUFNLG9CQUFvQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgQmFzZUFwaUNvbmZpZyB9IGZyb20gXCIuL2FwaS1jb25maWcuanNcIjtcbmV4cG9ydCB0eXBlIHsgTWlkZGxld2FyZSBhcyBTZGtnZW5NaWRkbGV3YXJlIH0gZnJvbSBcIi4vYXBpLWNvbmZpZy5qc1wiO1xuZXhwb3J0IHR5cGUgeyBDb250ZXh0LCBDb250ZXh0UmVwbHksIENvbnRleHRSZXF1ZXN0IH0gZnJvbSBcIi4vY29udGV4dC5qc1wiO1xuZXhwb3J0IHsgZGVjb2RlLCBlbmNvZGUgfSBmcm9tIFwiLi9lbmNvZGUtZGVjb2RlLmpzXCI7XG5leHBvcnQgeyBGYXRhbCwgU2RrZ2VuRXJyb3IsIFNka2dlbkVycm9yV2l0aERhdGEgfSBmcm9tIFwiLi9lcnJvci5qc1wiO1xuZXhwb3J0IHsgU2RrZ2VuSHR0cENsaWVudCB9IGZyb20gXCIuL2h0dHAtY2xpZW50LmpzXCI7XG5leHBvcnQgeyBTZGtnZW5IdHRwU2VydmVyIH0gZnJvbSBcIi4vaHR0cC1zZXJ2ZXIuanNcIjtcbmV4cG9ydCB7IGFwaVRlc3RXcmFwcGVyIH0gZnJvbSBcIi4vdGVzdC13cmFwcGVyLmpzXCI7XG5leHBvcnQge1xuICBzdGFydFNka2dlblNlcnZlcixcbiAgY3JlYXRlU2RrZ2VuRW5kcG9pbnQsXG4gIGNyZWF0ZVNka2dlblR5cGUsXG4gIGNyZWF0ZVNka2dlblRlc3RDbGllbnQsXG4gIFV1aWQsXG4gIEludCxcbiAgVUludCxcbiAgZW5jb2RlVmFsdWUsXG4gIGRlY29kZVZhbHVlLFxuICB0eXBlIFR5cGVTcGVjLFxuICB0eXBlIEdlbmVyYXRlVHlwaW5nLFxuICB0eXBlIEdlbmVyYXRlVHlwaW5nRnJvbUZpZWxkcyxcbn0gZnJvbSBcIi4vbmV3LWludGVyZmFjZS5qc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlZmF1bHRFeHRyYUNvbnRleHQge31cbiJdfQ==
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-argument */
|
|
3
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
|
4
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
5
|
+
import { inspect } from "util";
|
|
6
|
+
import Decimal from "decimal.js";
|
|
7
|
+
import { BaseApiConfig } from "./api-config.js";
|
|
8
|
+
import { decode, encode } from "./encode-decode.js";
|
|
9
|
+
import { SdkgenHttpServer } from "./http-server.js";
|
|
10
|
+
import { apiTestWrapper } from "./test-wrapper.js";
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
12
|
+
export const Uuid = Symbol("Uuid");
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
14
|
+
export const Int = Symbol("Int");
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
16
|
+
export const UInt = Symbol("UInt");
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
18
|
+
export const Cpf = Symbol("Cpf");
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
20
|
+
export const Cnpj = Symbol("Cnpj");
|
|
21
|
+
class ApiConfig extends BaseApiConfig {
|
|
22
|
+
constructor(astJson, fn, middlewares) {
|
|
23
|
+
super();
|
|
24
|
+
this.astJson = astJson;
|
|
25
|
+
this.fn = fn;
|
|
26
|
+
this.middlewares = middlewares;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
class CustomTypeBaseClass {
|
|
30
|
+
}
|
|
31
|
+
CustomTypeBaseClass.mark = Symbol();
|
|
32
|
+
CustomTypeBaseClass.fields = {};
|
|
33
|
+
function getSdkgenType(type, registry) {
|
|
34
|
+
let normalizedType;
|
|
35
|
+
if (type === String ||
|
|
36
|
+
type === Uuid ||
|
|
37
|
+
type === Number ||
|
|
38
|
+
type === Boolean ||
|
|
39
|
+
type === BigInt ||
|
|
40
|
+
type === Int ||
|
|
41
|
+
type === UInt ||
|
|
42
|
+
type === Date ||
|
|
43
|
+
type === Buffer ||
|
|
44
|
+
type === Decimal ||
|
|
45
|
+
type === Cpf ||
|
|
46
|
+
type === Cnpj ||
|
|
47
|
+
type === URL ||
|
|
48
|
+
type === undefined) {
|
|
49
|
+
normalizedType = { type };
|
|
50
|
+
}
|
|
51
|
+
else if (type instanceof Function && type.mark === CustomTypeBaseClass.mark) {
|
|
52
|
+
normalizedType = { type };
|
|
53
|
+
}
|
|
54
|
+
else if (Array.isArray(type)) {
|
|
55
|
+
normalizedType = { type: Array, of: type[0] };
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
normalizedType = type;
|
|
59
|
+
}
|
|
60
|
+
if (normalizedType.nullable === true) {
|
|
61
|
+
delete normalizedType.nullable;
|
|
62
|
+
return `${getSdkgenType(normalizedType, registry)}?`;
|
|
63
|
+
}
|
|
64
|
+
if (normalizedType.type === String) {
|
|
65
|
+
return "string";
|
|
66
|
+
}
|
|
67
|
+
else if (normalizedType.type === Number) {
|
|
68
|
+
return "float";
|
|
69
|
+
}
|
|
70
|
+
else if (normalizedType.type === Int) {
|
|
71
|
+
return "int";
|
|
72
|
+
}
|
|
73
|
+
else if (normalizedType.type === UInt) {
|
|
74
|
+
return "uint";
|
|
75
|
+
}
|
|
76
|
+
else if (normalizedType.type === Uuid) {
|
|
77
|
+
return "uuid";
|
|
78
|
+
}
|
|
79
|
+
else if (normalizedType.type === Boolean) {
|
|
80
|
+
return "bool";
|
|
81
|
+
}
|
|
82
|
+
else if (normalizedType.type === BigInt) {
|
|
83
|
+
return "bigint";
|
|
84
|
+
}
|
|
85
|
+
else if (normalizedType.type === Date) {
|
|
86
|
+
return "datetime";
|
|
87
|
+
}
|
|
88
|
+
else if (normalizedType.type === Buffer) {
|
|
89
|
+
return "bytes";
|
|
90
|
+
}
|
|
91
|
+
else if (normalizedType.type === Decimal) {
|
|
92
|
+
return "decimal";
|
|
93
|
+
}
|
|
94
|
+
else if (normalizedType.type === Cpf) {
|
|
95
|
+
return "cpf";
|
|
96
|
+
}
|
|
97
|
+
else if (normalizedType.type === Cnpj) {
|
|
98
|
+
return "cnpj";
|
|
99
|
+
}
|
|
100
|
+
else if (normalizedType.type === URL) {
|
|
101
|
+
return "url";
|
|
102
|
+
}
|
|
103
|
+
else if (normalizedType.type === undefined) {
|
|
104
|
+
return "void";
|
|
105
|
+
}
|
|
106
|
+
else if (normalizedType.type === Array) {
|
|
107
|
+
return `${getSdkgenType(normalizedType.of, registry)}[]`;
|
|
108
|
+
}
|
|
109
|
+
else if (normalizedType.type instanceof Function && normalizedType.type.mark === CustomTypeBaseClass.mark) {
|
|
110
|
+
for (let counter = 1;; ++counter) {
|
|
111
|
+
const name = counter === 1 ? `${normalizedType.type.name}` : `${normalizedType.type.name}${counter}`;
|
|
112
|
+
const existing = registry.get(name);
|
|
113
|
+
if (existing === normalizedType.type) {
|
|
114
|
+
return name;
|
|
115
|
+
}
|
|
116
|
+
else if (existing) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
registry.set(name, normalizedType.type);
|
|
120
|
+
return name;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
throw new Error(`Unhandled sdkgen type: ${inspect(normalizedType)}`);
|
|
124
|
+
}
|
|
125
|
+
function getTypeTableFromRegistry(registry) {
|
|
126
|
+
const typeTable = {};
|
|
127
|
+
let newNamesFound = true;
|
|
128
|
+
while (newNamesFound) {
|
|
129
|
+
newNamesFound = false;
|
|
130
|
+
for (const [name, type] of registry) {
|
|
131
|
+
if (name in typeTable) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
newNamesFound = true;
|
|
135
|
+
typeTable[name] = Object.fromEntries(Object.entries(type.fields).map(([fieldName, fieldType]) => [fieldName, getSdkgenType(fieldType, registry)]));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return typeTable;
|
|
139
|
+
}
|
|
140
|
+
function createApiConfig(config) {
|
|
141
|
+
const astJson = {
|
|
142
|
+
functionTable: {},
|
|
143
|
+
typeTable: {},
|
|
144
|
+
errors: [],
|
|
145
|
+
annotations: {},
|
|
146
|
+
};
|
|
147
|
+
const handlers = {};
|
|
148
|
+
const registry = new Map();
|
|
149
|
+
for (const [name, endpoint] of Object.entries(config.endpoints)) {
|
|
150
|
+
astJson.functionTable[name] = {
|
|
151
|
+
args: Object.fromEntries(Object.entries(endpoint.options.args ?? {}).map(([arg, type]) => [arg, getSdkgenType(type, registry)])),
|
|
152
|
+
ret: getSdkgenType(endpoint.options.return, registry),
|
|
153
|
+
};
|
|
154
|
+
handlers[name] = endpoint.handler;
|
|
155
|
+
}
|
|
156
|
+
astJson.typeTable = getTypeTableFromRegistry(registry);
|
|
157
|
+
return new ApiConfig(astJson, handlers, config.middlewares ?? []);
|
|
158
|
+
}
|
|
159
|
+
export async function startSdkgenServer(config) {
|
|
160
|
+
const api = createApiConfig(config);
|
|
161
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
|
|
162
|
+
const server = new SdkgenHttpServer(api, config.extraContext);
|
|
163
|
+
await server.listen(config.port ?? 80);
|
|
164
|
+
}
|
|
165
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
166
|
+
export function createSdkgenTestClient(config) {
|
|
167
|
+
const api = createApiConfig(config);
|
|
168
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
169
|
+
return apiTestWrapper(api, config.extraContext).fn;
|
|
170
|
+
}
|
|
171
|
+
export function createSdkgenType(fields) {
|
|
172
|
+
var _a;
|
|
173
|
+
const customType = (_a = class extends CustomTypeBaseClass {
|
|
174
|
+
},
|
|
175
|
+
_a.fields = fields,
|
|
176
|
+
_a);
|
|
177
|
+
return customType;
|
|
178
|
+
}
|
|
179
|
+
class SdkgenEndpoint {
|
|
180
|
+
constructor(options, handler) {
|
|
181
|
+
this.options = options;
|
|
182
|
+
this.handler = handler;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
export function createSdkgenEndpoint(options, handler) {
|
|
186
|
+
return new SdkgenEndpoint(options, handler);
|
|
187
|
+
}
|
|
188
|
+
export function encodeValue(type, value) {
|
|
189
|
+
const registry = new Map();
|
|
190
|
+
const legacyType = getSdkgenType(type, registry);
|
|
191
|
+
const typeTable = getTypeTableFromRegistry(registry);
|
|
192
|
+
return encode(typeTable, "", legacyType, value);
|
|
193
|
+
}
|
|
194
|
+
export function decodeValue(type, value) {
|
|
195
|
+
const registry = new Map();
|
|
196
|
+
const legacyType = getSdkgenType(type, registry);
|
|
197
|
+
const typeTable = getTypeTableFromRegistry(registry);
|
|
198
|
+
return decode(typeTable, "", legacyType, value);
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LWludGVyZmFjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9uZXctaW50ZXJmYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDREQUE0RDtBQUM1RCwwREFBMEQ7QUFDMUQsK0RBQStEO0FBQy9ELHVEQUF1RDtBQUN2RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRy9CLE9BQU8sT0FBTyxNQUFNLFlBQVksQ0FBQztBQUdqQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVwRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHbkQsZ0VBQWdFO0FBQ2hFLE1BQU0sQ0FBQyxNQUFNLElBQUksR0FBa0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQ2xELGdFQUFnRTtBQUNoRSxNQUFNLENBQUMsTUFBTSxHQUFHLEdBQWtCLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNoRCxnRUFBZ0U7QUFDaEUsTUFBTSxDQUFDLE1BQU0sSUFBSSxHQUFrQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7QUFDbEQsZ0VBQWdFO0FBQ2hFLE1BQU0sQ0FBQyxNQUFNLEdBQUcsR0FBa0IsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2hELGdFQUFnRTtBQUNoRSxNQUFNLENBQUMsTUFBTSxJQUFJLEdBQWtCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUVsRCxNQUFNLFNBQW1DLFNBQVEsYUFBNEI7SUFDM0UsWUFDUyxPQUE4QixFQUM5QixFQUdOLEVBQ2UsV0FBNkM7UUFFN0QsS0FBSyxFQUFFLENBQUM7UUFQRCxZQUFPLEdBQVAsT0FBTyxDQUF1QjtRQUM5QixPQUFF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U0FBTSxHQUFHLE1BQU87V0FDeEIsQ0FBQztJQUVGLE9BQU8sVUFDNEIsQ0FBQztBQUN0QyxDQUFDO0FBK0ZELE1BQU0sY0FBYztJQUNsQixZQUNrQixPQUEyQixFQUMzQixPQUFnRjtRQURoRixZQUFPLEdBQVAsT0FBTyxDQUFvQjtRQUMzQixZQUFPLEdBQVAsT0FBTyxDQUF5RTtJQUMvRixDQUFDO0NBQ0w7QUFVRCxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLE9BQWdCLEVBQ2hCLE9BQXdIO0lBRXhILE9BQU8sSUFBSSxjQUFjLENBQXVELE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztBQUNwRyxDQUFDO0FBWUQsTUFBTSxVQUFVLFdBQVcsQ0FBd0IsSUFBVSxFQUFFLEtBQTJCO0lBQ3hGLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFzQyxDQUFDO0lBRS9ELE1BQU0sVUFBVSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDakQsTUFBTSxTQUFTLEdBQUcsd0JBQXdCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFckQsT0FBTyxNQUFNLENBQUMsU0FBUyxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDbEQsQ0FBQztBQUVELE1BQU0sVUFBVSxXQUFXLENBQXdCLElBQVUsRUFBRSxLQUFnQjtJQUM3RSxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBc0MsQ0FBQztJQUUvRCxNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2pELE1BQU0sU0FBUyxHQUFHLHdCQUF3QixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXJELE9BQU8sTUFBTSxDQUFDLFNBQVMsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBeUIsQ0FBQztBQUMxRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hc3NpZ25tZW50ICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLWFyZ3VtZW50ICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IGluc3BlY3QgfSBmcm9tIFwidXRpbFwiO1xuXG5pbXBvcnQgdHlwZSB7IEFzdEpzb24gfSBmcm9tIFwiQHNka2dlbi9wYXJzZXJcIjtcbmltcG9ydCBEZWNpbWFsIGZyb20gXCJkZWNpbWFsLmpzXCI7XG5cbmltcG9ydCB0eXBlIHsgTWlkZGxld2FyZSB9IGZyb20gXCIuL2FwaS1jb25maWcuanNcIjtcbmltcG9ydCB7IEJhc2VBcGlDb25maWcgfSBmcm9tIFwiLi9hcGktY29uZmlnLmpzXCI7XG5pbXBvcnQgdHlwZSB7IENvbnRleHQgfSBmcm9tIFwiLi9jb250ZXh0LmpzXCI7XG5pbXBvcnQgeyBkZWNvZGUsIGVuY29kZSB9IGZyb20gXCIuL2VuY29kZS1kZWNvZGUuanNcIjtcbmltcG9ydCB7IFNka2dlbkh0dHBTZXJ2ZXIgfSBmcm9tIFwiLi9odHRwLXNlcnZlci5qc1wiO1xuaW1wb3J0IHR5cGUgeyBEZWZhdWx0RXh0cmFDb250ZXh0IH0gZnJvbSBcIi4vaW5kZXguanNcIjtcbmltcG9ydCB7IGFwaVRlc3RXcmFwcGVyIH0gZnJvbSBcIi4vdGVzdC13cmFwcGVyLmpzXCI7XG5pbXBvcnQgdHlwZSB7IERlZXBSZWFkb25seSB9IGZyb20gXCIuL3V0aWxzLmpzXCI7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjb25zdCBVdWlkOiB1bmlxdWUgc3ltYm9sID0gU3ltYm9sKFwiVXVpZFwiKTtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbmFtaW5nLWNvbnZlbnRpb25cbmV4cG9ydCBjb25zdCBJbnQ6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2woXCJJbnRcIik7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgVUludDogdW5pcXVlIHN5bWJvbCA9IFN5bWJvbChcIlVJbnRcIik7XG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG5leHBvcnQgY29uc3QgQ3BmOiB1bmlxdWUgc3ltYm9sID0gU3ltYm9sKFwiQ3BmXCIpO1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNvbnN0IENucGo6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2woXCJDbnBqXCIpO1xuXG5jbGFzcyBBcGlDb25maWc8RXh0cmFDb250ZXh0VCA9IHVua25vd24+IGV4dGVuZHMgQmFzZUFwaUNvbmZpZzxFeHRyYUNvbnRleHRUPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyBhc3RKc29uOiBEZWVwUmVhZG9ubHk8QXN0SnNvbj4sXG4gICAgcHVibGljIGZuOiB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICAgICAgW25hbWU6IHN0cmluZ106ICgoY3R4OiBDb250ZXh0ICYgRXh0cmFDb250ZXh0VCwgYXJnczogYW55KSA9PiBQcm9taXNlPGFueT4pIHwgdW5kZWZpbmVkO1xuICAgIH0sXG4gICAgcHVibGljIHJlYWRvbmx5IG1pZGRsZXdhcmVzOiBBcnJheTxNaWRkbGV3YXJlPEV4dHJhQ29udGV4dFQ+PixcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNka2dlbkNvbmZpZzxFeHRyYUNvbnRleHRUPiB7XG4gIHBvcnQ/OiBudW1iZXI7XG4gIGVuZHBvaW50czogUmVjb3JkPHN0cmluZywgU2RrZ2VuRW5kcG9pbnQ8YW55LCBhbnk+PjtcbiAgbWlkZGxld2FyZXM/OiBBcnJheTxNaWRkbGV3YXJlPEV4dHJhQ29udGV4dFQ+PjtcbiAgZXh0cmFDb250ZXh0OiBFeHRyYUNvbnRleHRUO1xufVxuXG5jbGFzcyBDdXN0b21UeXBlQmFzZUNsYXNzIHtcbiAgc3RhdGljIHJlYWRvbmx5IG1hcms6IHVuaXF1ZSBzeW1ib2wgPSBTeW1ib2woKTtcbiAgc3RhdGljIHJlYWRvbmx5IGZpZWxkczogUmVjb3JkPHN0cmluZywgVHlwZVNwZWM+ID0ge307XG59XG5cbnR5cGUgQ3VzdG9tVHlwZVJlZ2lzdHJ5ID0gTWFwPHN0cmluZywgdHlwZW9mIEN1c3RvbVR5cGVCYXNlQ2xhc3M+O1xuXG5mdW5jdGlvbiBnZXRTZGtnZW5UeXBlKHR5cGU6IFR5cGVTcGVjLCByZWdpc3RyeTogQ3VzdG9tVHlwZVJlZ2lzdHJ5KTogc3RyaW5nIHtcbiAgbGV0IG5vcm1hbGl6ZWRUeXBlOiBhbnk7XG5cbiAgaWYgKFxuICAgIHR5cGUgPT09IFN0cmluZyB8fFxuICAgIHR5cGUgPT09IFV1aWQgfHxcbiAgICB0eXBlID09PSBOdW1iZXIgfHxcbiAgICB0eXBlID09PSBCb29sZWFuIHx8XG4gICAgdHlwZSA9PT0gQmlnSW50IHx8XG4gICAgdHlwZSA9PT0gSW50IHx8XG4gICAgdHlwZSA9PT0gVUludCB8fFxuICAgIHR5cGUgPT09IERhdGUgfHxcbiAgICB0eXBlID09PSBCdWZmZXIgfHxcbiAgICB0eXBlID09PSBEZWNpbWFsIHx8XG4gICAgdHlwZSA9PT0gQ3BmIHx8XG4gICAgdHlwZSA9PT0gQ25waiB8fFxuICAgIHR5cGUgPT09IFVSTCB8fFxuICAgIHR5cGUgPT09IHVuZGVmaW5lZFxuICApIHtcbiAgICBub3JtYWxpemVkVHlwZSA9IHsgdHlwZSB9O1xuICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBGdW5jdGlvbiAmJiAodHlwZSBhcyB0eXBlb2YgQ3VzdG9tVHlwZUJhc2VDbGFzcykubWFyayA9PT0gQ3VzdG9tVHlwZUJhc2VDbGFzcy5tYXJrKSB7XG4gICAgbm9ybWFsaXplZFR5cGUgPSB7IHR5cGUgfTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHR5cGUpKSB7XG4gICAgbm9ybWFsaXplZFR5cGUgPSB7IHR5cGU6IEFycmF5LCBvZjogdHlwZVswXSB9O1xuICB9IGVsc2Uge1xuICAgIG5vcm1hbGl6ZWRUeXBlID0gdHlwZTtcbiAgfVxuXG4gIGlmIChub3JtYWxpemVkVHlwZS5udWxsYWJsZSA9PT0gdHJ1ZSkge1xuICAgIGRlbGV0ZSBub3JtYWxpemVkVHlwZS5udWxsYWJsZTtcbiAgICByZXR1cm4gYCR7Z2V0U2RrZ2VuVHlwZShub3JtYWxpemVkVHlwZSwgcmVnaXN0cnkpfT9gO1xuICB9XG5cbiAgaWYgKG5vcm1hbGl6ZWRUeXBlLnR5cGUgPT09IFN0cmluZykge1xuICAgIHJldHVybiBcInN0cmluZ1wiO1xuICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRUeXBlLnR5cGUgPT09IE51bWJlcikge1xuICAgIHJldHVybiBcImZsb2F0XCI7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSA9PT0gSW50KSB7XG4gICAgcmV0dXJuIFwiaW50XCI7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSA9PT0gVUludCkge1xuICAgIHJldHVybiBcInVpbnRcIjtcbiAgfSBlbHNlIGlmIChub3JtYWxpemVkVHlwZS50eXBlID09PSBVdWlkKSB7XG4gICAgcmV0dXJuIFwidXVpZFwiO1xuICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRUeXBlLnR5cGUgPT09IEJvb2xlYW4pIHtcbiAgICByZXR1cm4gXCJib29sXCI7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSA9PT0gQmlnSW50KSB7XG4gICAgcmV0dXJuIFwiYmlnaW50XCI7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSA9PT0gRGF0ZSkge1xuICAgIHJldHVybiBcImRhdGV0aW1lXCI7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSA9PT0gQnVmZmVyKSB7XG4gICAgcmV0dXJuIFwiYnl0ZXNcIjtcbiAgfSBlbHNlIGlmIChub3JtYWxpemVkVHlwZS50eXBlID09PSBEZWNpbWFsKSB7XG4gICAgcmV0dXJuIFwiZGVjaW1hbFwiO1xuICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRUeXBlLnR5cGUgPT09IENwZikge1xuICAgIHJldHVybiBcImNwZlwiO1xuICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRUeXBlLnR5cGUgPT09IENucGopIHtcbiAgICByZXR1cm4gXCJjbnBqXCI7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSA9PT0gVVJMKSB7XG4gICAgcmV0dXJuIFwidXJsXCI7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIFwidm9pZFwiO1xuICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWRUeXBlLnR5cGUgPT09IEFycmF5KSB7XG4gICAgcmV0dXJuIGAke2dldFNka2dlblR5cGUobm9ybWFsaXplZFR5cGUub2YsIHJlZ2lzdHJ5KX1bXWA7XG4gIH0gZWxzZSBpZiAobm9ybWFsaXplZFR5cGUudHlwZSBpbnN0YW5jZW9mIEZ1bmN0aW9uICYmIChub3JtYWxpemVkVHlwZS50eXBlIGFzIHR5cGVvZiBDdXN0b21UeXBlQmFzZUNsYXNzKS5tYXJrID09PSBDdXN0b21UeXBlQmFzZUNsYXNzLm1hcmspIHtcbiAgICBmb3IgKGxldCBjb3VudGVyID0gMTsgOyArK2NvdW50ZXIpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSBjb3VudGVyID09PSAxID8gYCR7bm9ybWFsaXplZFR5cGUudHlwZS5uYW1lfWAgOiBgJHtub3JtYWxpemVkVHlwZS50eXBlLm5hbWV9JHtjb3VudGVyfWA7XG4gICAgICBjb25zdCBleGlzdGluZyA9IHJlZ2lzdHJ5LmdldChuYW1lKTtcblxuICAgICAgaWYgKGV4aXN0aW5nID09PSBub3JtYWxpemVkVHlwZS50eXBlKSB7XG4gICAgICAgIHJldHVybiBuYW1lO1xuICAgICAgfSBlbHNlIGlmIChleGlzdGluZykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgcmVnaXN0cnkuc2V0KG5hbWUsIG5vcm1hbGl6ZWRUeXBlLnR5cGUpO1xuICAgICAgcmV0dXJuIG5hbWU7XG4gICAgfVxuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmhhbmRsZWQgc2RrZ2VuIHR5cGU6ICR7aW5zcGVjdChub3JtYWxpemVkVHlwZSl9YCk7XG59XG5cbmZ1bmN0aW9uIGdldFR5cGVUYWJsZUZyb21SZWdpc3RyeShyZWdpc3RyeTogQ3VzdG9tVHlwZVJlZ2lzdHJ5KSB7XG4gIGNvbnN0IHR5cGVUYWJsZTogQXN0SnNvbltcInR5cGVUYWJsZVwiXSA9IHt9O1xuXG4gIGxldCBuZXdOYW1lc0ZvdW5kID0gdHJ1ZTtcblxuICB3aGlsZSAobmV3TmFtZXNGb3VuZCkge1xuICAgIG5ld05hbWVzRm91bmQgPSBmYWxzZTtcblxuICAgIGZvciAoY29uc3QgW25hbWUsIHR5cGVdIG9mIHJlZ2lzdHJ5KSB7XG4gICAgICBpZiAobmFtZSBpbiB0eXBlVGFibGUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIG5ld05hbWVzRm91bmQgPSB0cnVlO1xuXG4gICAgICB0eXBlVGFibGVbbmFtZV0gPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKHR5cGUuZmllbGRzKS5tYXAoKFtmaWVsZE5hbWUsIGZpZWxkVHlwZV0pID0+IFtmaWVsZE5hbWUsIGdldFNka2dlblR5cGUoZmllbGRUeXBlLCByZWdpc3RyeSldKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHR5cGVUYWJsZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQXBpQ29uZmlnPEV4dHJhQ29udGV4dFQ+KGNvbmZpZzogU2RrZ2VuQ29uZmlnPEV4dHJhQ29udGV4dFQ+KSB7XG4gIGNvbnN0IGFzdEpzb246IEFzdEpzb24gPSB7XG4gICAgZnVuY3Rpb25UYWJsZToge30sXG4gICAgdHlwZVRhYmxlOiB7fSxcbiAgICBlcnJvcnM6IFtdLFxuICAgIGFubm90YXRpb25zOiB7fSxcbiAgfTtcblxuICBjb25zdCBoYW5kbGVyczoge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgW25hbWU6IHN0cmluZ106IChjdHg6IENvbnRleHQgJiBFeHRyYUNvbnRleHRULCBhcmdzOiBhbnkpID0+IFByb21pc2U8YW55PjtcbiAgfSA9IHt9O1xuXG4gIGNvbnN0IHJlZ2lzdHJ5ID0gbmV3IE1hcDxzdHJpbmcsIHR5cGVvZiBDdXN0b21UeXBlQmFzZUNsYXNzPigpO1xuXG4gIGZvciAoY29uc3QgW25hbWUsIGVuZHBvaW50XSBvZiBPYmplY3QuZW50cmllcyhjb25maWcuZW5kcG9pbnRzKSkge1xuICAgIGFzdEpzb24uZnVuY3Rpb25UYWJsZVtuYW1lXSA9IHtcbiAgICAgIGFyZ3M6IE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyhlbmRwb2ludC5vcHRpb25zLmFyZ3MgPz8ge30pLm1hcCgoW2FyZywgdHlwZV0pID0+IFthcmcsIGdldFNka2dlblR5cGUodHlwZSwgcmVnaXN0cnkpXSkpLFxuICAgICAgcmV0OiBnZXRTZGtnZW5UeXBlKGVuZHBvaW50Lm9wdGlvbnMucmV0dXJuLCByZWdpc3RyeSksXG4gICAgfTtcbiAgICBoYW5kbGVyc1tuYW1lXSA9IGVuZHBvaW50LmhhbmRsZXI7XG4gIH1cblxuICBhc3RKc29uLnR5cGVUYWJsZSA9IGdldFR5cGVUYWJsZUZyb21SZWdpc3RyeShyZWdpc3RyeSk7XG5cbiAgcmV0dXJuIG5ldyBBcGlDb25maWc8RXh0cmFDb250ZXh0VD4oYXN0SnNvbiwgaGFuZGxlcnMsIGNvbmZpZy5taWRkbGV3YXJlcyA/PyBbXSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzdGFydFNka2dlblNlcnZlcjxFeHRyYUNvbnRleHRUPihjb25maWc6IFNka2dlbkNvbmZpZzxFeHRyYUNvbnRleHRUPikge1xuICBjb25zdCBhcGkgPSBjcmVhdGVBcGlDb25maWcoY29uZmlnKTtcblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hcmd1bWVudCwgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuICBjb25zdCBzZXJ2ZXIgPSBuZXcgU2RrZ2VuSHR0cFNlcnZlcjxFeHRyYUNvbnRleHRUPihhcGksIGNvbmZpZy5leHRyYUNvbnRleHQgYXMgYW55KTtcblxuICBhd2FpdCBzZXJ2ZXIubGlzdGVuKGNvbmZpZy5wb3J0ID8/IDgwKTtcbn1cblxudHlwZSBDYWxsYWJsZUVuZHBvaW50PEV4dHJhQ29udGV4dFQsIEVuZHBvaW50IGV4dGVuZHMgU2RrZ2VuRW5kcG9pbnQ8dW5rbm93biwgdW5rbm93bj4+ID0gRW5kcG9pbnQgZXh0ZW5kcyBTZGtnZW5FbmRwb2ludDxpbmZlciBBcmdzLCBpbmZlciBSZXR1cm4+XG4gID8gKGN0eDogUGFydGlhbDxDb250ZXh0ICYgRXh0cmFDb250ZXh0VD4sIGFyZ3M6IEFyZ3MpID0+IFByb21pc2U8UmV0dXJuPlxuICA6IG5ldmVyO1xuXG50eXBlIENhbGxhYmxlRW5kcG9pbnRzPEV4dHJhQ29udGV4dFQsIEVuZHBvaW50cyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIFNka2dlbkVuZHBvaW50PHVua25vd24sIHVua25vd24+Pj4gPSB7XG4gIFtFbmRwb2ludE5hbWUgaW4ga2V5b2YgRW5kcG9pbnRzXTogQ2FsbGFibGVFbmRwb2ludDxFeHRyYUNvbnRleHRULCBFbmRwb2ludHNbRW5kcG9pbnROYW1lXT47XG59O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueVxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNka2dlblRlc3RDbGllbnQ8Q29uZmlnVCBleHRlbmRzIFNka2dlbkNvbmZpZzxhbnk+Pihjb25maWc6IENvbmZpZ1QpIHtcbiAgY29uc3QgYXBpID0gY3JlYXRlQXBpQ29uZmlnKGNvbmZpZyk7XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXJndW1lbnRcbiAgcmV0dXJuIGFwaVRlc3RXcmFwcGVyKGFwaSwgY29uZmlnLmV4dHJhQ29udGV4dCkuZm4gYXMgdW5rbm93biBhcyBDYWxsYWJsZUVuZHBvaW50czxDb25maWdUW1wiZXh0cmFDb250ZXh0XCJdLCBDb25maWdUW1wiZW5kcG9pbnRzXCJdPjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNka2dlblR5cGU8RmllbGRzIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgVHlwZVNwZWM+PihmaWVsZHM6IEZpZWxkcykge1xuICBjb25zdCBjdXN0b21UeXBlID0gY2xhc3MgZXh0ZW5kcyBDdXN0b21UeXBlQmFzZUNsYXNzIHtcbiAgICBzdGF0aWMgZmllbGRzID0gZmllbGRzO1xuICB9O1xuXG4gIHJldHVybiBjdXN0b21UeXBlIGFzIHVua25vd24gYXMgeyBtYXJrOiB0eXBlb2YgQ3VzdG9tVHlwZUJhc2VDbGFzc1tcIm1hcmtcIl07IGZpZWxkczogRmllbGRzIH0gJiAobmV3ICgpID0+IEN1c3RvbVR5cGVCYXNlQ2xhc3MgJlxuICAgIEdlbmVyYXRlVHlwaW5nRnJvbUZpZWxkczxGaWVsZHM+KTtcbn1cblxuZXhwb3J0IHR5cGUgVHlwZVNwZWMgPVxuICB8IHR5cGVvZiBTdHJpbmdcbiAgfCB0eXBlb2YgQm9vbGVhblxuICB8IHR5cGVvZiBOdW1iZXJcbiAgfCB0eXBlb2YgSW50XG4gIHwgdHlwZW9mIFVJbnRcbiAgfCB0eXBlb2YgQmlnSW50XG4gIHwgdHlwZW9mIEN1c3RvbVR5cGVCYXNlQ2xhc3NcbiAgfCB0eXBlb2YgVXVpZFxuICB8IHR5cGVvZiBEYXRlXG4gIHwgdHlwZW9mIEJ1ZmZlclxuICB8IHR5cGVvZiBEZWNpbWFsXG4gIHwgdHlwZW9mIENwZlxuICB8IHR5cGVvZiBDbnBqXG4gIHwgdHlwZW9mIFVSTFxuICB8IHVuZGVmaW5lZFxuICB8IFtUeXBlU3BlY11cbiAgfCAoKFxuICAgICAgfCB7IHR5cGU6IHR5cGVvZiBTdHJpbmc7IG1pbkxlbmd0aD86IG51bWJlcjsgbWF4TGVuZ3RoPzogbnVtYmVyOyBwYXR0ZXJuPzogUmVnRXhwIH1cbiAgICAgIHwgeyB0eXBlOiB0eXBlb2YgQm9vbGVhbiB9XG4gICAgICB8IHsgdHlwZTogdHlwZW9mIE51bWJlcjsgbWluPzogbnVtYmVyOyBtYXg/OiBudW1iZXIgfVxuICAgICAgfCB7IHR5cGU6IHR5cGVvZiBJbnQ7IG1pbj86IG51bWJlcjsgbWF4PzogbnVtYmVyIH1cbiAgICAgIHwgeyB0eXBlOiB0eXBlb2YgVUludDsgbWluPzogbnVtYmVyOyBtYXg/OiBudW1iZXIgfVxuICAgICAgfCB7IHR5cGU6IHR5cGVvZiBCaWdJbnQ7IG1pbj86IGJpZ2ludDsgbWF4PzogYmlnaW50IH1cbiAgICAgIHwgeyB0eXBlOiB0eXBlb2YgQ3VzdG9tVHlwZUJhc2VDbGFzcyB9XG4gICAgICB8IHsgdHlwZTogdHlwZW9mIFV1aWQgfVxuICAgICAgfCB7IHR5cGU6IHR5cGVvZiBEYXRlIH1cbiAgICAgIHwgeyB0eXBlOiB0eXBlb2YgQnVmZmVyIH1cbiAgICAgIHwgeyB0eXBlOiB0eXBlb2YgRGVjaW1hbCB9XG4gICAgICB8IHsgdHlwZTogdHlwZW9mIENwZiB9XG4gICAgICB8IHsgdHlwZTogdHlwZW9mIENucGogfVxuICAgICAgfCB7IHR5cGU6IHR5cGVvZiBVUkwgfVxuICAgICAgfCB7IHR5cGU6IHVuZGVmaW5lZCB9XG4gICAgICB8IHsgdHlwZTogW1R5cGVTcGVjXTsgbWluTGVuZ3RoPzogbnVtYmVyOyBtYXhMZW5ndGg/OiBudW1iZXIgfVxuICAgICAgfCB7IHR5cGU6IHR5cGVvZiBBcnJheTsgb2Y6IFR5cGVTcGVjOyBtaW5MZW5ndGg/OiBudW1iZXI7IG1heExlbmd0aD86IG51bWJlciB9XG4gICAgKSAmIHsgbnVsbGFibGU/OiB0cnVlIH0pO1xuXG5pbnRlcmZhY2UgQXBpRW5kcG9pbnRPcHRpb25zIHtcbiAgcmVzdD86IHtcbiAgICBtZXRob2Q6IFwiR0VUXCIgfCBcIlBPU1RcIiB8IFwiUFVUXCIgfCBcIlBBVENIXCIgfCBcIkRFTEVURVwiO1xuICAgIHBhdGg6IHN0cmluZztcbiAgICBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICBib2R5Pzogc3RyaW5nO1xuICB9O1xuICBhcmdzPzogUmVjb3JkPHN0cmluZywgVHlwZVNwZWM+O1xuICByZXR1cm4/OiBUeXBlU3BlYztcbiAgbWlkZGxld2FyZXM/OiBBcnJheTxNaWRkbGV3YXJlPEluZmVyQ29udGV4dDxEZWZhdWx0RXh0cmFDb250ZXh0Pj4+O1xufVxuXG5leHBvcnQgdHlwZSBHZW5lcmF0ZVR5cGluZzxUeXBlPiA9IFR5cGUgZXh0ZW5kcyB7IG51bGxhYmxlOiB0cnVlIH1cbiAgPyBudWxsIHwgR2VuZXJhdGVUeXBpbmc8T21pdDxUeXBlLCBcIm51bGxhYmxlXCI+PlxuICA6IFR5cGUgZXh0ZW5kcyB0eXBlb2YgU3RyaW5nIHwgeyB0eXBlOiB0eXBlb2YgU3RyaW5nIH1cbiAgPyBzdHJpbmdcbiAgOiBUeXBlIGV4dGVuZHMgdHlwZW9mIEJvb2xlYW4gfCB7IHR5cGU6IHR5cGVvZiBCb29sZWFuIH1cbiAgPyBib29sZWFuXG4gIDogVHlwZSBleHRlbmRzIHR5cGVvZiBOdW1iZXIgfCB7IHR5cGU6IHR5cGVvZiBOdW1iZXIgfVxuICA/IG51bWJlclxuICA6IFR5cGUgZXh0ZW5kcyB0eXBlb2YgSW50IHwgeyB0eXBlOiB0eXBlb2YgSW50IH1cbiAgPyBudW1iZXJcbiAgOiBUeXBlIGV4dGVuZHMgdHlwZW9mIFVJbnQgfCB7IHR5cGU6IHR5cGVvZiBVSW50IH1cbiAgPyBudW1iZXJcbiAgOiBUeXBlIGV4dGVuZHMgdHlwZW9mIEJpZ0ludCB8IHsgdHlwZTogdHlwZW9mIEJpZ0ludCB9XG4gID8gYmlnaW50XG4gIDogVHlwZSBleHRlbmRzIHR5cGVvZiBVdWlkIHwgeyB0eXBlOiB0eXBlb2YgVXVpZCB9XG4gID8gc3RyaW5nXG4gIDogVHlwZSBleHRlbmRzIHR5cGVvZiBEYXRlIHwgeyB0eXBlOiB0eXBlb2YgRGF0ZSB9XG4gID8gRGF0ZVxuICA6IFR5cGUgZXh0ZW5kcyB0eXBlb2YgQnVmZmVyIHwgeyB0eXBlOiB0eXBlb2YgQnVmZmVyIH1cbiAgPyBCdWZmZXJcbiAgOiBUeXBlIGV4dGVuZHMgdHlwZW9mIENwZiB8IHsgdHlwZTogdHlwZW9mIENwZiB9XG4gID8gc3RyaW5nXG4gIDogVHlwZSBleHRlbmRzIHR5cGVvZiBDbnBqIHwgeyB0eXBlOiB0eXBlb2YgQ25waiB9XG4gID8gc3RyaW5nXG4gIDogVHlwZSBleHRlbmRzIHR5cGVvZiBVUkwgfCB7IHR5cGU6IHR5cGVvZiBVUkwgfVxuICA/IHN0cmluZ1xuICA6IFR5cGUgZXh0ZW5kcyBbaW5mZXIgSW5uZXJdXG4gID8gQXJyYXk8R2VuZXJhdGVUeXBpbmc8SW5uZXI+PlxuICA6IFR5cGUgZXh0ZW5kcyB7IHR5cGU6IHR5cGVvZiBBcnJheTsgb2Y6IGluZmVyIElubmVyIH1cbiAgPyBBcnJheTxHZW5lcmF0ZVR5cGluZzxJbm5lcj4+XG4gIDogVHlwZSBleHRlbmRzIHsgdHlwZTogW2luZmVyIElubmVyXSB9XG4gID8gQXJyYXk8R2VuZXJhdGVUeXBpbmc8SW5uZXI+PlxuICA6IFR5cGUgZXh0ZW5kcyB0eXBlb2YgQ3VzdG9tVHlwZUJhc2VDbGFzc1xuICA/IEluc3RhbmNlVHlwZTxUeXBlPlxuICA6IFR5cGUgZXh0ZW5kcyB7IHR5cGU6IHR5cGVvZiBDdXN0b21UeXBlQmFzZUNsYXNzIH1cbiAgPyBJbnN0YW5jZVR5cGU8VHlwZVtcInR5cGVcIl0+XG4gIDogdW5kZWZpbmVkIGV4dGVuZHMgVHlwZVxuICA/IHZvaWRcbiAgOiB7ICRlcnJvcjogXCLinYwgdW5yZWNvZ25pemVkIHR5cGVcIiB9O1xuXG5leHBvcnQgdHlwZSBHZW5lcmF0ZVR5cGluZ0Zyb21GaWVsZHM8RmllbGRzIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgVHlwZVNwZWM+PiA9IHtcbiAgW0ZpZWxkIGluIGtleW9mIEZpZWxkc106IEdlbmVyYXRlVHlwaW5nPEZpZWxkc1tGaWVsZF0+O1xufTtcblxuY2xhc3MgU2RrZ2VuRW5kcG9pbnQ8QXJncywgUmV0dXJuPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBvcHRpb25zOiBBcGlFbmRwb2ludE9wdGlvbnMsXG4gICAgcHVibGljIHJlYWRvbmx5IGhhbmRsZXI6IChjdHg6IEluZmVyQ29udGV4dDxEZWZhdWx0RXh0cmFDb250ZXh0PiwgYXJnczogQXJncykgPT4gUHJvbWlzZTxSZXR1cm4+LFxuICApIHt9XG59XG5cbnR5cGUgSW5mZXJDb250ZXh0PE9iaj4gPSBPYmogZXh0ZW5kcyB7IGN0eDogdW5rbm93biB9ID8gT2JqW1wiY3R4XCJdICYgQ29udGV4dCA6IENvbnRleHQ7XG5cbnR5cGUgR2V0RW5kcG9pbnRBcmdzPE9wdGlvbnMgZXh0ZW5kcyBBcGlFbmRwb2ludE9wdGlvbnM+ID0gT3B0aW9ucyBleHRlbmRzIHsgYXJnczogUmVjb3JkPHN0cmluZywgVHlwZVNwZWM+IH1cbiAgPyBHZW5lcmF0ZVR5cGluZ0Zyb21GaWVsZHM8T3B0aW9uc1tcImFyZ3NcIl0+XG4gIDoge307XG5cbnR5cGUgR2V0RW5kcG9pbnRSZXR1cm48T3B0aW9ucyBleHRlbmRzIEFwaUVuZHBvaW50T3B0aW9ucz4gPSBHZW5lcmF0ZVR5cGluZzxPcHRpb25zW1wicmV0dXJuXCJdPjtcblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVNka2dlbkVuZHBvaW50PE9wdGlvbnMgZXh0ZW5kcyBBcGlFbmRwb2ludE9wdGlvbnM+KFxuICBvcHRpb25zOiBPcHRpb25zLFxuICBoYW5kbGVyOiAoY3R4OiBJbmZlckNvbnRleHQ8RGVmYXVsdEV4dHJhQ29udGV4dD4sIGFyZ3M6IEdldEVuZHBvaW50QXJnczxPcHRpb25zPikgPT4gUHJvbWlzZTxHZXRFbmRwb2ludFJldHVybjxPcHRpb25zPj4sXG4pIHtcbiAgcmV0dXJuIG5ldyBTZGtnZW5FbmRwb2ludDxHZXRFbmRwb2ludEFyZ3M8T3B0aW9ucz4sIEdldEVuZHBvaW50UmV0dXJuPE9wdGlvbnM+PihvcHRpb25zLCBoYW5kbGVyKTtcbn1cblxuZXhwb3J0IHR5cGUgSnNvbkFycmF5ID0gSnNvblZhbHVlW107XG5cbmV4cG9ydCB0eXBlIEpzb25PYmplY3QgPSB7XG4gIFtLIGluIHN0cmluZ10/OiBKc29uVmFsdWU7XG59O1xuXG5leHBvcnQgdHlwZSBKc29uUHJpbWl0aXZlID0gYm9vbGVhbiB8IG51bGwgfCBudW1iZXIgfCBzdHJpbmc7XG5cbmV4cG9ydCB0eXBlIEpzb25WYWx1ZSA9IEpzb25BcnJheSB8IEpzb25PYmplY3QgfCBKc29uUHJpbWl0aXZlO1xuXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlVmFsdWU8VHlwZSBleHRlbmRzIFR5cGVTcGVjPih0eXBlOiBUeXBlLCB2YWx1ZTogR2VuZXJhdGVUeXBpbmc8VHlwZT4pOiBKc29uVmFsdWUge1xuICBjb25zdCByZWdpc3RyeSA9IG5ldyBNYXA8c3RyaW5nLCB0eXBlb2YgQ3VzdG9tVHlwZUJhc2VDbGFzcz4oKTtcblxuICBjb25zdCBsZWdhY3lUeXBlID0gZ2V0U2RrZ2VuVHlwZSh0eXBlLCByZWdpc3RyeSk7XG4gIGNvbnN0IHR5cGVUYWJsZSA9IGdldFR5cGVUYWJsZUZyb21SZWdpc3RyeShyZWdpc3RyeSk7XG5cbiAgcmV0dXJuIGVuY29kZSh0eXBlVGFibGUsIFwiXCIsIGxlZ2FjeVR5cGUsIHZhbHVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZVZhbHVlPFR5cGUgZXh0ZW5kcyBUeXBlU3BlYz4odHlwZTogVHlwZSwgdmFsdWU6IEpzb25WYWx1ZSk6IEdlbmVyYXRlVHlwaW5nPFR5cGU+IHtcbiAgY29uc3QgcmVnaXN0cnkgPSBuZXcgTWFwPHN0cmluZywgdHlwZW9mIEN1c3RvbVR5cGVCYXNlQ2xhc3M+KCk7XG5cbiAgY29uc3QgbGVnYWN5VHlwZSA9IGdldFNka2dlblR5cGUodHlwZSwgcmVnaXN0cnkpO1xuICBjb25zdCB0eXBlVGFibGUgPSBnZXRUeXBlVGFibGVGcm9tUmVnaXN0cnkocmVnaXN0cnkpO1xuXG4gIHJldHVybiBkZWNvZGUodHlwZVRhYmxlLCBcIlwiLCBsZWdhY3lUeXBlLCB2YWx1ZSkgYXMgR2VuZXJhdGVUeXBpbmc8VHlwZT47XG59XG4iXX0=
|