socket-function 1.1.49 → 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.
Files changed (45) hide show
  1. package/dist/SetProcessVariables.ts.cache +9 -0
  2. package/dist/SocketFunction.ts.cache +467 -0
  3. package/hot/dist/HotReloadController.ts.cache +252 -0
  4. package/index.d.ts +1 -16
  5. package/package.json +1 -1
  6. package/require/dist/RequireController.ts.cache +386 -0
  7. package/require/dist/compileFlags.ts.cache +41 -0
  8. package/require/dist/extMapper.ts.cache +368 -0
  9. package/require/dist/require.ts.cache +676 -0
  10. package/src/JSONLACKS/dist/JSONLACKS.ts.cache +469 -0
  11. package/src/dist/CallFactory.ts.cache +930 -0
  12. package/src/dist/Zip.ts.cache +156 -0
  13. package/src/dist/batching.ts.cache +377 -0
  14. package/src/dist/bits.ts.cache +121 -0
  15. package/src/dist/buffers.ts.cache +76 -0
  16. package/src/dist/caching.ts.cache +302 -0
  17. package/src/dist/callHTTPHandler.ts.cache +264 -0
  18. package/src/dist/callManager.ts.cache +159 -0
  19. package/src/dist/certStore.ts.cache +59 -0
  20. package/src/dist/createSingleton.ts.cache +62 -0
  21. package/src/dist/fixLargeNetworkCalls.ts.cache +17 -0
  22. package/src/dist/forwardPort.ts.cache +222 -0
  23. package/src/dist/https.ts.cache +141 -0
  24. package/src/dist/misc.ts.cache +499 -0
  25. package/src/dist/nodeCache.ts.cache +136 -0
  26. package/src/dist/nodeProxy.ts.cache +57 -0
  27. package/src/dist/protocolNegotiation.ts.cache +101 -0
  28. package/src/dist/tlsParsing.ts.cache +85 -0
  29. package/src/dist/types.ts.cache +9 -0
  30. package/src/dist/webSocketServer.ts.cache +365 -0
  31. package/src/dist/websocketFactory.ts.cache +53 -0
  32. package/src/formatting/dist/colors.ts.cache +98 -0
  33. package/src/formatting/dist/format.ts.cache +396 -0
  34. package/src/formatting/dist/logColors.ts.cache +28 -0
  35. package/src/lz4/dist/LZ4.ts.cache +53 -0
  36. package/src/profiling/dist/getOwnTime.ts.cache +100 -0
  37. package/src/profiling/dist/measure.ts.cache +338 -0
  38. package/src/profiling/dist/stats.ts.cache +202 -0
  39. package/src/profiling/dist/statsFormat.ts.cache +45 -0
  40. package/src/profiling/getOwnTime.ts +7 -1
  41. package/src/profiling/measure.ts +25 -16
  42. package/test.ts +11 -5
  43. package/time/dist/trueTimeShim.ts.cache +656 -0
  44. package/time/trueTimeShim.d.ts +1 -16
  45. package/time/trueTimeShim.ts +7 -43
@@ -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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsbEhUVFBIYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2FsbEhUVFBIYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUdBLCtDQUFrRTtBQUNsRSxzREFBbUQ7QUFFbkQsZ0RBQXdCO0FBQ3hCLGlDQUF5RTtBQUN6RSwyQ0FBeUQ7QUFDekQsdURBQW9EO0FBRXBELGlHQUFpRztBQUNqRyw0REFBNEQ7QUFDNUQsTUFBTSxlQUFlLEdBQUcsSUFBQSxpQ0FBZSxFQUFDLGlDQUFpQyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLFNBQWlDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFFbkksU0FBZ0Isa0JBQWtCLENBQUMsSUFBYztJQUM3QyxlQUFlLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN0QyxDQUFDO0FBRkQsZ0RBRUM7QUFFRCxTQUFnQiw0QkFBNEIsQ0FBQyxPQUE2QjtJQUN0RSxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztJQUNoQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUNELElBQUksSUFBSSxHQUFHLEdBQUcsQ0FBQztJQUNmLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3JCLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDM0IsSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUNELE9BQU87UUFDSCxPQUFPLEVBQUUsSUFBSTtRQUNiLHFGQUFxRjtRQUNyRixtREFBbUQ7UUFDbkQsSUFB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Q0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDMUQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUUsQ0FBQztZQUFTLENBQUM7UUFDUCxRQUFRLENBQUMsR0FBRyxFQUFFLENBQUM7SUFDbkIsQ0FBQztBQUNMLENBQUM7QUFoTkQsMENBZ05DO0FBR0QsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRzlDLFNBQWdCLG9CQUFvQixDQUNoQyxNQUFzQixFQUN0QixPQUFxQztJQUVyQyxNQUFNLENBQUMsYUFBYSxDQUFDLEdBQUcsT0FBTyxDQUFDO0lBQ2hDLE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFORCxvREFNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBodHRwIGZyb20gXCJodHRwXCI7XG5pbXBvcnQgdGxzIGZyb20gXCJ0bHNcIjtcbmltcG9ydCB7IENhbGxlckNvbnRleHQsIENhbGxUeXBlLCBGdWxsQ2FsbFR5cGUgfSBmcm9tIFwiLi4vU29ja2V0RnVuY3Rpb25UeXBlc1wiO1xuaW1wb3J0IHsgaXNEYXRhSW1tdXRhYmxlLCBwZXJmb3JtTG9jYWxDYWxsIH0gZnJvbSBcIi4vY2FsbE1hbmFnZXJcIjtcbmltcG9ydCB7IFNvY2tldEZ1bmN0aW9uIH0gZnJvbSBcIi4uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyBnemlwIH0gZnJvbSBcInpsaWJcIjtcbmltcG9ydCB6bGliIGZyb20gXCJ6bGliXCI7XG5pbXBvcnQgeyBmb3JtYXROdW1iZXJTdWZmaXhlZCwgZ2V0Um9vdERvbWFpbiwgc2hhMjU2SGFzaCB9IGZyb20gXCIuL21pc2NcIjtcbmltcG9ydCB7IGdldENsaWVudE5vZGVJZCwgZ2V0Tm9kZUlkIH0gZnJvbSBcIi4vbm9kZUNhY2hlXCI7XG5pbXBvcnQgeyBjcmVhdGVTaW5nbGV0b24gfSBmcm9tIFwiLi9jcmVhdGVTaW5nbGV0b25cIjtcblxuLy8gU2hhcmVkIGFjcm9zcyBjb3BpZXMgb2YgdGhpcyBwYWNrYWdlLCBzbyB0aGUgZGVmYXVsdCBIVFRQIGNhbGwgc2V0IHRocm91Z2ggb25lIGNvcHkgaXMgdXNlZCBieVxuLy8gIHRoZSBIVFRQIGhhbmRsZXIgb2YgYW55IG90aGVyIGNvcHkuIFNlZSBjcmVhdGVTaW5nbGV0b24uXG5jb25zdCBkZWZhdWx0SFRUUENhbGwgPSBjcmVhdGVTaW5nbGV0b24oXCJjYWxsSFRUUEhhbmRsZXIuZGVmYXVsdEhUVFBDYWxsXCIsIDEsICgpID0+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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsbE1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjYWxsTWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxzREFBc0Q7QUFHdEQsaURBQWdFO0FBQ2hFLGdEQUFpRDtBQUNqRCx1REFBb0Q7QUFFcEQsMkZBQTJGO0FBQzNGLHlFQUF5RTtBQUN6RSxNQUFNLE9BQU8sR0FBRyxJQUFBLGlDQUFlLEVBQUMscUJBQXFCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFLL0QsQ0FBQSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDVixNQUFNLGNBQWMsR0FBRyxJQUFBLGlDQUFlLEVBQUMsNEJBQTRCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksR0FBRyxFQUFVLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUV2RyxNQUFNLFdBQVcsR0FBRyxJQUFBLGlDQUFlLEVBQUMseUJBQXlCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQTBCLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUMxRyxNQUFNLGlCQUFpQixHQUFHLElBQUEsaUNBQWUsRUFBQywrQkFBK0IsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBZ0MsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBRTVILFNBQWdCLFlBQVksQ0FBQyxJQUFjOztJQUN2QyxPQUFPLE1BQUEsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsMENBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRkQsb0NBRUM7QUFDRCxTQUFnQixrQkFBa0IsQ0FBQyxJQUFjOztJQUM3QyxPQUFPLE1BQUEsTUFBQSxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQywwQ0FBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQywwQ0FBRSxRQUFRLENBQUM7QUFDdkUs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QWMsR0FBRyxJQUFBLHFCQUFXLEVBQUMsS0FBSyxVQUFVLGNBQWMsQ0FDbkUsUUFBc0IsRUFDdEIsTUFBcUIsRUFDckIsS0FBaUQ7SUFFakQsSUFBSSxXQUFXLEdBQWdCLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDaEUsS0FBSyxJQUFJLElBQUksSUFBSSxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUNyRCxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDdEIsTUFBTSxJQUFBLGtDQUFpQixFQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUN6RCxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztRQUN6QixJQUFJLElBQUksR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUNiLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFBLG1CQUFVLEVBQUMsSUFBSSxDQUFDLGtCQUFrQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxRQUFRLENBQUMsU0FBUyxJQUFJLFFBQVEsQ0FBQyxZQUFZLE9BQU8sQ0FBQyxDQUFDO1FBQ2xMLENBQUM7UUFDRCxtRUFBbUU7SUFDdkUsQ0FBQztJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3ZCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgcGF0aD1cIi4uL2hvdC9Ib3RSZWxvYWRDb250cm9sbGVyLnRzXCIgLz5cbmltcG9ydCB7IENhbGxlckNvbnRleHQsIENhbGxUeXBlLCBDbGllbnRIb29rQ29udGV4dCwgRnVsbENhbGxUeXBlLCBGdW5jdGlvbkZsYWdzLCBIb29rQ29udGV4dCwgU29ja2V0RXhwb3NlZEludGVyZmFjZSwgU29ja2V0RXhwb3NlZEludGVyZmFjZUNsYXNzLCBTb2NrZXRFeHBvc2VkU2hhcGUsIFNvY2tldEZ1bmN0aW9uQ2xpZW50SG9vaywgU29ja2V0RnVuY3Rpb25Ib29rLCBTb2NrZXRSZWdpc3RlcmVkIH0gZnJvbSBcIi4uL1NvY2tldEZ1bmN0aW9uVHlwZXNcIjtcbmltcG9ydCB7IF9zZXRTb2NrZXRDb250ZXh0IH0gZnJvbSBcIi4uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyBlbnRyaWVzLCBpc05vZGUgfSBmcm9tIFwiLi9taXNjXCI7XG5pbXBvcnQgZGVidWdicmVhayBmcm9tIFwiZGVidWdicmVha1wiO1xuaW1wb3J0IHsgbWVhc3VyZUJsb2NrLCBtZWFzdXJlV3JhcCB9IGZyb20gXCIuL3Byb2ZpbGluZy9tZWFzdXJlXCI7XG5pbXBvcnQgeyBmb3JtYXRUaW1lIH0gZnJvbSBcIi4vZm9ybWF0dGluZy9mb3JtYXRcIjtcbmltcG9ydCB7IGNyZWF0ZVNpbmdsZXRvbiB9IGZyb20gXCIuL2NyZWF0ZVNpbmdsZXRvblwiO1xuXG4vLyBTaGFyZWQgYWNyb3NzIGNvcGllcyBvZiB0aGlzIHBhY2thZ2UsIHNvIGEgY2FsbCByb3V0ZWQgdGhyb3VnaCBvbmUgY29weSBjYW4gZmluZCBhIGNsYXNzXG4vLyAgKGFuZCBpdHMgaG9va3MpIHJlZ2lzdGVyZWQgdGhyb3VnaCBhbm90aGVyIGNvcHkuIFNlZSBjcmVhdGVTaW5nbGV0b24uXG5jb25zdCBjbGFzc2VzID0gY3JlYXRlU2luZ2xldG9uKFwiY2FsbE1hbmFnZXIuY2xhc3Nlc1wiLCAxLCAoKSA9PiAoe30gYXMge1xuICAgIFtjbGFzc0d1aWQ6IHN0cmluZ106IHtcbiAgICAgICAgY29udHJvbGxlcjogU29ja2V0RXhwb3NlZEludGVyZmFjZTtcbiAgICAgICAgc2hhcGU6IFNvY2tldEV4cG9zZWRTaGFwZTtcbiAgICB9XG59KSkuZ2V0KCk7XG5jb25zdCBleHBvc2VkQ2xhc3NlcyA9IGNyZWF0ZVNpbmdsZXRvbihcImNhbGxNYW5hZ2VyLmV4cG9zZWRDbGFzc2VzXCIsIDEsICgpID0+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"; */