socket-function 1.1.48 → 1.2.0
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/SetProcessVariables.ts.cache +9 -0
- package/dist/SocketFunction.ts.cache +467 -0
- package/hot/dist/HotReloadController.ts.cache +252 -0
- package/package.json +1 -1
- package/require/dist/RequireController.ts.cache +386 -0
- package/require/dist/compileFlags.ts.cache +41 -0
- package/require/dist/extMapper.ts.cache +368 -0
- package/require/dist/require.ts.cache +676 -0
- package/src/JSONLACKS/dist/JSONLACKS.ts.cache +469 -0
- package/src/dist/CallFactory.ts.cache +930 -0
- package/src/dist/Zip.ts.cache +156 -0
- package/src/dist/batching.ts.cache +377 -0
- package/src/dist/bits.ts.cache +121 -0
- package/src/dist/buffers.ts.cache +76 -0
- package/src/dist/caching.ts.cache +302 -0
- package/src/dist/callHTTPHandler.ts.cache +264 -0
- package/src/dist/callManager.ts.cache +159 -0
- package/src/dist/certStore.ts.cache +59 -0
- package/src/dist/createSingleton.ts.cache +62 -0
- package/src/dist/fixLargeNetworkCalls.ts.cache +17 -0
- package/src/dist/forwardPort.ts.cache +222 -0
- package/src/dist/https.ts.cache +141 -0
- package/src/dist/misc.ts.cache +499 -0
- package/src/dist/nodeCache.ts.cache +136 -0
- package/src/dist/nodeProxy.ts.cache +57 -0
- package/src/dist/protocolNegotiation.ts.cache +101 -0
- package/src/dist/tlsParsing.ts.cache +85 -0
- package/src/dist/types.ts.cache +9 -0
- package/src/dist/webSocketServer.ts.cache +365 -0
- package/src/dist/websocketFactory.ts.cache +53 -0
- package/src/formatting/dist/colors.ts.cache +98 -0
- package/src/formatting/dist/format.ts.cache +396 -0
- package/src/formatting/dist/logColors.ts.cache +28 -0
- package/src/lz4/dist/LZ4.ts.cache +53 -0
- package/src/profiling/dist/getOwnTime.ts.cache +100 -0
- package/src/profiling/dist/measure.ts.cache +338 -0
- package/src/profiling/dist/stats.ts.cache +202 -0
- package/src/profiling/dist/statsFormat.ts.cache +45 -0
- package/src/profiling/getOwnTime.ts +7 -1
- package/src/profiling/measure.ts +25 -16
- package/time/dist/trueTimeShim.ts.cache +656 -0
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
"use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
6
|
+
//exports.setHTTPResultHeaders = exports.httpCallHandler = exports.getCurrentHTTPRequest = exports.getNodeIdsFromRequest = exports.getServerLocationFromRequest = exports.setDefaultHTTPCall = void 0;
|
|
7
|
+
const callManager_1 = require("./callManager");
|
|
8
|
+
const SocketFunction_1 = require("../SocketFunction");
|
|
9
|
+
const zlib_1 = __importDefault(require("zlib"));
|
|
10
|
+
const misc_1 = require("./misc");
|
|
11
|
+
const nodeCache_1 = require("./nodeCache");
|
|
12
|
+
const createSingleton_1 = require("./createSingleton");
|
|
13
|
+
// Shared across copies of this package, so the default HTTP call set through one copy is used by
|
|
14
|
+
// the HTTP handler of any other copy. See createSingleton.
|
|
15
|
+
const defaultHTTPCall = (0, createSingleton_1.createSingleton)("callHTTPHandler.defaultHTTPCall", 1, () => ({ call: undefined }));
|
|
16
|
+
function setDefaultHTTPCall(call) {
|
|
17
|
+
defaultHTTPCall.get().call = call;
|
|
18
|
+
}
|
|
19
|
+
exports.setDefaultHTTPCall = setDefaultHTTPCall;
|
|
20
|
+
function getServerLocationFromRequest(request) {
|
|
21
|
+
let host = request.headers.host;
|
|
22
|
+
if (!host) {
|
|
23
|
+
throw new Error(`Missing host in request headers`);
|
|
24
|
+
}
|
|
25
|
+
let port = 443;
|
|
26
|
+
if (host.includes(":")) {
|
|
27
|
+
port = +host.split(":")[1];
|
|
28
|
+
host = host.split(":")[0];
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
address: host,
|
|
32
|
+
// This is OUR location, so whatever they connected to us... we must be listening on!
|
|
33
|
+
// (and the localPort doesn't matter in this case)
|
|
34
|
+
port,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
exports.getServerLocationFromRequest = getServerLocationFromRequest;
|
|
38
|
+
function getNodeIdsFromRequest(request) {
|
|
39
|
+
var _a;
|
|
40
|
+
// TODO: Support passing signed proof of userCertificate via headers in the HTTP request.
|
|
41
|
+
// THAT WAY HTTP can have consistent nodeIds, instead of making them randomly every time!
|
|
42
|
+
// (This isn't needed or possible for websockets, but they stay open, so calling functions
|
|
43
|
+
// after they open to set the nodeId is possible, and preferred).
|
|
44
|
+
let remoteAddress = (_a = request.socket.remoteAddress) === null || _a === void 0 ? void 0 : _a.split(":").pop();
|
|
45
|
+
if (!remoteAddress) {
|
|
46
|
+
throw new Error(`Missing remoteAddress`);
|
|
47
|
+
}
|
|
48
|
+
const nodeId = (0, nodeCache_1.getClientNodeId)(remoteAddress);
|
|
49
|
+
const serverLocation = getServerLocationFromRequest(request);
|
|
50
|
+
// IMPORTANT! Not the actual local id, but is the id the client called
|
|
51
|
+
const localNodeId = (0, nodeCache_1.getNodeId)(serverLocation.address, serverLocation.port);
|
|
52
|
+
return { nodeId, localNodeId };
|
|
53
|
+
}
|
|
54
|
+
exports.getNodeIdsFromRequest = getNodeIdsFromRequest;
|
|
55
|
+
// Shared across copies of this package, so getCurrentHTTPRequest works even when the call was set
|
|
56
|
+
// up by a different copy's HTTP handler. See createSingleton.
|
|
57
|
+
const requests = (0, createSingleton_1.createSingleton)("callHTTPHandler.requests", 1, () => new Map()).get();
|
|
58
|
+
function getCurrentHTTPRequest() {
|
|
59
|
+
return requests.get(SocketFunction_1.SocketFunction.getCaller());
|
|
60
|
+
}
|
|
61
|
+
exports.getCurrentHTTPRequest = getCurrentHTTPRequest;
|
|
62
|
+
async function httpCallHandler(request, response) {
|
|
63
|
+
var _a;
|
|
64
|
+
try {
|
|
65
|
+
// Always set x-frame-options, to prevent iframe embedding click hijacking
|
|
66
|
+
response.setHeader("X-Frame-Options", "SAMEORIGIN");
|
|
67
|
+
// Don't keep alive, to prevent issues with zombie sockets.
|
|
68
|
+
response.setHeader("Connection", "close");
|
|
69
|
+
// CORS bs (due to having to explictly allow subdomains)
|
|
70
|
+
{
|
|
71
|
+
response.setHeader("Strict-Transport-Security", "max-age=63072000; includeSubDomains; preload");
|
|
72
|
+
response.setHeader("Cross-Origin-Opener-Policy", SocketFunction_1.SocketFunction.COOP);
|
|
73
|
+
response.setHeader("Cross-Origin-Embedder-Policy", SocketFunction_1.SocketFunction.COEP);
|
|
74
|
+
let origin = request.headers.origin || request.headers.referer;
|
|
75
|
+
let allowed = false;
|
|
76
|
+
if (!origin) {
|
|
77
|
+
// I guess it's a script, so just allow it (as it could easily set any header it wanted anyways)
|
|
78
|
+
allowed = true;
|
|
79
|
+
origin = "*";
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
let host = request.headers.host;
|
|
83
|
+
if (!host) {
|
|
84
|
+
throw new Error("Missing host in request headers");
|
|
85
|
+
}
|
|
86
|
+
let hostDomain = (0, misc_1.getRootDomain)(host);
|
|
87
|
+
let originDomain = (0, misc_1.getRootDomain)(origin);
|
|
88
|
+
allowed = hostDomain === originDomain;
|
|
89
|
+
if (!allowed) {
|
|
90
|
+
console.log(`Rejected CORS, hostDomain: ${hostDomain} !== ${originDomain}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Allow if it has no origin, as that means it isn't a CORS request?
|
|
94
|
+
if (allowed) {
|
|
95
|
+
response.setHeader("Cross-Origin-Resource-Policy", "cross-origin");
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
response.setHeader("Cross-Origin-Resource-Policy", "same-site");
|
|
99
|
+
}
|
|
100
|
+
response.setHeader("vary", "Access-Control-Request-Headers");
|
|
101
|
+
response.setHeader("Access-Control-Allow-Origin", allowed ? origin : "");
|
|
102
|
+
if (allowed) {
|
|
103
|
+
response.setHeader("Access-Control-Allow-Credentials", "true");
|
|
104
|
+
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
105
|
+
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Content-Length, X-Requested-With, x-uncompressed-content-length, Cookie");
|
|
106
|
+
}
|
|
107
|
+
response.setHeader("Access-Control-Expose-Headers", "x-uncompressed-content-length");
|
|
108
|
+
}
|
|
109
|
+
let urlBase = request.url;
|
|
110
|
+
if (!urlBase) {
|
|
111
|
+
throw new Error("Missing URL");
|
|
112
|
+
}
|
|
113
|
+
let protocol = "https";
|
|
114
|
+
let url = protocol + "://" + request.headers.host + request.url;
|
|
115
|
+
if (SocketFunction_1.SocketFunction.logMessages) {
|
|
116
|
+
console.log(`HTTP request (${request.method}) ${url}`);
|
|
117
|
+
}
|
|
118
|
+
let urlObj = new URL(url);
|
|
119
|
+
let payload = await new Promise((resolve, reject) => {
|
|
120
|
+
let data = [];
|
|
121
|
+
request
|
|
122
|
+
.on("data", chunk => data.push(chunk))
|
|
123
|
+
.on("end", () => resolve(Buffer.concat(data)))
|
|
124
|
+
.on("error", (err) => reject(err));
|
|
125
|
+
});
|
|
126
|
+
const { nodeId, localNodeId } = getNodeIdsFromRequest(request);
|
|
127
|
+
let caller = {
|
|
128
|
+
nodeId,
|
|
129
|
+
localNodeId,
|
|
130
|
+
};
|
|
131
|
+
let classGuid = urlObj.searchParams.get("classGuid");
|
|
132
|
+
let functionName = urlObj.searchParams.get("functionName");
|
|
133
|
+
let args = urlObj.searchParams.get("args");
|
|
134
|
+
if (!classGuid) {
|
|
135
|
+
let defaultCall = defaultHTTPCall.get().call;
|
|
136
|
+
if (defaultCall) {
|
|
137
|
+
classGuid = defaultCall.classGuid;
|
|
138
|
+
functionName = defaultCall.functionName;
|
|
139
|
+
args = defaultCall.args;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
throw new Error("Missing classGuid in URL query");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (!functionName) {
|
|
146
|
+
throw new Error("Missing functionName in URL query");
|
|
147
|
+
}
|
|
148
|
+
if (!args) {
|
|
149
|
+
args = [];
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
if (typeof args === "string") {
|
|
153
|
+
args = JSON.parse(args);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (payload.length > 0) {
|
|
157
|
+
args = JSON.parse(payload.toString())["args"];
|
|
158
|
+
}
|
|
159
|
+
let call = {
|
|
160
|
+
nodeId,
|
|
161
|
+
classGuid,
|
|
162
|
+
functionName,
|
|
163
|
+
args,
|
|
164
|
+
};
|
|
165
|
+
if ((0, callManager_1.isDataImmutable)(call)) {
|
|
166
|
+
/** ETag cache, BUT, hashes only the input. Only valid for fully immutable resources
|
|
167
|
+
* (ex data storage, as any endpoints that run code could have that code change).
|
|
168
|
+
* - Shouldn't be needed, but I am seeing chrome fail to cache a lot of requests,
|
|
169
|
+
* which could cost us multiple dollars in server costs from atlas.
|
|
170
|
+
*/
|
|
171
|
+
response.setHeader("cache-control", "public, max-age=15206400, immutable");
|
|
172
|
+
let hash = (0, misc_1.sha256Hash)(Buffer.from(JSON.stringify(call)));
|
|
173
|
+
response.setHeader("ETag", hash);
|
|
174
|
+
if (request.headers["if-none-match"] === hash) {
|
|
175
|
+
response.writeHead(304);
|
|
176
|
+
console.log(`CACHED Immutable HTTP response (${request.method}) ${url}`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
requests.set(caller, request);
|
|
181
|
+
let result;
|
|
182
|
+
try {
|
|
183
|
+
result = await (0, callManager_1.performLocalCall)({
|
|
184
|
+
caller,
|
|
185
|
+
call
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
requests.delete(caller);
|
|
190
|
+
}
|
|
191
|
+
let resultBuffer;
|
|
192
|
+
if (typeof result === "object" && result && result instanceof Buffer) {
|
|
193
|
+
resultBuffer = result;
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
resultBuffer = Buffer.from(JSON.stringify(result));
|
|
197
|
+
}
|
|
198
|
+
let headers = resultBuffer[resultHeaders];
|
|
199
|
+
// NOTE: Our ETag caching is only to reduce data sent on the wire, we evaluate the calls
|
|
200
|
+
// every time (so it is strictly a wire cache for HTTP, not a computation cache)
|
|
201
|
+
if (SocketFunction_1.SocketFunction.HTTP_ETAG_CACHE) {
|
|
202
|
+
response.setHeader("cache-control", "private, max-age=0, must-revalidate");
|
|
203
|
+
let hash = (0, misc_1.sha256Hash)(resultBuffer);
|
|
204
|
+
response.setHeader("ETag", hash);
|
|
205
|
+
if (request.headers["if-none-match"] === hash) {
|
|
206
|
+
response.writeHead(304);
|
|
207
|
+
console.log(`CACHED HTTP response ${(0, misc_1.formatNumberSuffixed)(resultBuffer.length)}B (${request.method}) ${url}`);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
if (headers) {
|
|
212
|
+
for (let headerName in headers) {
|
|
213
|
+
response.setHeader(headerName, headers[headerName]);
|
|
214
|
+
}
|
|
215
|
+
let status = headers["status"];
|
|
216
|
+
if (status) {
|
|
217
|
+
response.writeHead(+status);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
let uncompressedLength = resultBuffer.length;
|
|
222
|
+
if (SocketFunction_1.SocketFunction.HTTP_COMPRESS && ((_a = request.headers["accept-encoding"]) === null || _a === void 0 ? void 0 : _a.includes("gzip")) && !(headers === null || headers === void 0 ? void 0 : headers["Content-Encoding"])) {
|
|
223
|
+
// NOTE: This is a BIT slow. To speed it up, functions can use an internal cache, according to their function,
|
|
224
|
+
// and return a Buffer (which they can as any cast to make the returned type allowed, as returned Buffers will
|
|
225
|
+
// just be treated like a buffer of JSON data).
|
|
226
|
+
// - The caller should use getCurrentHTTPRequest first though, to check if gzip is allowed
|
|
227
|
+
response.setHeader("Content-Encoding", "gzip");
|
|
228
|
+
resultBuffer = await new Promise((resolve, reject) => {
|
|
229
|
+
zlib_1.default.gzip(resultBuffer, {}, (err, result) => {
|
|
230
|
+
if (err) {
|
|
231
|
+
reject(err);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
resolve(result);
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
response.setHeader("Content-Length", resultBuffer.length.toString());
|
|
240
|
+
if (!response.getHeader("X-Uncompressed-Content-Length")) {
|
|
241
|
+
response.setHeader("X-Uncompressed-Content-Length", uncompressedLength.toString());
|
|
242
|
+
}
|
|
243
|
+
response.write(resultBuffer);
|
|
244
|
+
if (SocketFunction_1.SocketFunction.logMessages) {
|
|
245
|
+
console.log(`HTTP response ${(0, misc_1.formatNumberSuffixed)(resultBuffer.length)}B (${request.method}) ${url}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
catch (e) {
|
|
249
|
+
console.log(`HTTP error (${request.method}) ${e.stack}`);
|
|
250
|
+
response.writeHead(500, String(e.message).replace(/[^\x20-\x7E]/g, ""));
|
|
251
|
+
}
|
|
252
|
+
finally {
|
|
253
|
+
response.end();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
exports.httpCallHandler = httpCallHandler;
|
|
257
|
+
const resultHeaders = Symbol("resultHeaders");
|
|
258
|
+
function setHTTPResultHeaders(result, headers) {
|
|
259
|
+
result[resultHeaders] = headers;
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
exports.setHTTPResultHeaders = setHTTPResultHeaders;
|
|
263
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsbEhUVFBIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2FsbEhUVFBIYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBLCtDQUFrRTtBQUNsRSxzREFBbUQ7QUFFbkQsZ0RBQXdCO0FBQ3hCLGlDQUF5RTtBQUN6RSwyQ0FBeUQ7QUFDekQsdURBQW9EO0FBRXBELGlHQUFpRztBQUNqRyw0REFBNEQ7QUFDNUQsTUFBTSxlQUFlLEdBQUcsSUFBQSxpQ0FBZSxFQUFDLGlDQUFpQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQWlDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFFbkksU0FBZ0Isa0JBQWtCLENBQUMsSUFBYztJQUM3QyxlQUFlLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN0QyxDQUFDO0FBRkQsZ0RBRUM7QUFFRCxTQUFnQiw0QkFBNEIsQ0FBQyxPQUE2QjtJQUN0RSxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUNELElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQztJQUNmLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3JCLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUNELE9BQU87UUFDSCxPQUFPLEVBQUUsSUFBSTtRQUNiLHFGQUFxRjtRQUNyRixtREFBbUQ7UUFDbkQsSUFBSTtLQUNQLENBQUM7QUFDTixDQUFDO0FBaEJELG9FQWdCQztBQUVELFNBQWdCLHFCQUFxQixDQUFDLE9BQTZCOztJQUMvRCx5RkFBeUY7SUFDekYsMEZBQTBGO0lBQzFGLDJGQUEyRjtJQUMzRixzRUFBc0U7SUFDdEUsSUFBSSxhQUFhLEdBQUcsTUFBQSxPQUFPLENBQUMsTUFBTSxDQUFDLGFBQWEsMENBQUUsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUNuRSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFDRCxNQUFNLE1BQU0sR0FBRyxJQUFBLDJCQUFlLEVBQUMsYUFBYSxDQUFDLENBQUM7SUFFOUMsTUFBTSxjQUFjLEdBQUcsNEJBQTRCLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDN0Qsc0VBQXNFO0lBQ3RFLE1BQU0sV0FBVyxHQUFHLElBQUEscUJBQVMsRUFBQyxjQUFjLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDO0FBQ25DLENBQUM7QUFmRCxzREFlQztBQUVELGtHQUFrRztBQUNsRywrREFBK0Q7QUFDL0QsTUFBTSxRQUFRLEdBQUcsSUFBQSxpQ0FBZSxFQUFDLDBCQUEwQixFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEdBQUcsRUFBdUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQzVILFNBQWdCLHFCQUFxQjtJQUNqQyxPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsK0JBQWMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0FBQ3BELENBQUM7QUFGRCxzREFFQztBQUVNLEtBQUssVUFBVSxlQUFlLENBQUMsT0FBNkIsRUFBRSxRQUE2Qjs7SUFDOUYsSUFBSSxDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDcEQsMkRBQTJEO1FBQzNELFFBQVEsQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTFDLHdEQUF3RDtRQUN4RCxDQUFDO1lBQ0csUUFBUSxDQUFDLFNBQVMsQ0FBQywyQkFBMkIsRUFBRSw4Q0FBOEMsQ0FBQyxDQUFDO1lBQ2hHLFFBQVEsQ0FBQyxTQUFTLENBQUMsNEJBQTRCLEVBQUUsK0JBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0RSxRQUFRLENBQUMsU0FBUyxDQUFDLDhCQUE4QixFQUFFLCtCQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFeEUsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDL0QsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDO1lBQ3BCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDVixnR0FBZ0c7Z0JBQ2hHLE9BQU8sR0FBRyxJQUFJLENBQUM7Z0JBQ2YsTUFBTSxHQUFHLEdBQUcsQ0FBQztZQUNqQixDQUFDO2lCQUFNLENBQUM7Z0JBQ0osSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7Z0JBQ2hDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDUixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7Z0JBQ3ZELENBQUM7Z0JBQ0QsSUFBSSxVQUFVLEdBQUcsSUFBQSxvQkFBYSxFQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNyQyxJQUFJLFlBQVksR0FBRyxJQUFBLG9CQUFhLEVBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3pDLE9BQU8sR0FBRyxVQUFVLEtBQUssWUFBWSxDQUFDO2dCQUN0QyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ1gsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsVUFBVSxRQUFRLFlBQVksRUFBRSxDQUFDLENBQUM7Z0JBQ2hGLENBQUM7WUFDTCxDQUFDO1lBRUQsb0VBQW9FO1lBQ3BFLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQ1YsUUFBUSxDQUFDLFNBQVMsQ0FBQyw4QkFBOEIsRUFBRSxjQUFjLENBQUMsQ0FBQztZQUN2RSxDQUFDO2lCQUFNLENBQUM7Z0JBQ0osUUFBUSxDQUFDLFNBQVMsQ0FBQyw4QkFBOEIsRUFBRSxXQUFXLENBQUMsQ0FBQztZQUNwRSxDQUFDO1lBRUQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQztZQUM3RCxRQUFRLENBQUMsU0FBUyxDQUFDLDZCQUE2QixFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUV6RSxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUNWLFFBQVEsQ0FBQyxTQUFTLENBQUMsa0NBQWtDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQy9ELFFBQVEsQ0FBQyxTQUFTLENBQUMsOEJBQThCLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztnQkFDdEYsUUFBUSxDQUFDLFNBQVMsQ0FBQyw4QkFBOEIsRUFBRSxzR0FBc0csQ0FBQyxDQUFDO1lBQy9KLENBQUM7WUFDRCxRQUFRLENBQUMsU0FBUyxDQUFDLCtCQUErQixFQUFFLCtCQUErQixDQUFDLENBQUM7UUFDekYsQ0FBQztRQUdELElBQUksT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUM7UUFDMUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ1gsTUFBTSxJQUFJLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBRUQsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksR0FBRyxHQUFHLFFBQVEsR0FBRyxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUVoRSxJQUFJLCtCQUFjLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsT0FBTyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFDRCxJQUFJLE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUUxQixJQUFJLE9BQU8sR0FBRyxNQUFNLElBQUksT0FBTyxDQUFTLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3hELElBQUksSUFBSSxHQUFhLEVBQUUsQ0FBQztZQUN4QixPQUFPO2lCQUNGLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUNyQyxFQUFFLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7aUJBQzdDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUNqQztRQUNULENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsR0FBRyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUUvRCxJQUFJLE1BQU0sR0FBa0I7WUFDeEIsTUFBTTtZQUNOLFdBQVc7U0FDZCxDQUFDO1FBRUYsSUFBSSxTQUFTLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckQsSUFBSSxZQUFZLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDM0QsSUFBSSxJQUFJLEdBQThCLE1BQU0sQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXRFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNiLElBQUksV0FBVyxHQUFHLGVBQWUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDN0MsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDZCxTQUFTLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQztnQkFDbEMsWUFBWSxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUM7Z0JBQ3hDLElBQUksR0FBRyxXQUFXLENBQUMsSUFBSSxDQUFDO1lBQzVCLENBQUM7aUJBQU0sQ0FBQztnQkFDSixNQUFNLElBQUksS0FBSyxDQUFDLGdDQUFnQyxDQUFDLENBQUM7WUFDdEQsQ0FBQztRQUNMLENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ3pELENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDUixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQ2QsQ0FBQzthQUFNLENBQUM7WUFDSixJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO2dCQUMzQixJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQWMsQ0FBQztZQUN6QyxDQUFDO1FBQ0wsQ0FBQztRQUVELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNyQixJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQWMsQ0FBQztRQUMvRCxDQUFDO1FBRUQsSUFBSSxJQUFJLEdBQWlCO1lBQ3JCLE1BQU07WUFDTixTQUFTO1lBQ1QsWUFBWTtZQUNaLElBQUk7U0FDUCxDQUFDO1FBRUYsSUFBSSxJQUFBLDZCQUFlLEVBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN4Qjs7OztjQUlFO1lBQ0YsUUFBUSxDQUFDLFNBQVMsQ0FBQyxlQUFlLEVBQUUscUNBQXFDLENBQUMsQ0FBQztZQUMzRSxJQUFJLElBQUksR0FBRyxJQUFBLGlCQUFVLEVBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN6RCxRQUFRLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNqQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQzVDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUNBQW1DLE9BQU8sQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDekUsT0FBTztZQUNYLENBQUM7UUFDTCxDQUFDO1FBRUQsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDOUIsSUFBSSxNQUFlLENBQUM7UUFDcEIsSUFBSSxDQUFDO1lBQ0QsTUFBTSxHQUFHLE1BQU0sSUFBQSw4QkFBZ0IsRUFBQztnQkFDNUIsTUFBTTtnQkFDTixJQUFJO2FBQ1AsQ0FBQyxDQUFDO1FBQ1AsQ0FBQztnQkFBUyxDQUFDO1lBQ1AsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBRUQsSUFBSSxZQUFvQixDQUFDO1FBQ3pCLElBQUksT0FBTyxNQUFNLEtBQUssUUFBUSxJQUFJLE1BQU0sSUFBSSxNQUFNLFlBQVksTUFBTSxFQUFFLENBQUM7WUFDbkUsWUFBWSxHQUFHLE1BQU0sQ0FBQztRQUMxQixDQUFDO2FBQU0sQ0FBQztZQUNKLFlBQVksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBRUQsSUFBSSxPQUFPLEdBQUksWUFBK0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUU5RCx3RkFBd0Y7UUFDeEYsaUZBQWlGO1FBQ2pGLElBQUksK0JBQWMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNqQyxRQUFRLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxxQ0FBcUMsQ0FBQyxDQUFDO1lBQzNFLElBQUksSUFBSSxHQUFHLElBQUEsaUJBQVUsRUFBQyxZQUFZLENBQUMsQ0FBQztZQUNwQyxRQUFRLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNqQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7Z0JBQzVDLFFBQVEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLElBQUEsMkJBQW9CLEVBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLE9BQU8sQ0FBQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQztnQkFDL0csT0FBTztZQUNYLENBQUM7UUFDTCxDQUFDO1FBRUQsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNWLEtBQUssSUFBSSxVQUFVLElBQUksT0FBTyxFQUFFLENBQUM7Z0JBQzdCLFFBQVEsQ0FBQyxTQUFTLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQ3hELENBQUM7WUFDRCxJQUFJLE1BQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0IsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDVCxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzVCLE9BQU87WUFDWCxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksa0JBQWtCLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQztRQUM3QyxJQUFJLCtCQUFjLENBQUMsYUFBYSxLQUFJLE1BQUEsT0FBTyxDQUFDLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQywwQ0FBRSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUEsSUFBSSxDQUFDLENBQUEsT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFHLGtCQUFrQixDQUFDLENBQUEsRUFBRSxDQUFDO1lBQ3pILDhHQUE4RztZQUM5RywrR0FBK0c7WUFDL0csZ0RBQWdEO1lBQ2hELDJGQUEyRjtZQUMzRixRQUFRLENBQUMsU0FBUyxDQUFDLGtCQUFrQixFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLFlBQVksR0FBRyxNQUFNLElBQUksT0FBTyxDQUFTLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUN6RCxjQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsTUFBTSxFQUFFLEVBQUU7b0JBQ3hDLElBQUksR0FBRyxFQUFFLENBQUM7d0JBQ04sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNoQixDQUFDO3lCQUFNLENBQUM7d0JBQ0osT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUNwQixDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDO1FBQ0QsUUFBUSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDckUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsK0JBQStCLENBQUMsRUFBRSxDQUFDO1lBQ3ZELFFBQVEsQ0FBQyxTQUFTLENBQUMsK0JBQStCLEVBQUUsa0JBQWtCLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUN2RixDQUFDO1FBQ0QsUUFBUSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QixJQUFJLCtCQUFjLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBQSwyQkFBb0IsRUFBQyxZQUFZLENBQUMsTUFBTSxDQUFDLE9BQU8sT0FBTyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzVHLENBQUM7SUFFTCxDQUFDO0lBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztRQUNkLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDMUQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUUsQ0FBQztZQUFTLENBQUM7UUFDUCxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDbkIsQ0FBQztBQUNMLENBQUM7QUFoTkQsMENBZ05DO0FBR0QsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRzlDLFNBQWdCLG9CQUFvQixDQUNoQyxNQUFzQixFQUN0QixPQUFxQztJQUVyQyxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsT0FBTyxDQUFDO0lBQ2hDLE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFORCxvREFNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBodHRwIGZyb20gXCJodHRwXCI7XG5pbXBvcnQgdGxzIGZyb20gXCJ0bHNcIjtcbmltcG9ydCB7IENhbGxlckNvbnRleHQsIENhbGxUeXBlLCBGdWxsQ2FsbFR5cGUgfSBmcm9tIFwiLi4vU29ja2V0RnVuY3Rpb25UeXBlc1wiO1xuaW1wb3J0IHsgaXNEYXRhSW1tdXRhYmxlLCBwZXJmb3JtTG9jYWxDYWxsIH0gZnJvbSBcIi4vY2FsbE1hbmFnZXJcIjtcbmltcG9ydCB7IFNvY2tldEZ1bmN0aW9uIH0gZnJvbSBcIi4uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyBnemlwIH0gZnJvbSBcInpsaWJcIjtcbmltcG9ydCB6bGliIGZyb20gXCJ6bGliXCI7XG5pbXBvcnQgeyBmb3JtYXROdW1iZXJTdWZmaXhlZCwgZ2V0Um9vdERvbWFpbiwgc2hhMjU2SGFzaCB9IGZyb20gXCIuL21pc2NcIjtcbmltcG9ydCB7IGdldENsaWVudE5vZGVJZCwgZ2V0Tm9kZUlkIH0gZnJvbSBcIi4vbm9kZUNhY2hlXCI7XG5pbXBvcnQgeyBjcmVhdGVTaW5nbGV0b24gfSBmcm9tIFwiLi9jcmVhdGVTaW5nbGV0b25cIjtcblxuLy8gU2hhcmVkIGFjcm9zcyBjb3BpZXMgb2YgdGhpcyBwYWNrYWdlLCBzbyB0aGUgZGVmYXVsdCBIVFRQIGNhbGwgc2V0IHRocm91Z2ggb25lIGNvcHkgaXMgdXNlZCBieVxuLy8gIHRoZSBIVFRQIGhhbmRsZXIgb2YgYW55IG90aGVyIGNvcHkuIFNlZSBjcmVhdGVTaW5nbGV0b24uXG5jb25zdCBkZWZhdWx0SFRUUENhbGwgPSBjcmVhdGVTaW5nbGV0b24oXCJjYWxsSFRUUEhhbmRsZXIuZGVmYXVsdEhUVFBDYWxsXCIsIDEsICgpID0+ICh7IGNhbGw6IHVuZGVmaW5lZCBhcyBDYWxsVHlwZSB8IHVuZGVmaW5lZCB9KSk7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXREZWZhdWx0SFRUUENhbGwoY2FsbDogQ2FsbFR5cGUpIHtcbiAgICBkZWZhdWx0SFRUUENhbGwuZ2V0KCkuY2FsbCA9IGNhbGw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZXJ2ZXJMb2NhdGlvbkZyb21SZXF1ZXN0KHJlcXVlc3Q6IGh0dHAuSW5jb21pbmdNZXNzYWdlKSB7XG4gICAgbGV0IGhvc3QgPSByZXF1ZXN0LmhlYWRlcnMuaG9zdDtcbiAgICBpZiAoIWhvc3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIGhvc3QgaW4gcmVxdWVzdCBoZWFkZXJzYCk7XG4gICAgfVxuICAgIGxldCBwb3J0ID0gNDQzO1xuICAgIGlmIChob3N0LmluY2x1ZGVzKFwiOlwiKSkge1xuICAgICAgICBwb3J0ID0gK2hvc3Quc3BsaXQoXCI6XCIpWzFdO1xuICAgICAgICBob3N0ID0gaG9zdC5zcGxpdChcIjpcIilbMF07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIGFkZHJlc3M6IGhvc3QsXG4gICAgICAgIC8vIFRoaXMgaXMgT1VSIGxvY2F0aW9uLCBzbyB3aGF0ZXZlciB0aGV5IGNvbm5lY3RlZCB0byB1cy4uLiB3ZSBtdXN0IGJlIGxpc3RlbmluZyBvbiFcbiAgICAgICAgLy8gIChhbmQgdGhlIGxvY2FsUG9ydCBkb2Vzbid0IG1hdHRlciBpbiB0aGlzIGNhc2UpXG4gICAgICAgIHBvcnQsXG4gICAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE5vZGVJZHNGcm9tUmVxdWVzdChyZXF1ZXN0OiBodHRwLkluY29taW5nTWVzc2FnZSkge1xuICAgIC8vIFRPRE86IFN1cHBvcnQgcGFzc2luZyBzaWduZWQgcHJvb2Ygb2YgdXNlckNlcnRpZmljYXRlIHZpYSBoZWFkZXJzIGluIHRoZSBIVFRQIHJlcXVlc3QuXG4gICAgLy8gIFRIQVQgV0FZIEhUVFAgY2FuIGhhdmUgY29uc2lzdGVudCBub2RlSWRzLCBpbnN0ZWFkIG9mIG1ha2luZyB0aGVtIHJhbmRvbWx5IGV2ZXJ5IHRpbWUhXG4gICAgLy8gIChUaGlzIGlzbid0IG5lZWRlZCBvciBwb3NzaWJsZSBmb3Igd2Vic29ja2V0cywgYnV0IHRoZXkgc3RheSBvcGVuLCBzbyBjYWxsaW5nIGZ1bmN0aW9uc1xuICAgIC8vICAgICAgYWZ0ZXIgdGhleSBvcGVuIHRvIHNldCB0aGUgbm9kZUlkIGlzIHBvc3NpYmxlLCBhbmQgcHJlZmVycmVkKS5cbiAgICBsZXQgcmVtb3RlQWRkcmVzcyA9IHJlcXVlc3Quc29ja2V0LnJlbW90ZUFkZHJlc3M/LnNwbGl0KFwiOlwiKS5wb3AoKTtcbiAgICBpZiAoIXJlbW90ZUFkZHJlc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nIHJlbW90ZUFkZHJlc3NgKTtcbiAgICB9XG4gICAgY29uc3Qgbm9kZUlkID0gZ2V0Q2xpZW50Tm9kZUlkKHJlbW90ZUFkZHJlc3MpO1xuXG4gICAgY29uc3Qgc2VydmVyTG9jYXRpb24gPSBnZXRTZXJ2ZXJMb2NhdGlvbkZyb21SZXF1ZXN0KHJlcXVlc3QpO1xuICAgIC8vIElNUE9SVEFOVCEgTm90IHRoZSBhY3R1YWwgbG9jYWwgaWQsIGJ1dCBpcyB0aGUgaWQgdGhlIGNsaWVudCBjYWxsZWRcbiAgICBjb25zdCBsb2NhbE5vZGVJZCA9IGdldE5vZGVJZChzZXJ2ZXJMb2NhdGlvbi5hZGRyZXNzLCBzZXJ2ZXJMb2NhdGlvbi5wb3J0KTtcbiAgICByZXR1cm4geyBub2RlSWQsIGxvY2FsTm9kZUlkIH07XG59XG5cbi8vIFNoYXJlZCBhY3Jvc3MgY29waWVzIG9mIHRoaXMgcGFja2FnZSwgc28gZ2V0Q3VycmVudEhUVFBSZXF1ZXN0IHdvcmtzIGV2ZW4gd2hlbiB0aGUgY2FsbCB3YXMgc2V0XG4vLyAgdXAgYnkgYSBkaWZmZXJlbnQgY29weSdzIEhUVFAgaGFuZGxlci4gU2VlIGNyZWF0ZVNpbmdsZXRvbi5cbmNvbnN0IHJlcXVlc3RzID0gY3JlYXRlU2luZ2xldG9uKFwiY2FsbEhUVFBIYW5kbGVyLnJlcXVlc3RzXCIsIDEsICgpID0+IG5ldyBNYXA8Q2FsbGVyQ29udGV4dCwgaHR0cC5JbmNvbWluZ01lc3NhZ2U+KCkpLmdldCgpO1xuZXhwb3J0IGZ1bmN0aW9uIGdldEN1cnJlbnRIVFRQUmVxdWVzdCgpOiBodHRwLkluY29taW5nTWVzc2FnZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHJlcXVlc3RzLmdldChTb2NrZXRGdW5jdGlvbi5nZXRDYWxsZXIoKSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBodHRwQ2FsbEhhbmRsZXIocmVxdWVzdDogaHR0cC5JbmNvbWluZ01lc3NhZ2UsIHJlc3BvbnNlOiBodHRwLlNlcnZlclJlc3BvbnNlKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgLy8gQWx3YXlzIHNldCB4LWZyYW1lLW9wdGlvbnMsIHRvIHByZXZlbnQgaWZyYW1lIGVtYmVkZGluZyBjbGljayBoaWphY2tpbmdcbiAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiWC1GcmFtZS1PcHRpb25zXCIsIFwiU0FNRU9SSUdJTlwiKTtcbiAgICAgICAgLy8gRG9uJ3Qga2VlcCBhbGl2ZSwgdG8gcHJldmVudCBpc3N1ZXMgd2l0aCB6b21iaWUgc29ja2V0cy5cbiAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiQ29ubmVjdGlvblwiLCBcImNsb3NlXCIpO1xuXG4gICAgICAgIC8vIENPUlMgYnMgKGR1ZSB0byBoYXZpbmcgdG8gZXhwbGljdGx5IGFsbG93IHN1YmRvbWFpbnMpXG4gICAgICAgIHtcbiAgICAgICAgICAgIHJlc3BvbnNlLnNldEhlYWRlcihcIlN0cmljdC1UcmFuc3BvcnQtU2VjdXJpdHlcIiwgXCJtYXgtYWdlPTYzMDcyMDAwOyBpbmNsdWRlU3ViRG9tYWluczsgcHJlbG9hZFwiKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLnNldEhlYWRlcihcIkNyb3NzLU9yaWdpbi1PcGVuZXItUG9saWN5XCIsIFNvY2tldEZ1bmN0aW9uLkNPT1ApO1xuICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiQ3Jvc3MtT3JpZ2luLUVtYmVkZGVyLVBvbGljeVwiLCBTb2NrZXRGdW5jdGlvbi5DT0VQKTtcblxuICAgICAgICAgICAgbGV0IG9yaWdpbiA9IHJlcXVlc3QuaGVhZGVycy5vcmlnaW4gfHwgcmVxdWVzdC5oZWFkZXJzLnJlZmVyZXI7XG4gICAgICAgICAgICBsZXQgYWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKCFvcmlnaW4pIHtcbiAgICAgICAgICAgICAgICAvLyBJIGd1ZXNzIGl0J3MgYSBzY3JpcHQsIHNvIGp1c3QgYWxsb3cgaXQgKGFzIGl0IGNvdWxkIGVhc2lseSBzZXQgYW55IGhlYWRlciBpdCB3YW50ZWQgYW55d2F5cylcbiAgICAgICAgICAgICAgICBhbGxvd2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBvcmlnaW4gPSBcIipcIjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbGV0IGhvc3QgPSByZXF1ZXN0LmhlYWRlcnMuaG9zdDtcbiAgICAgICAgICAgICAgICBpZiAoIWhvc3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTWlzc2luZyBob3N0IGluIHJlcXVlc3QgaGVhZGVyc1wiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IGhvc3REb21haW4gPSBnZXRSb290RG9tYWluKGhvc3QpO1xuICAgICAgICAgICAgICAgIGxldCBvcmlnaW5Eb21haW4gPSBnZXRSb290RG9tYWluKG9yaWdpbik7XG4gICAgICAgICAgICAgICAgYWxsb3dlZCA9IGhvc3REb21haW4gPT09IG9yaWdpbkRvbWFpbjtcbiAgICAgICAgICAgICAgICBpZiAoIWFsbG93ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFJlamVjdGVkIENPUlMsIGhvc3REb21haW46ICR7aG9zdERvbWFpbn0gIT09ICR7b3JpZ2luRG9tYWlufWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWxsb3cgaWYgaXQgaGFzIG5vIG9yaWdpbiwgYXMgdGhhdCBtZWFucyBpdCBpc24ndCBhIENPUlMgcmVxdWVzdD9cbiAgICAgICAgICAgIGlmIChhbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiQ3Jvc3MtT3JpZ2luLVJlc291cmNlLVBvbGljeVwiLCBcImNyb3NzLW9yaWdpblwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiQ3Jvc3MtT3JpZ2luLVJlc291cmNlLVBvbGljeVwiLCBcInNhbWUtc2l0ZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwidmFyeVwiLCBcIkFjY2Vzcy1Db250cm9sLVJlcXVlc3QtSGVhZGVyc1wiKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLnNldEhlYWRlcihcIkFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblwiLCBhbGxvd2VkID8gb3JpZ2luIDogXCJcIik7XG5cbiAgICAgICAgICAgIGlmIChhbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHNcIiwgXCJ0cnVlXCIpO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldEhlYWRlcihcIkFjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHNcIiwgXCJHRVQsIFBPU1QsIFBVVCwgREVMRVRFLCBPUFRJT05TXCIpO1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLnNldEhlYWRlcihcIkFjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnNcIiwgXCJDb250ZW50LVR5cGUsIEF1dGhvcml6YXRpb24sIENvbnRlbnQtTGVuZ3RoLCBYLVJlcXVlc3RlZC1XaXRoLCB4LXVuY29tcHJlc3NlZC1jb250ZW50LWxlbmd0aCwgQ29va2llXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiQWNjZXNzLUNvbnRyb2wtRXhwb3NlLUhlYWRlcnNcIiwgXCJ4LXVuY29tcHJlc3NlZC1jb250ZW50LWxlbmd0aFwiKTtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgbGV0IHVybEJhc2UgPSByZXF1ZXN0LnVybDtcbiAgICAgICAgaWYgKCF1cmxCYXNlKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIFVSTFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBwcm90b2NvbCA9IFwiaHR0cHNcIjtcbiAgICAgICAgbGV0IHVybCA9IHByb3RvY29sICsgXCI6Ly9cIiArIHJlcXVlc3QuaGVhZGVycy5ob3N0ICsgcmVxdWVzdC51cmw7XG5cbiAgICAgICAgaWYgKFNvY2tldEZ1bmN0aW9uLmxvZ01lc3NhZ2VzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSFRUUCByZXF1ZXN0ICgke3JlcXVlc3QubWV0aG9kfSkgJHt1cmx9YCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHVybE9iaiA9IG5ldyBVUkwodXJsKTtcblxuICAgICAgICBsZXQgcGF5bG9hZCA9IGF3YWl0IG5ldyBQcm9taXNlPEJ1ZmZlcj4oKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbGV0IGRhdGE6IEJ1ZmZlcltdID0gW107XG4gICAgICAgICAgICByZXF1ZXN0XG4gICAgICAgICAgICAgICAgLm9uKFwiZGF0YVwiLCBjaHVuayA9PiBkYXRhLnB1c2goY2h1bmspKVxuICAgICAgICAgICAgICAgIC5vbihcImVuZFwiLCAoKSA9PiByZXNvbHZlKEJ1ZmZlci5jb25jYXQoZGF0YSkpKVxuICAgICAgICAgICAgICAgIC5vbihcImVycm9yXCIsIChlcnIpID0+IHJlamVjdChlcnIpKVxuICAgICAgICAgICAgICAgIDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgeyBub2RlSWQsIGxvY2FsTm9kZUlkIH0gPSBnZXROb2RlSWRzRnJvbVJlcXVlc3QocmVxdWVzdCk7XG5cbiAgICAgICAgbGV0IGNhbGxlcjogQ2FsbGVyQ29udGV4dCA9IHtcbiAgICAgICAgICAgIG5vZGVJZCxcbiAgICAgICAgICAgIGxvY2FsTm9kZUlkLFxuICAgICAgICB9O1xuXG4gICAgICAgIGxldCBjbGFzc0d1aWQgPSB1cmxPYmouc2VhcmNoUGFyYW1zLmdldChcImNsYXNzR3VpZFwiKTtcbiAgICAgICAgbGV0IGZ1bmN0aW9uTmFtZSA9IHVybE9iai5zZWFyY2hQYXJhbXMuZ2V0KFwiZnVuY3Rpb25OYW1lXCIpO1xuICAgICAgICBsZXQgYXJnczogc3RyaW5nIHwgdW5rbm93bltdIHwgbnVsbCA9IHVybE9iai5zZWFyY2hQYXJhbXMuZ2V0KFwiYXJnc1wiKTtcblxuICAgICAgICBpZiAoIWNsYXNzR3VpZCkge1xuICAgICAgICAgICAgbGV0IGRlZmF1bHRDYWxsID0gZGVmYXVsdEhUVFBDYWxsLmdldCgpLmNhbGw7XG4gICAgICAgICAgICBpZiAoZGVmYXVsdENhbGwpIHtcbiAgICAgICAgICAgICAgICBjbGFzc0d1aWQgPSBkZWZhdWx0Q2FsbC5jbGFzc0d1aWQ7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb25OYW1lID0gZGVmYXVsdENhbGwuZnVuY3Rpb25OYW1lO1xuICAgICAgICAgICAgICAgIGFyZ3MgPSBkZWZhdWx0Q2FsbC5hcmdzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNaXNzaW5nIGNsYXNzR3VpZCBpbiBVUkwgcXVlcnlcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmdW5jdGlvbk5hbWUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIk1pc3NpbmcgZnVuY3Rpb25OYW1lIGluIFVSTCBxdWVyeVwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghYXJncykge1xuICAgICAgICAgICAgYXJncyA9IFtdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBhcmdzID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgYXJncyA9IEpTT04ucGFyc2UoYXJncykgYXMgdW5rbm93bltdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBheWxvYWQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgYXJncyA9IEpTT04ucGFyc2UocGF5bG9hZC50b1N0cmluZygpKVtcImFyZ3NcIl0gYXMgdW5rbm93bltdO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGNhbGw6IEZ1bGxDYWxsVHlwZSA9IHtcbiAgICAgICAgICAgIG5vZGVJZCxcbiAgICAgICAgICAgIGNsYXNzR3VpZCxcbiAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSxcbiAgICAgICAgICAgIGFyZ3MsXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGlzRGF0YUltbXV0YWJsZShjYWxsKSkge1xuICAgICAgICAgICAgLyoqIEVUYWcgY2FjaGUsIEJVVCwgaGFzaGVzIG9ubHkgdGhlIGlucHV0LiBPbmx5IHZhbGlkIGZvciBmdWxseSBpbW11dGFibGUgcmVzb3VyY2VzXG4gICAgICAgICAgICAgKiAgICAgIChleCBkYXRhIHN0b3JhZ2UsIGFzIGFueSBlbmRwb2ludHMgdGhhdCBydW4gY29kZSBjb3VsZCBoYXZlIHRoYXQgY29kZSBjaGFuZ2UpLlxuICAgICAgICAgICAgICogICAgICAtIFNob3VsZG4ndCBiZSBuZWVkZWQsIGJ1dCBJIGFtIHNlZWluZyBjaHJvbWUgZmFpbCB0byBjYWNoZSBhIGxvdCBvZiByZXF1ZXN0cyxcbiAgICAgICAgICAgICAqICAgICAgICAgIHdoaWNoIGNvdWxkIGNvc3QgdXMgbXVsdGlwbGUgZG9sbGFycyBpbiBzZXJ2ZXIgY29zdHMgZnJvbSBhdGxhcy5cbiAgICAgICAgICAgICovXG4gICAgICAgICAgICByZXNwb25zZS5zZXRIZWFkZXIoXCJjYWNoZS1jb250cm9sXCIsIFwicHVibGljLCBtYXgtYWdlPTE1MjA2NDAwLCBpbW11dGFibGVcIik7XG4gICAgICAgICAgICBsZXQgaGFzaCA9IHNoYTI1Nkhhc2goQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkoY2FsbCkpKTtcbiAgICAgICAgICAgIHJlc3BvbnNlLnNldEhlYWRlcihcIkVUYWdcIiwgaGFzaCk7XG4gICAgICAgICAgICBpZiAocmVxdWVzdC5oZWFkZXJzW1wiaWYtbm9uZS1tYXRjaFwiXSA9PT0gaGFzaCkge1xuICAgICAgICAgICAgICAgIHJlc3BvbnNlLndyaXRlSGVhZCgzMDQpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDQUNIRUQgSW1tdXRhYmxlIEhUVFAgcmVzcG9uc2UgKCR7cmVxdWVzdC5tZXRob2R9KSAke3VybH1gKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXF1ZXN0cy5zZXQoY2FsbGVyLCByZXF1ZXN0KTtcbiAgICAgICAgbGV0IHJlc3VsdDogdW5rbm93bjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IHBlcmZvcm1Mb2NhbENhbGwoe1xuICAgICAgICAgICAgICAgIGNhbGxlcixcbiAgICAgICAgICAgICAgICBjYWxsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAgIHJlcXVlc3RzLmRlbGV0ZShjYWxsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHJlc3VsdEJ1ZmZlcjogQnVmZmVyO1xuICAgICAgICBpZiAodHlwZW9mIHJlc3VsdCA9PT0gXCJvYmplY3RcIiAmJiByZXN1bHQgJiYgcmVzdWx0IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgICAgICAgICByZXN1bHRCdWZmZXIgPSByZXN1bHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXN1bHRCdWZmZXIgPSBCdWZmZXIuZnJvbShKU09OLnN0cmluZ2lmeShyZXN1bHQpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBoZWFkZXJzID0gKHJlc3VsdEJ1ZmZlciBhcyBIVFRQUmVzdWx0VHlwZSlbcmVzdWx0SGVhZGVyc107XG5cbiAgICAgICAgLy8gTk9URTogT3VyIEVUYWcgY2FjaGluZyBpcyBvbmx5IHRvIHJlZHVjZSBkYXRhIHNlbnQgb24gdGhlIHdpcmUsIHdlIGV2YWx1YXRlIHRoZSBjYWxsc1xuICAgICAgICAvLyAgZXZlcnkgdGltZSAoc28gaXQgaXMgc3RyaWN0bHkgYSB3aXJlIGNhY2hlIGZvciBIVFRQLCBub3QgYSBjb21wdXRhdGlvbiBjYWNoZSlcbiAgICAgICAgaWYgKFNvY2tldEZ1bmN0aW9uLkhUVFBfRVRBR19DQUNIRSkge1xuICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiY2FjaGUtY29udHJvbFwiLCBcInByaXZhdGUsIG1heC1hZ2U9MCwgbXVzdC1yZXZhbGlkYXRlXCIpO1xuICAgICAgICAgICAgbGV0IGhhc2ggPSBzaGEyNTZIYXNoKHJlc3VsdEJ1ZmZlcik7XG4gICAgICAgICAgICByZXNwb25zZS5zZXRIZWFkZXIoXCJFVGFnXCIsIGhhc2gpO1xuICAgICAgICAgICAgaWYgKHJlcXVlc3QuaGVhZGVyc1tcImlmLW5vbmUtbWF0Y2hcIl0gPT09IGhhc2gpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoMzA0KTtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgQ0FDSEVEIEhUVFAgcmVzcG9uc2UgICR7Zm9ybWF0TnVtYmVyU3VmZml4ZWQocmVzdWx0QnVmZmVyLmxlbmd0aCl9QiAgKCR7cmVxdWVzdC5tZXRob2R9KSAke3VybH1gKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGVhZGVycykge1xuICAgICAgICAgICAgZm9yIChsZXQgaGVhZGVyTmFtZSBpbiBoZWFkZXJzKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKGhlYWRlck5hbWUsIGhlYWRlcnNbaGVhZGVyTmFtZV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHN0YXR1cyA9IGhlYWRlcnNbXCJzdGF0dXNcIl07XG4gICAgICAgICAgICBpZiAoc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2Uud3JpdGVIZWFkKCtzdGF0dXMpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBsZXQgdW5jb21wcmVzc2VkTGVuZ3RoID0gcmVzdWx0QnVmZmVyLmxlbmd0aDtcbiAgICAgICAgaWYgKFNvY2tldEZ1bmN0aW9uLkhUVFBfQ09NUFJFU1MgJiYgcmVxdWVzdC5oZWFkZXJzW1wiYWNjZXB0LWVuY29kaW5nXCJdPy5pbmNsdWRlcyhcImd6aXBcIikgJiYgIWhlYWRlcnM/LltcIkNvbnRlbnQtRW5jb2RpbmdcIl0pIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IFRoaXMgaXMgYSBCSVQgc2xvdy4gVG8gc3BlZWQgaXQgdXAsIGZ1bmN0aW9ucyBjYW4gdXNlIGFuIGludGVybmFsIGNhY2hlLCBhY2NvcmRpbmcgdG8gdGhlaXIgZnVuY3Rpb24sXG4gICAgICAgICAgICAvLyAgYW5kIHJldHVybiBhIEJ1ZmZlciAod2hpY2ggdGhleSBjYW4gYXMgYW55IGNhc3QgdG8gbWFrZSB0aGUgcmV0dXJuZWQgdHlwZSBhbGxvd2VkLCBhcyByZXR1cm5lZCBCdWZmZXJzIHdpbGxcbiAgICAgICAgICAgIC8vICBqdXN0IGJlIHRyZWF0ZWQgbGlrZSBhIGJ1ZmZlciBvZiBKU09OIGRhdGEpLlxuICAgICAgICAgICAgLy8gIC0gVGhlIGNhbGxlciBzaG91bGQgdXNlIGdldEN1cnJlbnRIVFRQUmVxdWVzdCBmaXJzdCB0aG91Z2gsIHRvIGNoZWNrIGlmIGd6aXAgaXMgYWxsb3dlZFxuICAgICAgICAgICAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiQ29udGVudC1FbmNvZGluZ1wiLCBcImd6aXBcIik7XG4gICAgICAgICAgICByZXN1bHRCdWZmZXIgPSBhd2FpdCBuZXcgUHJvbWlzZTxCdWZmZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICB6bGliLmd6aXAocmVzdWx0QnVmZmVyLCB7fSwgKGVyciwgcmVzdWx0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXNwb25zZS5zZXRIZWFkZXIoXCJDb250ZW50LUxlbmd0aFwiLCByZXN1bHRCdWZmZXIubGVuZ3RoLnRvU3RyaW5nKCkpO1xuICAgICAgICBpZiAoIXJlc3BvbnNlLmdldEhlYWRlcihcIlgtVW5jb21wcmVzc2VkLUNvbnRlbnQtTGVuZ3RoXCIpKSB7XG4gICAgICAgICAgICByZXNwb25zZS5zZXRIZWFkZXIoXCJYLVVuY29tcHJlc3NlZC1Db250ZW50LUxlbmd0aFwiLCB1bmNvbXByZXNzZWRMZW5ndGgudG9TdHJpbmcoKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2Uud3JpdGUocmVzdWx0QnVmZmVyKTtcbiAgICAgICAgaWYgKFNvY2tldEZ1bmN0aW9uLmxvZ01lc3NhZ2VzKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSFRUUCByZXNwb25zZSAgJHtmb3JtYXROdW1iZXJTdWZmaXhlZChyZXN1bHRCdWZmZXIubGVuZ3RoKX1CICAoJHtyZXF1ZXN0Lm1ldGhvZH0pICR7dXJsfWApO1xuICAgICAgICB9XG5cbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgY29uc29sZS5sb2coYEhUVFAgZXJyb3IgICgke3JlcXVlc3QubWV0aG9kfSkgJHtlLnN0YWNrfWApO1xuICAgICAgICByZXNwb25zZS53cml0ZUhlYWQoNTAwLCBTdHJpbmcoZS5tZXNzYWdlKS5yZXBsYWNlKC9bXlxceDIwLVxceDdFXS9nLCBcIlwiKSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgICAgcmVzcG9uc2UuZW5kKCk7XG4gICAgfVxufVxuXG5cbmNvbnN0IHJlc3VsdEhlYWRlcnMgPSBTeW1ib2woXCJyZXN1bHRIZWFkZXJzXCIpO1xudHlwZSBIVFRQUmVzdWx0VHlwZSA9IEJ1ZmZlciAmIHsgW3Jlc3VsdEhlYWRlcnNdPzogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSB9O1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0SFRUUFJlc3VsdEhlYWRlcnMoXG4gICAgcmVzdWx0OiBIVFRQUmVzdWx0VHlwZSxcbiAgICBoZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9LFxuKTogSFRUUFJlc3VsdFR5cGUge1xuICAgIHJlc3VsdFtyZXN1bHRIZWFkZXJzXSA9IGhlYWRlcnM7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn0iXX0=
|
|
264
|
+
/* _JS_SOURCE_HASH = "3d6960a14b632f45ab1c002bb5e7c9352f6f554aa8be29835b13cad26a35b297"; */
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
3
|
+
//exports.runServerHooks = exports.runClientHooks = exports.unregisterGlobalClientHook = exports.registerGlobalClientHook = exports.unregisterGlobalHook = exports.registerGlobalHook = exports.exposeClass = exports.registerClass = exports.isDataImmutable = exports.performLocalCall = exports.shouldCompressCall = exports.getCallFlags = void 0;
|
|
4
|
+
const SocketFunction_1 = require("../SocketFunction");
|
|
5
|
+
const measure_1 = require("./profiling/measure");
|
|
6
|
+
const format_1 = require("./formatting/format");
|
|
7
|
+
const createSingleton_1 = require("./createSingleton");
|
|
8
|
+
// Shared across copies of this package, so a call routed through one copy can find a class
|
|
9
|
+
// (and its hooks) registered through another copy. See createSingleton.
|
|
10
|
+
const classes = (0, createSingleton_1.createSingleton)("callManager.classes", 1, () => ({})).get();
|
|
11
|
+
const exposedClasses = (0, createSingleton_1.createSingleton)("callManager.exposedClasses", 1, () => new Set()).get();
|
|
12
|
+
const globalHooks = (0, createSingleton_1.createSingleton)("callManager.globalHooks", 1, () => []).get();
|
|
13
|
+
const globalClientHooks = (0, createSingleton_1.createSingleton)("callManager.globalClientHooks", 1, () => []).get();
|
|
14
|
+
function getCallFlags(call) {
|
|
15
|
+
var _a;
|
|
16
|
+
return (_a = classes[call.classGuid]) === null || _a === void 0 ? void 0 : _a.shape[call.functionName];
|
|
17
|
+
}
|
|
18
|
+
exports.getCallFlags = getCallFlags;
|
|
19
|
+
function shouldCompressCall(call) {
|
|
20
|
+
var _a, _b;
|
|
21
|
+
return (_b = (_a = classes[call.classGuid]) === null || _a === void 0 ? void 0 : _a.shape[call.functionName]) === null || _b === void 0 ? void 0 : _b.compress;
|
|
22
|
+
}
|
|
23
|
+
exports.shouldCompressCall = shouldCompressCall;
|
|
24
|
+
async function performLocalCall(config) {
|
|
25
|
+
const { call, caller } = config;
|
|
26
|
+
let classDef = classes[call.classGuid];
|
|
27
|
+
if (!classDef) {
|
|
28
|
+
throw new Error(`Class ${call.classGuid} not found. Have ${Object.keys(classes).join(", ")}`);
|
|
29
|
+
}
|
|
30
|
+
if (!exposedClasses.has(call.classGuid)) {
|
|
31
|
+
throw new Error(`Class ${call.classGuid} not exposed. Call SocketFunction.expose (serverside) with this class. Exposed classes: ${Array.from(exposedClasses).join(", ")}`);
|
|
32
|
+
}
|
|
33
|
+
let controller = classDef.controller;
|
|
34
|
+
let functionShape = classDef.shape[call.functionName];
|
|
35
|
+
if (!functionShape) {
|
|
36
|
+
throw new Error(`Function ${call.functionName} not exposed in ${call.classGuid}. Add it to the 3rd argument of SocketFunction.expose.`);
|
|
37
|
+
}
|
|
38
|
+
if (!controller[call.functionName]) {
|
|
39
|
+
throw new Error(`Function ${call.functionName} does not exist`);
|
|
40
|
+
}
|
|
41
|
+
let serverContext = await (0, exports.runServerHooks)(call, caller, functionShape);
|
|
42
|
+
if ("overrideResult" in serverContext) {
|
|
43
|
+
for (let callback of serverContext.onResult) {
|
|
44
|
+
await callback(serverContext.overrideResult);
|
|
45
|
+
}
|
|
46
|
+
if ("overrideResult" in serverContext) {
|
|
47
|
+
return serverContext.overrideResult;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// NOTE: We purposely don't await inside _setSocketContext, so the context is reset synchronously
|
|
51
|
+
let result = (0, SocketFunction_1._setSocketContext)(caller, () => {
|
|
52
|
+
return controller[call.functionName](...call.args);
|
|
53
|
+
});
|
|
54
|
+
for (let callback of serverContext.onResult) {
|
|
55
|
+
await callback(result);
|
|
56
|
+
}
|
|
57
|
+
if ("overrideResult" in serverContext) {
|
|
58
|
+
return serverContext.overrideResult;
|
|
59
|
+
}
|
|
60
|
+
return await result;
|
|
61
|
+
}
|
|
62
|
+
exports.performLocalCall = performLocalCall;
|
|
63
|
+
function isDataImmutable(call) {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
return !!((_b = (_a = classes[call.classGuid]) === null || _a === void 0 ? void 0 : _a.shape[call.functionName]) === null || _b === void 0 ? void 0 : _b.dataImmutable);
|
|
66
|
+
}
|
|
67
|
+
exports.isDataImmutable = isDataImmutable;
|
|
68
|
+
function registerClass(classGuid, controller, shape, config) {
|
|
69
|
+
var _a;
|
|
70
|
+
if (!((_a = globalThis.isHotReloading) === null || _a === void 0 ? void 0 : _a.call(globalThis)) && classes[classGuid]) {
|
|
71
|
+
console.warn(`Class ${classGuid} already registered. This is normal if you are using multiple copies of socket-function at once.`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (!(config === null || config === void 0 ? void 0 : config.noFunctionMeasure)) {
|
|
75
|
+
let niceClassName = controller.constructor.name || classGuid;
|
|
76
|
+
for (let functionName of Object.keys(shape)) {
|
|
77
|
+
if (functionName === "constructor")
|
|
78
|
+
continue;
|
|
79
|
+
let fnc = controller[functionName];
|
|
80
|
+
if (typeof fnc !== "function")
|
|
81
|
+
continue;
|
|
82
|
+
controller[functionName] = (0, measure_1.measureWrap)(fnc, `${niceClassName}().${functionName}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
classes[classGuid] = {
|
|
86
|
+
controller,
|
|
87
|
+
shape,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
exports.registerClass = registerClass;
|
|
91
|
+
function exposeClass(exposedClass) {
|
|
92
|
+
exposedClasses.add(exposedClass._classGuid);
|
|
93
|
+
}
|
|
94
|
+
exports.exposeClass = exposeClass;
|
|
95
|
+
function registerGlobalHook(hook) {
|
|
96
|
+
globalHooks.push(hook);
|
|
97
|
+
}
|
|
98
|
+
exports.registerGlobalHook = registerGlobalHook;
|
|
99
|
+
function unregisterGlobalHook(hook) {
|
|
100
|
+
let index = globalHooks.indexOf(hook);
|
|
101
|
+
if (index >= 0) {
|
|
102
|
+
globalHooks.splice(index, 1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.unregisterGlobalHook = unregisterGlobalHook;
|
|
106
|
+
function registerGlobalClientHook(hook) {
|
|
107
|
+
globalClientHooks.push(hook);
|
|
108
|
+
}
|
|
109
|
+
exports.registerGlobalClientHook = registerGlobalClientHook;
|
|
110
|
+
function unregisterGlobalClientHook(hook) {
|
|
111
|
+
let index = globalClientHooks.indexOf(hook);
|
|
112
|
+
if (index >= 0) {
|
|
113
|
+
globalClientHooks.splice(index, 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.unregisterGlobalClientHook = unregisterGlobalClientHook;
|
|
117
|
+
exports.runClientHooks = (0, measure_1.measureWrap)(async function runClientHooks(callType, hooks, connectionId) {
|
|
118
|
+
var _a;
|
|
119
|
+
let context = { call: callType, connectionId, onResult: [] };
|
|
120
|
+
let clientHooks = ((_a = hooks.clientHooks) === null || _a === void 0 ? void 0 : _a.slice()) || [];
|
|
121
|
+
if (!hooks.noClientHooks) {
|
|
122
|
+
clientHooks = globalClientHooks.concat(clientHooks);
|
|
123
|
+
for (let otherClientHook of globalHooks.concat(hooks.hooks || []).map(x => x.clientHook)) {
|
|
124
|
+
if (otherClientHook) {
|
|
125
|
+
clientHooks.push(otherClientHook);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
for (let hook of clientHooks) {
|
|
130
|
+
let time = Date.now();
|
|
131
|
+
await (0, measure_1.measureBlock)(async () => {
|
|
132
|
+
await hook(context);
|
|
133
|
+
}, `clientHook|${hook.name || hook.toString().slice(0, 100)}`);
|
|
134
|
+
time = Date.now() - time;
|
|
135
|
+
if (time > 500) {
|
|
136
|
+
console.warn(`Slow (${(0, format_1.formatTime)(time)}) client hook: ${JSON.stringify(hook.name || hook.toString().slice(0, 100))} for ${callType.classGuid}.${callType.functionName}(...)`);
|
|
137
|
+
}
|
|
138
|
+
// NOTE: See ClientHookContext.overrideResult for why we break here
|
|
139
|
+
if ("overrideResult" in context) {
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return context;
|
|
144
|
+
});
|
|
145
|
+
exports.runServerHooks = (0, measure_1.measureWrap)(async function runServerHooks(callType, caller, hooks) {
|
|
146
|
+
let hookContext = { call: callType, onResult: [] };
|
|
147
|
+
for (let hook of globalHooks.concat(hooks.hooks || [])) {
|
|
148
|
+
let time = Date.now();
|
|
149
|
+
await (0, SocketFunction_1._setSocketContext)(caller, () => hook(hookContext));
|
|
150
|
+
time = Date.now() - time;
|
|
151
|
+
if (time > 500) {
|
|
152
|
+
console.warn(`Slow (${(0, format_1.formatTime)(time)}) server hook: ${JSON.stringify(hook.name || hook.toString().slice(0, 100))} for ${callType.classGuid}.${callType.functionName}(...)`);
|
|
153
|
+
}
|
|
154
|
+
// NOTE: See HookContext.overrideResult for why we don't break here
|
|
155
|
+
}
|
|
156
|
+
return hookContext;
|
|
157
|
+
});
|
|
158
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsbE1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjYWxsTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxzREFBc0Q7QUFHdEQsaURBQWdFO0FBQ2hFLGdEQUFpRDtBQUNqRCx1REFBb0Q7QUFFcEQsMkZBQTJGO0FBQzNGLHlFQUF5RTtBQUN6RSxNQUFNLE9BQU8sR0FBRyxJQUFBLGlDQUFlLEVBQUMscUJBQXFCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFLL0QsQ0FBQSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDVixNQUFNLGNBQWMsR0FBRyxJQUFBLGlDQUFlLEVBQUMsNEJBQTRCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksR0FBRyxFQUFVLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUV2RyxNQUFNLFdBQVcsR0FBRyxJQUFBLGlDQUFlLEVBQUMseUJBQXlCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQTBCLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUMxRyxNQUFNLGlCQUFpQixHQUFHLElBQUEsaUNBQWUsRUFBQywrQkFBK0IsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBZ0MsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBRTVILFNBQWdCLFlBQVksQ0FBQyxJQUFjOztJQUN2QyxPQUFPLE1BQUEsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsMENBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRkQsb0NBRUM7QUFDRCxTQUFnQixrQkFBa0IsQ0FBQyxJQUFjOztJQUM3QyxPQUFPLE1BQUEsTUFBQSxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQywwQ0FBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQywwQ0FBRSxRQUFRLENBQUM7QUFDdkUsQ0FBQztBQUZELGdEQUVDO0FBRU0sS0FBSyxVQUFVLGdCQUFnQixDQUNsQyxNQUdDO0lBRUQsTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDaEMsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUV2QyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDWixNQUFNLElBQUksS0FBSyxDQUFDLFNBQVMsSUFBSSxDQUFDLFNBQVMsb0JBQW9CLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNsRyxDQUFDO0lBRUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDdEMsTUFBTSxJQUFJLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLDJGQUEyRixLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0ssQ0FBQztJQUVELElBQUksVUFBVSxHQUFHLFFBQVEsQ0FBQyxVQUFVLENBQUM7SUFDckMsSUFBSSxhQUFhLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDdEQsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2pCLE1BQU0sSUFBSSxLQUFLLENBQUMsWUFBWSxJQUFJLENBQUMsWUFBWSxtQkFBbUIsSUFBSSxDQUFDLFNBQVMsd0RBQXdELENBQUMsQ0FBQztJQUM1SSxDQUFDO0lBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztRQUNqQyxNQUFNLElBQUksS0FBSyxDQUFDLFlBQVksSUFBSSxDQUFDLFlBQVksaUJBQWlCLENBQUMsQ0FBQztJQUNwRSxDQUFDO0lBRUQsSUFBSSxhQUFhLEdBQUcsTUFBTSxJQUFBLHNCQUFjLEVBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQztJQUN0RSxJQUFJLGdCQUFnQixJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ3BDLEtBQUssSUFBSSxRQUFRLElBQUksYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzFDLE1BQU0sUUFBUSxDQUFDLGFBQWEsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBQ0QsSUFBSSxnQkFBZ0IsSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUNwQyxPQUFPLGFBQWEsQ0FBQyxjQUFjLENBQUM7UUFDeEMsQ0FBQztJQUNMLENBQUM7SUFFRCxpR0FBaUc7SUFDakcsSUFBSSxNQUFNLEdBQUcsSUFBQSxrQ0FBaUIsRUFBQyxNQUFNLEVBQUUsR0FBRyxFQUFFO1FBQ3hDLE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2RCxDQUFDLENBQUMsQ0FBQztJQUNILEtBQUssSUFBSSxRQUFRLElBQUksYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQzFDLE1BQU0sUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRCxJQUFJLGdCQUFnQixJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ3BDLE9BQU8sYUFBYSxDQUFDLGNBQWMsQ0FBQztJQUN4QyxDQUFDO0lBQ0QsT0FBTyxNQUFNLE1BQU0sQ0FBQztBQUN4QixDQUFDO0FBakRELDRDQWlEQztBQUVELFNBQWdCLGVBQWUsQ0FBQyxJQUFjOztJQUMxQyxPQUFPLENBQUMsQ0FBQyxDQUFBLE1BQUEsTUFBQSxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQywwQ0FBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQywwQ0FBRSxhQUFhLENBQUEsQ0FBQztBQUM5RSxDQUFDO0FBRkQsMENBRUM7QUFFRCxTQUFnQixhQUFhLENBQUMsU0FBaUIsRUFBRSxVQUFrQyxFQUFFLEtBQXlCLEVBQUUsTUFFL0c7O0lBQ0csSUFBSSxDQUFDLENBQUEsTUFBQSxVQUFVLENBQUMsY0FBYywwREFBSSxDQUFBLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDdkQsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLFNBQVMsa0dBQWtHLENBQUMsQ0FBQztRQUNuSSxPQUFPO0lBQ1gsQ0FBQztJQUVELElBQUksQ0FBQyxDQUFBLE1BQU0sYUFBTixNQUFNLHVCQUFOLE1BQU0sQ0FBRSxpQkFBaUIsQ0FBQSxFQUFFLENBQUM7UUFDN0IsSUFBSSxhQUFhLEdBQUcsVUFBVSxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDO1FBQzdELEtBQUssSUFBSSxZQUFZLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFDLElBQUksWUFBWSxLQUFLLGFBQWE7Z0JBQUUsU0FBUztZQUM3QyxJQUFJLEdBQUcsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDbkMsSUFBSSxPQUFPLEdBQUcsS0FBSyxVQUFVO2dCQUFFLFNBQVM7WUFDeEMsVUFBVSxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUEscUJBQVcsRUFBQyxHQUFHLEVBQUUsR0FBRyxhQUFhLE1BQU0sWUFBWSxFQUFFLENBQUMsQ0FBQztRQUN0RixDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRztRQUNqQixVQUFVO1FBQ1YsS0FBSztLQUNSLENBQUM7QUFDTixDQUFDO0FBckJELHNDQXFCQztBQUVELFNBQWdCLFdBQVcsQ0FBQyxZQUE4QjtJQUN0RCxjQUFjLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUNoRCxDQUFDO0FBRkQsa0NBRUM7QUFFRCxTQUFnQixrQkFBa0IsQ0FBQyxJQUF3QjtJQUN2RCxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzNCLENBQUM7QUFGRCxnREFFQztBQUNELFNBQWdCLG9CQUFvQixDQUFDLElBQXdCO0lBQ3pELElBQUksS0FBSyxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEMsSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDYixXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqQyxDQUFDO0FBQ0wsQ0FBQztBQUxELG9EQUtDO0FBQ0QsU0FBZ0Isd0JBQXdCLENBQUMsSUFBOEI7SUFDbkUsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ2pDLENBQUM7QUFGRCw0REFFQztBQUNELFNBQWdCLDBCQUEwQixDQUFDLElBQThCO0lBQ3JFLElBQUksS0FBSyxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QyxJQUFJLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUNiLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQztBQUNMLENBQUM7QUFMRCxnRUFLQztBQUVZLFFBQUEsY0FBYyxHQUFHLElBQUEscUJBQVcsRUFBQyxLQUFLLFVBQVUsY0FBYyxDQUNuRSxRQUFzQixFQUN0QixLQUFpRCxFQUNqRCxZQUFnQzs7SUFFaEMsSUFBSSxPQUFPLEdBQXNCLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBRWhGLElBQUksV0FBVyxHQUFHLENBQUEsTUFBQSxLQUFLLENBQUMsV0FBVywwQ0FBRSxLQUFLLEVBQUUsS0FBSSxFQUFFLENBQUM7SUFDbkQsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUN2QixXQUFXLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3BELEtBQUssSUFBSSxlQUFlLElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ3ZGLElBQUksZUFBZSxFQUFFLENBQUM7Z0JBQ2xCLFdBQVcsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDdEMsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBQ0QsS0FBSyxJQUFJLElBQUksSUFBSSxXQUFXLEVBQUUsQ0FBQztRQUMzQixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEIsTUFBTSxJQUFBLHNCQUFZLEVBQUMsS0FBSyxJQUFJLEVBQUU7WUFDMUIsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDeEIsQ0FBQyxFQUFFLGNBQWMsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDL0QsSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDekIsSUFBSSxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7WUFDYixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBQSxtQkFBVSxFQUFDLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLFFBQVEsUUFBUSxDQUFDLFNBQVMsSUFBSSxRQUFRLENBQUMsWUFBWSxPQUFPLENBQUMsQ0FBQztRQUNsTCxDQUFDO1FBQ0QsbUVBQW1FO1FBQ25FLElBQUksZ0JBQWdCLElBQUksT0FBTyxFQUFFLENBQUM7WUFDOUIsTUFBTTtRQUNWLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTyxPQUFPLENBQUM7QUFDbkIsQ0FBQyxDQUFDLENBQUM7QUFFVSxRQUFBLGNBQWMsR0FBRyxJQUFBLHFCQUFXLEVBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDbkUsUUFBc0IsRUFDdEIsTUFBcUIsRUFDckIsS0FBaUQ7SUFFakQsSUFBSSxXQUFXLEdBQWdCLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDaEUsS0FBSyxJQUFJLElBQUksSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNyRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEIsTUFBTSxJQUFBLGtDQUFpQixFQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUN6RCxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFBLG1CQUFVLEVBQUMsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxRQUFRLENBQUMsU0FBUyxJQUFJLFFBQVEsQ0FBQyxZQUFZLE9BQU8sQ0FBQyxDQUFDO1FBQ2xMLENBQUM7UUFDRCxtRUFBbUU7SUFDdkUsQ0FBQztJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3ZCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uL2hvdC9Ib3RSZWxvYWRDb250cm9sbGVyLnRzXCIgLz5cbmltcG9ydCB7IENhbGxlckNvbnRleHQsIENhbGxUeXBlLCBDbGllbnRIb29rQ29udGV4dCwgRnVsbENhbGxUeXBlLCBGdW5jdGlvbkZsYWdzLCBIb29rQ29udGV4dCwgU29ja2V0RXhwb3NlZEludGVyZmFjZSwgU29ja2V0RXhwb3NlZEludGVyZmFjZUNsYXNzLCBTb2NrZXRFeHBvc2VkU2hhcGUsIFNvY2tldEZ1bmN0aW9uQ2xpZW50SG9vaywgU29ja2V0RnVuY3Rpb25Ib29rLCBTb2NrZXRSZWdpc3RlcmVkIH0gZnJvbSBcIi4uL1NvY2tldEZ1bmN0aW9uVHlwZXNcIjtcbmltcG9ydCB7IF9zZXRTb2NrZXRDb250ZXh0IH0gZnJvbSBcIi4uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyBlbnRyaWVzLCBpc05vZGUgfSBmcm9tIFwiLi9taXNjXCI7XG5pbXBvcnQgZGVidWdicmVhayBmcm9tIFwiZGVidWdicmVha1wiO1xuaW1wb3J0IHsgbWVhc3VyZUJsb2NrLCBtZWFzdXJlV3JhcCB9IGZyb20gXCIuL3Byb2ZpbGluZy9tZWFzdXJlXCI7XG5pbXBvcnQgeyBmb3JtYXRUaW1lIH0gZnJvbSBcIi4vZm9ybWF0dGluZy9mb3JtYXRcIjtcbmltcG9ydCB7IGNyZWF0ZVNpbmdsZXRvbiB9IGZyb20gXCIuL2NyZWF0ZVNpbmdsZXRvblwiO1xuXG4vLyBTaGFyZWQgYWNyb3NzIGNvcGllcyBvZiB0aGlzIHBhY2thZ2UsIHNvIGEgY2FsbCByb3V0ZWQgdGhyb3VnaCBvbmUgY29weSBjYW4gZmluZCBhIGNsYXNzXG4vLyAgKGFuZCBpdHMgaG9va3MpIHJlZ2lzdGVyZWQgdGhyb3VnaCBhbm90aGVyIGNvcHkuIFNlZSBjcmVhdGVTaW5nbGV0b24uXG5jb25zdCBjbGFzc2VzID0gY3JlYXRlU2luZ2xldG9uKFwiY2FsbE1hbmFnZXIuY2xhc3Nlc1wiLCAxLCAoKSA9PiAoe30gYXMge1xuICAgIFtjbGFzc0d1aWQ6IHN0cmluZ106IHtcbiAgICAgICAgY29udHJvbGxlcjogU29ja2V0RXhwb3NlZEludGVyZmFjZTtcbiAgICAgICAgc2hhcGU6IFNvY2tldEV4cG9zZWRTaGFwZTtcbiAgICB9XG59KSkuZ2V0KCk7XG5jb25zdCBleHBvc2VkQ2xhc3NlcyA9IGNyZWF0ZVNpbmdsZXRvbihcImNhbGxNYW5hZ2VyLmV4cG9zZWRDbGFzc2VzXCIsIDEsICgpID0+IG5ldyBTZXQ8c3RyaW5nPigpKS5nZXQoKTtcblxuY29uc3QgZ2xvYmFsSG9va3MgPSBjcmVhdGVTaW5nbGV0b24oXCJjYWxsTWFuYWdlci5nbG9iYWxIb29rc1wiLCAxLCAoKSA9PiBbXSBhcyBTb2NrZXRGdW5jdGlvbkhvb2tbXSkuZ2V0KCk7XG5jb25zdCBnbG9iYWxDbGllbnRIb29rcyA9IGNyZWF0ZVNpbmdsZXRvbihcImNhbGxNYW5hZ2VyLmdsb2JhbENsaWVudEhvb2tzXCIsIDEsICgpID0+IFtdIGFzIFNvY2tldEZ1bmN0aW9uQ2xpZW50SG9va1tdKS5nZXQoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENhbGxGbGFncyhjYWxsOiBDYWxsVHlwZSk6IEZ1bmN0aW9uRmxhZ3MgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBjbGFzc2VzW2NhbGwuY2xhc3NHdWlkXT8uc2hhcGVbY2FsbC5mdW5jdGlvbk5hbWVdO1xufVxuZXhwb3J0IGZ1bmN0aW9uIHNob3VsZENvbXByZXNzQ2FsbChjYWxsOiBDYWxsVHlwZSkge1xuICAgIHJldHVybiBjbGFzc2VzW2NhbGwuY2xhc3NHdWlkXT8uc2hhcGVbY2FsbC5mdW5jdGlvbk5hbWVdPy5jb21wcmVzcztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHBlcmZvcm1Mb2NhbENhbGwoXG4gICAgY29uZmlnOiB7XG4gICAgICAgIGNhbGw6IEZ1bGxDYWxsVHlwZTtcbiAgICAgICAgY2FsbGVyOiBDYWxsZXJDb250ZXh0O1xuICAgIH1cbik6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IHsgY2FsbCwgY2FsbGVyIH0gPSBjb25maWc7XG4gICAgbGV0IGNsYXNzRGVmID0gY2xhc3Nlc1tjYWxsLmNsYXNzR3VpZF07XG5cbiAgICBpZiAoIWNsYXNzRGVmKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2xhc3MgJHtjYWxsLmNsYXNzR3VpZH0gbm90IGZvdW5kLiBIYXZlICR7T2JqZWN0LmtleXMoY2xhc3Nlcykuam9pbihcIiwgXCIpfWApO1xuICAgIH1cblxuICAgIGlmICghZXhwb3NlZENsYXNzZXMuaGFzKGNhbGwuY2xhc3NHdWlkKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENsYXNzICR7Y2FsbC5jbGFzc0d1aWR9IG5vdCBleHBvc2VkLiBDYWxsIFNvY2tldEZ1bmN0aW9uLmV4cG9zZSAoc2VydmVyc2lkZSkgd2l0aCB0aGlzIGNsYXNzLiBFeHBvc2VkIGNsYXNzZXM6ICR7QXJyYXkuZnJvbShleHBvc2VkQ2xhc3Nlcykuam9pbihcIiwgXCIpfWApO1xuICAgIH1cblxuICAgIGxldCBjb250cm9sbGVyID0gY2xhc3NEZWYuY29udHJvbGxlcjtcbiAgICBsZXQgZnVuY3Rpb25TaGFwZSA9IGNsYXNzRGVmLnNoYXBlW2NhbGwuZnVuY3Rpb25OYW1lXTtcbiAgICBpZiAoIWZ1bmN0aW9uU2hhcGUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGdW5jdGlvbiAke2NhbGwuZnVuY3Rpb25OYW1lfSBub3QgZXhwb3NlZCBpbiAke2NhbGwuY2xhc3NHdWlkfS4gQWRkIGl0IHRvIHRoZSAzcmQgYXJndW1lbnQgb2YgU29ja2V0RnVuY3Rpb24uZXhwb3NlLmApO1xuICAgIH1cblxuICAgIGlmICghY29udHJvbGxlcltjYWxsLmZ1bmN0aW9uTmFtZV0pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGdW5jdGlvbiAke2NhbGwuZnVuY3Rpb25OYW1lfSBkb2VzIG5vdCBleGlzdGApO1xuICAgIH1cblxuICAgIGxldCBzZXJ2ZXJDb250ZXh0ID0gYXdhaXQgcnVuU2VydmVySG9va3MoY2FsbCwgY2FsbGVyLCBmdW5jdGlvblNoYXBlKTtcbiAgICBpZiAoXCJvdmVycmlkZVJlc3VsdFwiIGluIHNlcnZlckNvbnRleHQpIHtcbiAgICAgICAgZm9yIChsZXQgY2FsbGJhY2sgb2Ygc2VydmVyQ29udGV4dC5vblJlc3VsdCkge1xuICAgICAgICAgICAgYXdhaXQgY2FsbGJhY2soc2VydmVyQ29udGV4dC5vdmVycmlkZVJlc3VsdCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFwib3ZlcnJpZGVSZXN1bHRcIiBpbiBzZXJ2ZXJDb250ZXh0KSB7XG4gICAgICAgICAgICByZXR1cm4gc2VydmVyQ29udGV4dC5vdmVycmlkZVJlc3VsdDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIE5PVEU6IFdlIHB1cnBvc2VseSBkb24ndCBhd2FpdCBpbnNpZGUgX3NldFNvY2tldENvbnRleHQsIHNvIHRoZSBjb250ZXh0IGlzIHJlc2V0IHN5bmNocm9ub3VzbHlcbiAgICBsZXQgcmVzdWx0ID0gX3NldFNvY2tldENvbnRleHQoY2FsbGVyLCAoKSA9PiB7XG4gICAgICAgIHJldHVybiBjb250cm9sbGVyW2NhbGwuZnVuY3Rpb25OYW1lXSguLi5jYWxsLmFyZ3MpO1xuICAgIH0pO1xuICAgIGZvciAobGV0IGNhbGxiYWNrIG9mIHNlcnZlckNvbnRleHQub25SZXN1bHQpIHtcbiAgICAgICAgYXdhaXQgY2FsbGJhY2socmVzdWx0KTtcbiAgICB9XG5cbiAgICBpZiAoXCJvdmVycmlkZVJlc3VsdFwiIGluIHNlcnZlckNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIHNlcnZlckNvbnRleHQub3ZlcnJpZGVSZXN1bHQ7XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCByZXN1bHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGFJbW11dGFibGUoY2FsbDogQ2FsbFR5cGUpIHtcbiAgICByZXR1cm4gISFjbGFzc2VzW2NhbGwuY2xhc3NHdWlkXT8uc2hhcGVbY2FsbC5mdW5jdGlvbk5hbWVdPy5kYXRhSW1tdXRhYmxlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJDbGFzcyhjbGFzc0d1aWQ6IHN0cmluZywgY29udHJvbGxlcjogU29ja2V0RXhwb3NlZEludGVyZmFjZSwgc2hhcGU6IFNvY2tldEV4cG9zZWRTaGFwZSwgY29uZmlnPzoge1xuICAgIG5vRnVuY3Rpb25NZWFzdXJlPzogYm9vbGVhbjtcbn0pIHtcbiAgICBpZiAoIWdsb2JhbFRoaXMuaXNIb3RSZWxvYWRpbmc/LigpICYmIGNsYXNzZXNbY2xhc3NHdWlkXSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYENsYXNzICR7Y2xhc3NHdWlkfSBhbHJlYWR5IHJlZ2lzdGVyZWQuIFRoaXMgaXMgbm9ybWFsIGlmIHlvdSBhcmUgdXNpbmcgbXVsdGlwbGUgY29waWVzIG9mIHNvY2tldC1mdW5jdGlvbiBhdCBvbmNlLmApO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjb25maWc/Lm5vRnVuY3Rpb25NZWFzdXJlKSB7XG4gICAgICAgIGxldCBuaWNlQ2xhc3NOYW1lID0gY29udHJvbGxlci5jb25zdHJ1Y3Rvci5uYW1lIHx8IGNsYXNzR3VpZDtcbiAgICAgICAgZm9yIChsZXQgZnVuY3Rpb25OYW1lIG9mIE9iamVjdC5rZXlzKHNoYXBlKSkge1xuICAgICAgICAgICAgaWYgKGZ1bmN0aW9uTmFtZSA9PT0gXCJjb25zdHJ1Y3RvclwiKSBjb250aW51ZTtcbiAgICAgICAgICAgIGxldCBmbmMgPSBjb250cm9sbGVyW2Z1bmN0aW9uTmFtZV07XG4gICAgICAgICAgICBpZiAodHlwZW9mIGZuYyAhPT0gXCJmdW5jdGlvblwiKSBjb250aW51ZTtcbiAgICAgICAgICAgIGNvbnRyb2xsZXJbZnVuY3Rpb25OYW1lXSA9IG1lYXN1cmVXcmFwKGZuYywgYCR7bmljZUNsYXNzTmFtZX0oKS4ke2Z1bmN0aW9uTmFtZX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjbGFzc2VzW2NsYXNzR3VpZF0gPSB7XG4gICAgICAgIGNvbnRyb2xsZXIsXG4gICAgICAgIHNoYXBlLFxuICAgIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBleHBvc2VDbGFzcyhleHBvc2VkQ2xhc3M6IFNvY2tldFJlZ2lzdGVyZWQpIHtcbiAgICBleHBvc2VkQ2xhc3Nlcy5hZGQoZXhwb3NlZENsYXNzLl9jbGFzc0d1aWQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJHbG9iYWxIb29rKGhvb2s6IFNvY2tldEZ1bmN0aW9uSG9vaykge1xuICAgIGdsb2JhbEhvb2tzLnB1c2goaG9vayk7XG59XG5leHBvcnQgZnVuY3Rpb24gdW5yZWdpc3Rlckdsb2JhbEhvb2soaG9vazogU29ja2V0RnVuY3Rpb25Ib29rKSB7XG4gICAgbGV0IGluZGV4ID0gZ2xvYmFsSG9va3MuaW5kZXhPZihob29rKTtcbiAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICBnbG9iYWxIb29rcy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIH1cbn1cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlckdsb2JhbENsaWVudEhvb2soaG9vazogU29ja2V0RnVuY3Rpb25DbGllbnRIb29rKSB7XG4gICAgZ2xvYmFsQ2xpZW50SG9va3MucHVzaChob29rKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB1bnJlZ2lzdGVyR2xvYmFsQ2xpZW50SG9vayhob29rOiBTb2NrZXRGdW5jdGlvbkNsaWVudEhvb2spIHtcbiAgICBsZXQgaW5kZXggPSBnbG9iYWxDbGllbnRIb29rcy5pbmRleE9mKGhvb2spO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgIGdsb2JhbENsaWVudEhvb2tzLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxufVxuXG5leHBvcnQgY29uc3QgcnVuQ2xpZW50SG9va3MgPSBtZWFzdXJlV3JhcChhc3luYyBmdW5jdGlvbiBydW5DbGllbnRIb29rcyhcbiAgICBjYWxsVHlwZTogRnVsbENhbGxUeXBlLFxuICAgIGhvb2tzOiBFeGNsdWRlPFNvY2tldEV4cG9zZWRTaGFwZVtcIlwiXSwgdW5kZWZpbmVkPixcbiAgICBjb25uZWN0aW9uSWQ6IHsgbm9kZUlkOiBzdHJpbmcgfSxcbik6IFByb21pc2U8Q2xpZW50SG9va0NvbnRleHQ+IHtcbiAgICBsZXQgY29udGV4dDogQ2xpZW50SG9va0NvbnRleHQgPSB7IGNhbGw6IGNhbGxUeXBlLCBjb25uZWN0aW9uSWQsIG9uUmVzdWx0OiBbXSB9O1xuXG4gICAgbGV0IGNsaWVudEhvb2tzID0gaG9va3MuY2xpZW50SG9va3M/LnNsaWNlKCkgfHwgW107XG4gICAgaWYgKCFob29rcy5ub0NsaWVudEhvb2tzKSB7XG4gICAgICAgIGNsaWVudEhvb2tzID0gZ2xvYmFsQ2xpZW50SG9va3MuY29uY2F0KGNsaWVudEhvb2tzKTtcbiAgICAgICAgZm9yIChsZXQgb3RoZXJDbGllbnRIb29rIG9mIGdsb2JhbEhvb2tzLmNvbmNhdChob29rcy5ob29rcyB8fCBbXSkubWFwKHggPT4geC5jbGllbnRIb29rKSkge1xuICAgICAgICAgICAgaWYgKG90aGVyQ2xpZW50SG9vaykge1xuICAgICAgICAgICAgICAgIGNsaWVudEhvb2tzLnB1c2gob3RoZXJDbGllbnRIb29rKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCBob29rIG9mIGNsaWVudEhvb2tzKSB7XG4gICAgICAgIGxldCB0aW1lID0gRGF0ZS5ub3coKTtcbiAgICAgICAgYXdhaXQgbWVhc3VyZUJsb2NrKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IGhvb2soY29udGV4dCk7XG4gICAgICAgIH0sIGBjbGllbnRIb29rfCR7aG9vay5uYW1lIHx8IGhvb2sudG9TdHJpbmcoKS5zbGljZSgwLCAxMDApfWApO1xuICAgICAgICB0aW1lID0gRGF0ZS5ub3coKSAtIHRpbWU7XG4gICAgICAgIGlmICh0aW1lID4gNTAwKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFNsb3cgKCR7Zm9ybWF0VGltZSh0aW1lKX0pIGNsaWVudCBob29rOiAke0pTT04uc3RyaW5naWZ5KGhvb2submFtZSB8fCBob29rLnRvU3RyaW5nKCkuc2xpY2UoMCwgMTAwKSl9IGZvciAke2NhbGxUeXBlLmNsYXNzR3VpZH0uJHtjYWxsVHlwZS5mdW5jdGlvbk5hbWV9KC4uLilgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBOT1RFOiBTZWUgQ2xpZW50SG9va0NvbnRleHQub3ZlcnJpZGVSZXN1bHQgZm9yIHdoeSB3ZSBicmVhayBoZXJlXG4gICAgICAgIGlmIChcIm92ZXJyaWRlUmVzdWx0XCIgaW4gY29udGV4dCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29udGV4dDtcbn0pO1xuXG5leHBvcnQgY29uc3QgcnVuU2VydmVySG9va3MgPSBtZWFzdXJlV3JhcChhc3luYyBmdW5jdGlvbiBydW5TZXJ2ZXJIb29rcyhcbiAgICBjYWxsVHlwZTogRnVsbENhbGxUeXBlLFxuICAgIGNhbGxlcjogQ2FsbGVyQ29udGV4dCxcbiAgICBob29rczogRXhjbHVkZTxTb2NrZXRFeHBvc2VkU2hhcGVbXCJcIl0sIHVuZGVmaW5lZD4sXG4pOiBQcm9taXNlPEhvb2tDb250ZXh0PiB7XG4gICAgbGV0IGhvb2tDb250ZXh0OiBIb29rQ29udGV4dCA9IHsgY2FsbDogY2FsbFR5cGUsIG9uUmVzdWx0OiBbXSB9O1xuICAgIGZvciAobGV0IGhvb2sgb2YgZ2xvYmFsSG9va3MuY29uY2F0KGhvb2tzLmhvb2tzIHx8IFtdKSkge1xuICAgICAgICBsZXQgdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgIGF3YWl0IF9zZXRTb2NrZXRDb250ZXh0KGNhbGxlciwgKCkgPT4gaG9vayhob29rQ29udGV4dCkpO1xuICAgICAgICB0aW1lID0gRGF0ZS5ub3coKSAtIHRpbWU7XG4gICAgICAgIGlmICh0aW1lID4gNTAwKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFNsb3cgKCR7Zm9ybWF0VGltZSh0aW1lKX0pIHNlcnZlciBob29rOiAke0pTT04uc3RyaW5naWZ5KGhvb2submFtZSB8fCBob29rLnRvU3RyaW5nKCkuc2xpY2UoMCwgMTAwKSl9IGZvciAke2NhbGxUeXBlLmNsYXNzR3VpZH0uJHtjYWxsVHlwZS5mdW5jdGlvbk5hbWV9KC4uLilgKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBOT1RFOiBTZWUgSG9va0NvbnRleHQub3ZlcnJpZGVSZXN1bHQgZm9yIHdoeSB3ZSBkb24ndCBicmVhayBoZXJlXG4gICAgfVxuICAgIHJldHVybiBob29rQ29udGV4dDtcbn0pOyJdfQ==
|
|
159
|
+
/* _JS_SOURCE_HASH = "0287d257bb18707524dbc4504587f3bd6edeec3a80e538b9f5824a795c92c51e"; */
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
|
|
26
|
+
exports.watchTrustedCertificates = exports.getTrustedCertificates = exports.trustCertificate = void 0;
|
|
27
|
+
const tls = __importStar(require("tls"));
|
|
28
|
+
const misc_1 = require("./misc");
|
|
29
|
+
let trustedCerts = new Set();
|
|
30
|
+
let watchCallbacks = new Set();
|
|
31
|
+
/** Must be populated before the server starts */
|
|
32
|
+
function trustCertificate(cert) {
|
|
33
|
+
cert = cert.toString();
|
|
34
|
+
if (trustedCerts.has(cert))
|
|
35
|
+
return;
|
|
36
|
+
trustedCerts.add(cert);
|
|
37
|
+
let certs = getTrustedCertificates();
|
|
38
|
+
for (let callback of watchCallbacks) {
|
|
39
|
+
callback(certs);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.trustCertificate = trustCertificate;
|
|
43
|
+
function getTrustedCertificates() {
|
|
44
|
+
let certs = [];
|
|
45
|
+
if ((0, misc_1.isNode)()) {
|
|
46
|
+
certs.push(...tls.rootCertificates);
|
|
47
|
+
}
|
|
48
|
+
certs.push(...Array.from(trustedCerts));
|
|
49
|
+
return certs;
|
|
50
|
+
}
|
|
51
|
+
exports.getTrustedCertificates = getTrustedCertificates;
|
|
52
|
+
function watchTrustedCertificates(callback) {
|
|
53
|
+
watchCallbacks.add(callback);
|
|
54
|
+
callback(getTrustedCertificates());
|
|
55
|
+
return () => watchCallbacks.delete(callback);
|
|
56
|
+
}
|
|
57
|
+
exports.watchTrustedCertificates = watchTrustedCertificates;
|
|
58
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydFN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2VydFN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEseUNBQTJCO0FBQzNCLGlDQUE0QztBQUU1QyxJQUFJLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0FBQ3JDLElBQUksY0FBYyxHQUFHLElBQUksR0FBRyxFQUE2QixDQUFDO0FBRTFELGlEQUFpRDtBQUNqRCxTQUFnQixnQkFBZ0IsQ0FBQyxJQUFxQjtJQUNsRCxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3ZCLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFBRSxPQUFPO0lBQ25DLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkIsSUFBSSxLQUFLLEdBQUcsc0JBQXNCLEVBQUUsQ0FBQztJQUNyQyxLQUFLLElBQUksUUFBUSxJQUFJLGNBQWMsRUFBRSxDQUFDO1FBQ2xDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwQixDQUFDO0FBQ0wsQ0FBQztBQVJELDRDQVFDO0FBQ0QsU0FBZ0Isc0JBQXNCO0lBQ2xDLElBQUksS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUN6QixJQUFJLElBQUEsYUFBTSxHQUFFLEVBQUUsQ0FBQztRQUNYLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUN4QyxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDO0FBUEQsd0RBT0M7QUFFRCxTQUFnQix3QkFBd0IsQ0FBQyxRQUFtQztJQUN4RSxjQUFjLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQzdCLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxDQUFDLENBQUM7SUFDbkMsT0FBTyxHQUFHLEVBQUUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQ2pELENBQUM7QUFKRCw0REFJQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHRscyBmcm9tIFwidGxzXCI7XG5pbXBvcnQgeyBpc05vZGUsIHNoYTI1Nkhhc2ggfSBmcm9tIFwiLi9taXNjXCI7XG5cbmxldCB0cnVzdGVkQ2VydHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbmxldCB3YXRjaENhbGxiYWNrcyA9IG5ldyBTZXQ8KGNlcnRzOiBzdHJpbmdbXSkgPT4gdm9pZD4oKTtcblxuLyoqIE11c3QgYmUgcG9wdWxhdGVkIGJlZm9yZSB0aGUgc2VydmVyIHN0YXJ0cyAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRydXN0Q2VydGlmaWNhdGUoY2VydDogc3RyaW5nIHwgQnVmZmVyKSB7XG4gICAgY2VydCA9IGNlcnQudG9TdHJpbmcoKTtcbiAgICBpZiAodHJ1c3RlZENlcnRzLmhhcyhjZXJ0KSkgcmV0dXJuO1xuICAgIHRydXN0ZWRDZXJ0cy5hZGQoY2VydCk7XG4gICAgbGV0IGNlcnRzID0gZ2V0VHJ1c3RlZENlcnRpZmljYXRlcygpO1xuICAgIGZvciAobGV0IGNhbGxiYWNrIG9mIHdhdGNoQ2FsbGJhY2tzKSB7XG4gICAgICAgIGNhbGxiYWNrKGNlcnRzKTtcbiAgICB9XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0VHJ1c3RlZENlcnRpZmljYXRlcygpOiBzdHJpbmdbXSB7XG4gICAgbGV0IGNlcnRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChpc05vZGUoKSkge1xuICAgICAgICBjZXJ0cy5wdXNoKC4uLnRscy5yb290Q2VydGlmaWNhdGVzKTtcbiAgICB9XG4gICAgY2VydHMucHVzaCguLi5BcnJheS5mcm9tKHRydXN0ZWRDZXJ0cykpO1xuICAgIHJldHVybiBjZXJ0cztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHdhdGNoVHJ1c3RlZENlcnRpZmljYXRlcyhjYWxsYmFjazogKGNlcnRzOiBzdHJpbmdbXSkgPT4gdm9pZCkge1xuICAgIHdhdGNoQ2FsbGJhY2tzLmFkZChjYWxsYmFjayk7XG4gICAgY2FsbGJhY2soZ2V0VHJ1c3RlZENlcnRpZmljYXRlcygpKTtcbiAgICByZXR1cm4gKCkgPT4gd2F0Y2hDYWxsYmFja3MuZGVsZXRlKGNhbGxiYWNrKTtcbn0iXX0=
|
|
59
|
+
/* _JS_SOURCE_HASH = "4d43b17493f838041477a97682e019b4468e7e00fd98aeb9f8685feef8bdcaa1"; */
|