socket-function 1.1.49 → 1.2.1

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 (53) hide show
  1. package/SocketFunction.d.ts +1 -1
  2. package/SocketFunctionTypes.d.ts +1 -1
  3. package/dist/SetProcessVariables.ts.cache +9 -0
  4. package/dist/SocketFunction.ts.cache +467 -0
  5. package/hot/HotReloadController.d.ts +3 -3
  6. package/hot/dist/HotReloadController.ts.cache +252 -0
  7. package/index.d.ts +10 -25
  8. package/package.json +1 -1
  9. package/require/CSSShim.d.ts +1 -1
  10. package/require/RequireController.d.ts +2 -2
  11. package/require/compileFlags.d.ts +1 -1
  12. package/require/dist/RequireController.ts.cache +386 -0
  13. package/require/dist/compileFlags.ts.cache +41 -0
  14. package/require/dist/extMapper.ts.cache +368 -0
  15. package/require/dist/require.ts.cache +676 -0
  16. package/require/require.d.ts +1 -1
  17. package/src/JSONLACKS/dist/JSONLACKS.ts.cache +469 -0
  18. package/src/callManager.d.ts +1 -1
  19. package/src/dist/CallFactory.ts.cache +930 -0
  20. package/src/dist/Zip.ts.cache +156 -0
  21. package/src/dist/batching.ts.cache +377 -0
  22. package/src/dist/bits.ts.cache +121 -0
  23. package/src/dist/buffers.ts.cache +76 -0
  24. package/src/dist/caching.ts.cache +302 -0
  25. package/src/dist/callHTTPHandler.ts.cache +264 -0
  26. package/src/dist/callManager.ts.cache +159 -0
  27. package/src/dist/certStore.ts.cache +59 -0
  28. package/src/dist/createSingleton.ts.cache +62 -0
  29. package/src/dist/fixLargeNetworkCalls.ts.cache +17 -0
  30. package/src/dist/forwardPort.ts.cache +222 -0
  31. package/src/dist/https.ts.cache +141 -0
  32. package/src/dist/misc.ts.cache +499 -0
  33. package/src/dist/nodeCache.ts.cache +136 -0
  34. package/src/dist/nodeProxy.ts.cache +57 -0
  35. package/src/dist/protocolNegotiation.ts.cache +101 -0
  36. package/src/dist/tlsParsing.ts.cache +85 -0
  37. package/src/dist/types.ts.cache +9 -0
  38. package/src/dist/webSocketServer.ts.cache +365 -0
  39. package/src/dist/websocketFactory.ts.cache +53 -0
  40. package/src/formatting/dist/colors.ts.cache +98 -0
  41. package/src/formatting/dist/format.ts.cache +396 -0
  42. package/src/formatting/dist/logColors.ts.cache +28 -0
  43. package/src/lz4/dist/LZ4.ts.cache +53 -0
  44. package/src/profiling/dist/getOwnTime.ts.cache +100 -0
  45. package/src/profiling/dist/measure.ts.cache +338 -0
  46. package/src/profiling/dist/stats.ts.cache +202 -0
  47. package/src/profiling/dist/statsFormat.ts.cache +45 -0
  48. package/src/profiling/getOwnTime.ts +7 -1
  49. package/src/profiling/measure.ts +25 -16
  50. package/test.ts +11 -5
  51. package/time/dist/trueTimeShim.ts.cache +656 -0
  52. package/time/trueTimeShim.d.ts +1 -16
  53. package/time/trueTimeShim.ts +7 -43
@@ -0,0 +1,365 @@
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
29
+ exports.startSocketServer = void 0;
30
+ const https_1 = __importDefault(require("https"));
31
+ const http_1 = __importDefault(require("http"));
32
+ const net_1 = __importDefault(require("net"));
33
+ const callHTTPHandler_1 = require("./callHTTPHandler");
34
+ const protocolNegotiation_1 = require("./protocolNegotiation");
35
+ const SocketFunction_1 = require("../SocketFunction");
36
+ const certStore_1 = require("./certStore");
37
+ const CallFactory_1 = require("./CallFactory");
38
+ const tlsParsing_1 = require("./tlsParsing");
39
+ const nodeCache_1 = require("./nodeCache");
40
+ const crypto_1 = __importDefault(require("crypto"));
41
+ const misc_1 = require("./misc");
42
+ const batching_1 = require("./batching");
43
+ const logColors_1 = require("./formatting/logColors");
44
+ const logColors_2 = require("./formatting/logColors");
45
+ const logColors_3 = require("./formatting/logColors");
46
+ const format_1 = require("./formatting/format");
47
+ const forwardPort_1 = require("./forwardPort");
48
+ async function startSocketServer(config) {
49
+ const ws = await Promise.resolve().then(() => __importStar(require("ws")));
50
+ const webSocketServer = new ws.Server({
51
+ noServer: true,
52
+ // Negotiate connection-level flags via Sec-WebSocket-Protocol. The
53
+ // client proposes hex-encoded values that include the target nodeId;
54
+ // we accept only those whose target matches OUR identity
55
+ // (SocketFunction.mountedNodeId — not the address the client used to
56
+ // reach us). If none match we return false, which rejects the
57
+ // handshake — exactly the semantics we want (indistinguishable from
58
+ // "node not reachable"). If the client sent no Sec-WebSocket-Protocol
59
+ // at all, this callback isn't invoked and the handshake proceeds as
60
+ // a legacy client.
61
+ handleProtocols: (protocols, request) => {
62
+ var _a;
63
+ const ourNodeId = SocketFunction_1.SocketFunction.mountedNodeId;
64
+ const proposed = Array.from(protocols);
65
+ const chosen = (0, protocolNegotiation_1.chooseProtocol)(proposed, ourNodeId, { lz4: true });
66
+ if (!chosen) {
67
+ const proposedDecoded = proposed.map(p => (0, protocolNegotiation_1.decodeProtocol)(p));
68
+ let target = (_a = proposedDecoded[0]) === null || _a === void 0 ? void 0 : _a.target;
69
+ let getMachineId = (x) => x.split(".").slice(-3).join(".");
70
+ if (target && getMachineId(target) === getMachineId(ourNodeId)) {
71
+ console.log(`Rejecting handshake from old thread, ${target} !== ${ourNodeId}`);
72
+ }
73
+ else {
74
+ console.log(`Rejecting handshake on ${ourNodeId}: none of the ${proposed.length} proposed protocols target us`, { ourNodeId, proposedDecoded });
75
+ }
76
+ return false;
77
+ }
78
+ return chosen;
79
+ },
80
+ });
81
+ async function setupHTTPSServer(watchOptions) {
82
+ let httpsServerLast;
83
+ let onHttpServer;
84
+ let httpServerPromise = new Promise(r => onHttpServer = r);
85
+ let lastOptions;
86
+ await watchOptions(value => {
87
+ // NOTE: If this is called a lot... STOP CALLING IT A LOT! Calling setSecureContext
88
+ // so frequently likely leaks memory!
89
+ console.log(`Updating websocket server options`);
90
+ lastOptions = {
91
+ ...value,
92
+ ca: (0, certStore_1.getTrustedCertificates)(),
93
+ // Attempt to disable sessions, because they make SNI significantly harder to parse.
94
+ secureOptions: require("node:constants").SSL_OP_NO_TICKET,
95
+ };
96
+ if (!httpsServerLast) {
97
+ httpsServerLast = https_1.default.createServer(lastOptions);
98
+ // NOTE: This MIGHT be different than the keep alive option? Probably not, but also...
99
+ // something weird is happening with connections...
100
+ httpsServerLast.keepAliveTimeout = 0;
101
+ }
102
+ else {
103
+ httpsServerLast.setSecureContext(lastOptions);
104
+ }
105
+ onHttpServer(httpsServerLast);
106
+ });
107
+ let httpsServer = await httpServerPromise;
108
+ let allowedHostnames = new Set();
109
+ for (let hostname of config.allowHostnames || []) {
110
+ allowedHostnames.add(hostname);
111
+ }
112
+ (0, certStore_1.watchTrustedCertificates)(() => {
113
+ // NOTE: If this is called a lot... STOP CALLING IT A LOT! Calling setSecureContext frequently leaks memory! (As in, once a minute is maybe too much, once a second is definitely too much)
114
+ console.log(`Updating websocket server trusted certificates`);
115
+ lastOptions.ca = (0, certStore_1.getTrustedCertificates)();
116
+ httpsServer.setSecureContext(lastOptions);
117
+ });
118
+ httpsServer.on("connection", socket => {
119
+ let debug = socket.remoteAddress + ":" + socket.remotePort;
120
+ if (!SocketFunction_1.SocketFunction.silent) {
121
+ console.log(`HTTP server connection established ${debug}`);
122
+ }
123
+ socket.on("error", e => {
124
+ if (!SocketFunction_1.SocketFunction.silent) {
125
+ console.log(`HTTP server socket error for ${debug}, ${e.message}`);
126
+ }
127
+ });
128
+ socket.on("close", () => {
129
+ if (!SocketFunction_1.SocketFunction.silent) {
130
+ console.log(`HTTP server socket closed for ${debug}`);
131
+ }
132
+ });
133
+ });
134
+ httpsServer.on("error", e => {
135
+ console.error(`Connection attempt error ${e.message}`);
136
+ });
137
+ httpsServer.on("tlsClientError", e => {
138
+ // NOTE: This happens a lot when we have tabs open that connected to an old
139
+ // server (with old certs, that the browser will reject?)
140
+ if (!SocketFunction_1.SocketFunction.silent) {
141
+ console.error(`TLS client error ${e.message}`);
142
+ }
143
+ });
144
+ httpsServer.on("request", callHTTPHandler_1.httpCallHandler);
145
+ httpsServer.on("upgrade", (request, socket, upgradeHead) => {
146
+ let originHeader = request.headers["origin"];
147
+ if (originHeader) {
148
+ try {
149
+ let host = (0, misc_1.getRootDomain)(new URL("ws://" + request.headers["host"]).hostname);
150
+ let origin = (0, misc_1.getRootDomain)(new URL(originHeader).hostname);
151
+ let allowed = host === origin || allowedHostnames.has(origin);
152
+ if (!allowed && config.allowHostnameFnc) {
153
+ allowed = config.allowHostnameFnc(origin);
154
+ }
155
+ if (!allowed) {
156
+ throw new Error(`Invalid cross domain request, ${JSON.stringify(host)} !== ${JSON.stringify(origin)} (also not in config.allowedHostnames ${JSON.stringify(config.allowHostnames)})`);
157
+ }
158
+ }
159
+ catch (e) {
160
+ // Destroy the socket, so we don't lock up the client
161
+ socket.destroy();
162
+ // NOTE: Just log, because invalid requests are guaranteed to happen, and
163
+ // there's no point wasting time looking at them.
164
+ console.log(e);
165
+ return;
166
+ }
167
+ }
168
+ webSocketServer.handleUpgrade(request, socket, upgradeHead, (ws) => {
169
+ const { nodeId, localNodeId } = (0, callHTTPHandler_1.getNodeIdsFromRequest)(request);
170
+ (0, CallFactory_1.createCallFactory)(ws, nodeId, localNodeId).catch(e => {
171
+ console.error(`Error in creating call factory, ${e.stack}`);
172
+ });
173
+ });
174
+ });
175
+ return httpsServer;
176
+ }
177
+ // TODO: Only allow unauthorized for ip certificates, and then for domains use the domain as the nodeId,
178
+ // so it is easy to read, and consistent.
179
+ let options = {
180
+ ...config,
181
+ // Keep alive causes problems with our HTTP requests. AND... almost all of our data uses
182
+ // our websockets, so... we really don't need to keep alive our HTTP requests
183
+ // (and our images go through cloudflare, so we don't even need keep alive for that)
184
+ keepAlive: false,
185
+ keepAliveInitialDelay: 0,
186
+ noDelay: true,
187
+ };
188
+ if (!config.cert) {
189
+ throw new Error("No cert specified");
190
+ }
191
+ if (!config.key) {
192
+ throw new Error("No key specified");
193
+ }
194
+ const mainHTTPSServer = await setupHTTPSServer(callback => callback(options));
195
+ let sniServers = new Map();
196
+ for (let [domain, obj] of Object.entries(config.SNICerts || {})) {
197
+ sniServers.set(domain, await setupHTTPSServer(obj));
198
+ }
199
+ let httpServer = http_1.default.createServer({ keepAlive: false, }, async function (req, res) {
200
+ let url = new URL("http://" + req.headers.host + req.url);
201
+ url.protocol = "https:";
202
+ //url.hostname = opts.hostname;
203
+ url.hostname = req.headers.host || "";
204
+ res.writeHead(301, { Location: url + "" });
205
+ res.end();
206
+ });
207
+ httpServer.keepAliveTimeout = 0;
208
+ httpServer.on("error", e => {
209
+ console.error(`HTTP error ${e.stack}`);
210
+ });
211
+ let realServer = net_1.default.createServer(socket => {
212
+ const debug = socket.remoteAddress + ":" + socket.remotePort;
213
+ if (!SocketFunction_1.SocketFunction.silent) {
214
+ console.log(`Received TCP connection from ${debug}`);
215
+ }
216
+ function handleTLSHello(buffer, packetCount) {
217
+ if (!SocketFunction_1.SocketFunction.silent) {
218
+ console.log(`Received TCP header packet from ${debug}, have ${buffer.length} bytes so far, ${packetCount} packets`);
219
+ }
220
+ // All HTTPS requests start with 22, and no HTTP requests start with 22,
221
+ // so we just need to read the first byte.
222
+ let server;
223
+ if (buffer[0] !== 22) {
224
+ server = httpServer;
225
+ }
226
+ else {
227
+ let data = (0, tlsParsing_1.parseTLSHello)(buffer);
228
+ if (data.missingBytes > 0) {
229
+ return "more";
230
+ }
231
+ let sni = data.extensions.filter(x => x.type === tlsParsing_1.SNIType).flatMap(x => (0, tlsParsing_1.parseSNIExtension)(x.data))[0];
232
+ if (!SocketFunction_1.SocketFunction.silent) {
233
+ console.log(`Received TCP connection with SNI ${JSON.stringify(sni)}. Have handlers for: ${Array.from(sniServers.keys()).join(", ")}`);
234
+ }
235
+ if (!sni) {
236
+ console.warn(`No SNI found in TLS hello from ${debug}, using main server. Packets ${packetCount}`);
237
+ console.log(buffer.toString("base64"));
238
+ }
239
+ let originalSNI = sni;
240
+ if (sni) {
241
+ // Remove subdomains until we can find a domain
242
+ while (!sniServers.has(sni)) {
243
+ let parts = sni.split(".");
244
+ if (parts.length <= 2)
245
+ break;
246
+ sni = parts.slice(1).join(".");
247
+ }
248
+ }
249
+ if (!sniServers.has(sni)) {
250
+ console.warn(`No SNI server found for ${originalSNI}, using main server. SNI candidates ${Array.from(sniServers.keys()).join(", ")}`);
251
+ }
252
+ server = sniServers.get(sni) || mainHTTPSServer;
253
+ }
254
+ // NOTE: Messages aren't dequeued until the current handler finishes, so we don't need to pause the socket or anything.
255
+ server.emit("connection", socket);
256
+ socket.unshift(buffer);
257
+ }
258
+ let buffers = [];
259
+ function getNextData() {
260
+ // NOTE: ONCE is used, so we only look at the first buffer, and then after that
261
+ // we pipe. This should be very efficient, as pipe has insane throughput
262
+ // (100s of MB/s, easily, even on a terrible machine).
263
+ socket.once("data", buffer => {
264
+ if (typeof buffer === "string") {
265
+ buffer = Buffer.from(buffer);
266
+ }
267
+ buffers.push(buffer);
268
+ let result = handleTLSHello(Buffer.concat(buffers), buffers.length);
269
+ if (result === "more") {
270
+ getNextData();
271
+ }
272
+ });
273
+ }
274
+ getNextData();
275
+ socket.on("error", (e) => {
276
+ console.error(`TCP socket error for ${debug}, ${e.stack}`);
277
+ });
278
+ socket.on("close", () => {
279
+ if (!SocketFunction_1.SocketFunction.silent) {
280
+ console.log(`TCP socket closed for ${debug}`);
281
+ }
282
+ });
283
+ });
284
+ let host = config.public ? "0.0.0.0" : "127.0.0.1";
285
+ if (config.ip) {
286
+ host = config.ip;
287
+ }
288
+ let port = config.port;
289
+ if (!SocketFunction_1.SocketFunction.silent) {
290
+ console.log((0, logColors_2.yellow)(`Trying to listening on ${host}:${port}`));
291
+ }
292
+ let listeningPromise = waitUntilListening();
293
+ listeningPromise.catch(e => { });
294
+ // Return true if we are listening, false if the address is in use, and throws on other errors
295
+ async function waitUntilListening() {
296
+ return await new Promise((resolve, reject) => {
297
+ realServer.once("error", e => {
298
+ reject(e);
299
+ });
300
+ realServer.once("listening", () => {
301
+ resolve(false);
302
+ });
303
+ });
304
+ }
305
+ if (config.useAvailablePortIfPortInUse && port) {
306
+ realServer.listen(port, host);
307
+ let isListening = await new Promise((resolve, reject) => {
308
+ if (realServer.listening) {
309
+ resolve(true);
310
+ return;
311
+ }
312
+ realServer.once("error", e => {
313
+ if (e.message.includes("EADDRINUSE")) {
314
+ resolve(true);
315
+ }
316
+ else {
317
+ reject(e);
318
+ }
319
+ });
320
+ realServer.once("listening", () => {
321
+ resolve(false);
322
+ });
323
+ });
324
+ if (!isListening) {
325
+ port = 0;
326
+ realServer.listen(port, host);
327
+ listeningPromise = waitUntilListening();
328
+ }
329
+ }
330
+ else {
331
+ realServer.listen(port, host);
332
+ }
333
+ await listeningPromise;
334
+ port = realServer.address().port;
335
+ if (config.autoForwardPort && config.public) {
336
+ // let externalIP = await getExternalIP();
337
+ // let isListening = await testTCPIsListening(externalIP, port);
338
+ // if (!isListening) {
339
+ // console.log(magenta(`Port ${port} is not externally reachable, trying to forward it`));
340
+ // await forwardPort({ externalPort: port, internalPort: port });
341
+ // }
342
+ // Even if they are listening, they might not stay listening. Forward every 8 hours
343
+ // (including at the start, in case the forward is about to expire).
344
+ async function forward() {
345
+ await (0, forwardPort_1.forwardPort)({ externalPort: port, internalPort: port });
346
+ console.log((0, logColors_1.magenta)(`Forwarded port ${port} to our machine`));
347
+ }
348
+ // Every hour, in case our network configuration changes
349
+ (0, batching_1.runInfinitePollCallAtStart)(misc_1.timeInMinute * 30, forward).catch(e => console.error((0, logColors_1.red)(`Error in port forwarding ${e.stack}`)));
350
+ }
351
+ let nodeId = (0, nodeCache_1.getNodeId)(getCommonName(config.cert), port);
352
+ console.log((0, logColors_3.green)(`Started Listening on ${nodeId} (${host}) after ${(0, format_1.formatTime)(process.uptime() * 1000)}`));
353
+ return nodeId;
354
+ }
355
+ exports.startSocketServer = startSocketServer;
356
+ function getCommonName(cert) {
357
+ let subject = new crypto_1.default.X509Certificate(cert).subject;
358
+ let subjectKVPs = new Map(subject.split(",").map(x => x.trim().split("=")).map(x => [x[0], x.slice(1).join("=")]));
359
+ let commonName = subjectKVPs.get("CN");
360
+ if (!commonName)
361
+ throw new Error(`No common name in subject: ${subject}`);
362
+ return commonName;
363
+ }
364
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViU29ja2V0U2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsid2ViU29ja2V0U2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLGdEQUF3QjtBQUN4Qiw4Q0FBc0I7QUFFdEIsdURBQTJFO0FBQzNFLCtEQUF1RTtBQUN2RSxzREFBbUQ7QUFDbkQsMkNBQStFO0FBQy9FLCtDQUFrRDtBQUNsRCw2Q0FBeUU7QUFFekUsMkNBQXdDO0FBQ3hDLG9EQUE0QjtBQUM1QixpQ0FBNEU7QUFDNUUseUNBQWdGO0FBQ2hGLHNEQUFzRDtBQUN0RCxzREFBZ0Q7QUFDaEQsc0RBQStDO0FBQy9DLGdEQUFpRDtBQUVqRCwrQ0FBNEM7QUF1Q3JDLEtBQUssVUFBVSxpQkFBaUIsQ0FDbkMsTUFBMEI7SUFFMUIsTUFBTSxFQUFFLEdBQUcsd0RBQWEsSUFBSSxHQUFDLENBQUM7SUFFOUIsTUFBTSxlQUFlLEdBQUcsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO1FBQ2xDLFFBQVEsRUFBRSxJQUFJO1FBQ2QsbUVBQW1FO1FBQ25FLHFFQUFxRTtRQUNyRSx5REFBeUQ7UUFDekQscUVBQXFFO1FBQ3JFLDhEQUE4RDtRQUM5RCxvRUFBb0U7UUFDcEUsc0VBQXNFO1FBQ3RFLG9FQUFvRTtRQUNwRSxtQkFBbUI7UUFDbkIsZUFBZSxFQUFFLENBQUMsU0FBUyxFQUFFLE9BQU8sRUFBRSxFQUFFOztZQUNwQyxNQUFNLFNBQVMsR0FBRywrQkFBYyxDQUFDLGFBQWEsQ0FBQztZQUMvQyxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sTUFBTSxHQUFHLElBQUEsb0NBQWMsRUFBQyxRQUFRLEVBQUUsU0FBUyxFQUFFLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDbEUsSUFBSSxDQUFDLE1BQU0sRUFBRSxD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QkFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDdkQsSUFBSSxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkgsSUFBSSxVQUFVLEdBQUcsV0FBVyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN2QyxJQUFJLENBQUMsVUFBVTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDMUUsT0FBTyxVQUFVLENBQUM7QUFDdEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBodHRwcyBmcm9tIFwiaHR0cHNcIjtcbmltcG9ydCBodHRwIGZyb20gXCJodHRwXCI7XG5pbXBvcnQgbmV0IGZyb20gXCJuZXRcIjtcbmltcG9ydCB0bHMgZnJvbSBcInRsc1wiO1xuaW1wb3J0IHsgZ2V0Tm9kZUlkc0Zyb21SZXF1ZXN0LCBodHRwQ2FsbEhhbmRsZXIgfSBmcm9tIFwiLi9jYWxsSFRUUEhhbmRsZXJcIjtcbmltcG9ydCB7IGNob29zZVByb3RvY29sLCBkZWNvZGVQcm90b2NvbCB9IGZyb20gXCIuL3Byb3RvY29sTmVnb3RpYXRpb25cIjtcbmltcG9ydCB7IFNvY2tldEZ1bmN0aW9uIH0gZnJvbSBcIi4uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyBnZXRUcnVzdGVkQ2VydGlmaWNhdGVzLCB3YXRjaFRydXN0ZWRDZXJ0aWZpY2F0ZXMgfSBmcm9tIFwiLi9jZXJ0U3RvcmVcIjtcbmltcG9ydCB7IGNyZWF0ZUNhbGxGYWN0b3J5IH0gZnJvbSBcIi4vQ2FsbEZhY3RvcnlcIjtcbmltcG9ydCB7IHBhcnNlU05JRXh0ZW5zaW9uLCBwYXJzZVRMU0hlbGxvLCBTTklUeXBlIH0gZnJvbSBcIi4vdGxzUGFyc2luZ1wiO1xuaW1wb3J0IGRlYnVnYnJlYWsgZnJvbSBcImRlYnVnYnJlYWtcIjtcbmltcG9ydCB7IGdldE5vZGVJZCB9IGZyb20gXCIuL25vZGVDYWNoZVwiO1xuaW1wb3J0IGNyeXB0byBmcm9tIFwiY3J5cHRvXCI7XG5pbXBvcnQgeyBXYXRjaGFibGUsIGdldFJvb3REb21haW4sIHRpbWVJbkhvdXIsIHRpbWVJbk1pbnV0ZSB9IGZyb20gXCIuL21pc2NcIjtcbmltcG9ydCB7IGRlbGF5LCBydW5JbmZpbml0ZVBvbGwsIHJ1bkluZmluaXRlUG9sbENhbGxBdFN0YXJ0IH0gZnJvbSBcIi4vYmF0Y2hpbmdcIjtcbmltcG9ydCB7IG1hZ2VudGEsIHJlZCB9IGZyb20gXCIuL2Zvcm1hdHRpbmcvbG9nQ29sb3JzXCI7XG5pbXBvcnQgeyB5ZWxsb3cgfSBmcm9tIFwiLi9mb3JtYXR0aW5nL2xvZ0NvbG9yc1wiO1xuaW1wb3J0IHsgZ3JlZW4gfSBmcm9tIFwiLi9mb3JtYXR0aW5nL2xvZ0NvbG9yc1wiO1xuaW1wb3J0IHsgZm9ybWF0VGltZSB9IGZyb20gXCIuL2Zvcm1hdHRpbmcvZm9ybWF0XCI7XG5pbXBvcnQgeyBnZXRFeHRlcm5hbElQLCB0ZXN0VENQSXNMaXN0ZW5pbmcgfSBmcm9tIFwiLi9uZXR3b3JraW5nXCI7XG5pbXBvcnQgeyBmb3J3YXJkUG9ydCB9IGZyb20gXCIuL2ZvcndhcmRQb3J0XCI7XG5cbmV4cG9ydCB0eXBlIFNvY2tldFNlcnZlckNvbmZpZyA9IChcbiAgICBodHRwcy5TZXJ2ZXJPcHRpb25zICYge1xuICAgICAgICBrZXk6IHN0cmluZyB8IEJ1ZmZlcjtcbiAgICAgICAgY2VydDogc3RyaW5nIHwgQnVmZmVyO1xuXG4gICAgICAgIHBvcnQ6IG51bWJlcjtcbiAgICAgICAgLyoqIFlvdSBjYW4gYWxzbyBzZXQgYHBvcnQ6IDBgIGlmIHlvdSBkb24ndCBjYXJlIHdoYXQgcG9ydCB5b3Ugd2FudCBhdCBhbGwuICAqL1xuICAgICAgICB1c2VBdmFpbGFibGVQb3J0SWZQb3J0SW5Vc2U/OiBib29sZWFuO1xuXG4gICAgICAgIC8vIHB1YmxpYyBzZXRzIGlwIHRvIFwiMC4wLjAuMFwiLCBvdGhlcndpc2UgaXQgZGVmYXVsdHMgdG8gXCIxMjcuMC4wLjFcIiwgd2hpY2hcbiAgICAgICAgLy8gIGNhdXNlcyB0aGUgc2VydmVyIHRvIG9ubHkgYWNjZXB0IGxvY2FsIGNvbm5lY3Rpb25zLlxuICAgICAgICBwdWJsaWM/OiBib29sZWFuO1xuICAgICAgICAvKiogVHJpZXMgZm9yd2FyZGluZyBwb3J0cyAodXNpbmcgVVBuUCksIGlmIHdlIGRldGVjdCB0aGV5IGFyZW4ndCBleHRlcm5hbGx5IHJlYWNoYWJsZS5cbiAgICAgICAgICogICAgICAtIFRoaXMgY2F1c2VzIGFuIGV4dHJhIHJlcXVlc3QgYW5kIGRlbGF5IGR1cmluZyBzdGFydHVwLCBzbyBzaG91bGQgb25seSBiZSB1c2VkXG4gICAgICAgICAqICAgICAgICAgIGR1cmluZyBkZXZlbG9wbWVudC5cbiAgICAgICAgICogICAgICAtIElnbm9yZWQgaWYgcHVibGljIGlzIGZhbHNlIChpbiB3aGljaCBjYXNlIHdlIG1vdW50IG9uIDEyNy4wLjAuMSwgc28gcG9ydCBmb3J3YXJkaW5nXG4gICAgICAgICAqICAgICAgICAgIHdvdWxkbid0IG1hdHRlciBhbnl3YXlzKS5cbiAgICAgICAgKi9cbiAgICAgICAgYXV0b0ZvcndhcmRQb3J0PzogYm9vbGVhbjtcbiAgICAgICAgaXA/OiBzdHJpbmc7XG5cbiAgICAgICAgLy8gTk9URTogQW55IHNhbWUgb3JpZ2luIGFjY2Vzc2VzIGFyZSBhbGxvd2VkIChoZWFkZXIub3JpZ2luID09PSBoZWFkZXIuaG9zdClcbiAgICAgICAgLy8gRm9yIGV4YW1wbGUsIHRvIGFsbG93IFwibGV0eC5jYVwiIHRvIGFjY2VzcyB0aGUgc2VydmVyICh3aGVuIHRoZSBob3N0ZWQgZG9tYWluXG4gICAgICAgIC8vICBtYXkgYmUsIFwicXVlcnlzdWIuY29tXCIsIGZvciBleGFtcGxlKSwgdXNlIFtcImxldHguY2FcIl1cbiAgICAgICAgYWxsb3dIb3N0bmFtZXM/OiBzdHJpbmdbXTtcbiAgICAgICAgLy8gSWYgYSBob3N0bmFtZSBpcyBpbiBhbGxvd0hvc3RuYW1lcyBvciBhbGxvd0hvc3RuYW1lRm5jIHJldHVybnMgdHJ1ZSwgaXQgaXMgYWxsb3dlZFxuICAgICAgICBhbGxvd0hvc3RuYW1lRm5jPzogKGhvc3RuYW1lOiBzdHJpbmcpID0+IGJvb2xlYW47XG5cbiAgICAgICAgLyoqIElmIHRoZSBTTkkgbWF0Y2hlcyB0aGlzIGRvbWFpbiwgd2UgdXNlIGEgZGlmZmVyZW50IGtleS9jZXJ0LlxuICAgICAgICAgKiAgICAgIFdlIHJlbW92ZSBzdWJkb21haW5zIHVudGlsIHdlIGZpbmQgYSBtYXRjaFxuICAgICAgICAgKi9cbiAgICAgICAgU05JQ2VydHM/OiB7XG4gICAgICAgICAgICBbZG9tYWluOiBzdHJpbmddOiBXYXRjaGFibGU8aHR0cHMuU2VydmVyT3B0aW9ucz47XG4gICAgICAgIH07XG4gICAgfVxuKTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0U29ja2V0U2VydmVyKFxuICAgIGNvbmZpZzogU29ja2V0U2VydmVyQ29uZmlnXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHdzID0gYXdhaXQgaW1wb3J0KFwid3NcIik7XG5cbiAgICBjb25zdCB3ZWJTb2NrZXRTZXJ2ZXIgPSBuZXcgd3MuU2VydmVyKHtcbiAgICAgICAgbm9TZXJ2ZXI6IHRydWUsXG4gICAgICAgIC8vIE5lZ290aWF0ZSBjb25uZWN0aW9uLWxldmVsIGZsYWdzIHZpYSBTZWMtV2ViU29ja2V0LVByb3RvY29sLiBUaGVcbiAgICAgICAgLy8gY2xpZW50IHByb3Bvc2VzIGhleC1lbmNvZGVkIHZhbHVlcyB0aGF0IGluY2x1ZGUgdGhlIHRhcmdldCBub2RlSWQ7XG4gICAgICAgIC8vIHdlIGFjY2VwdCBvbmx5IHRob3NlIHdob3NlIHRhcmdldCBtYXRjaGVzIE9VUiBpZGVudGl0eVxuICAgICAgICAvLyAoU29ja2V0RnVuY3Rpb24ubW91bnRlZE5vZGVJZCDigJQgbm90IHRoZSBhZGRyZXNzIHRoZSBjbGllbnQgdXNlZCB0b1xuICAgICAgICAvLyByZWFjaCB1cykuIElmIG5vbmUgbWF0Y2ggd2UgcmV0dXJuIGZhbHNlLCB3aGljaCByZWplY3RzIHRoZVxuICAgICAgICAvLyBoYW5kc2hha2Ug4oCUIGV4YWN0bHkgdGhlIHNlbWFudGljcyB3ZSB3YW50IChpbmRpc3Rpbmd1aXNoYWJsZSBmcm9tXG4gICAgICAgIC8vIFwibm9kZSBub3QgcmVhY2hhYmxlXCIpLiBJZiB0aGUgY2xpZW50IHNlbnQgbm8gU2VjLVdlYlNvY2tldC1Qcm90b2NvbFxuICAgICAgICAvLyBhdCBhbGwsIHRoaXMgY2FsbGJhY2sgaXNuJ3QgaW52b2tlZCBhbmQgdGhlIGhhbmRzaGFrZSBwcm9jZWVkcyBhc1xuICAgICAgICAvLyBhIGxlZ2FjeSBjbGllbnQuXG4gICAgICAgIGhhbmRsZVByb3RvY29sczogKHByb3RvY29scywgcmVxdWVzdCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb3VyTm9kZUlkID0gU29ja2V0RnVuY3Rpb24ubW91bnRlZE5vZGVJZDtcbiAgICAgICAgICAgIGNvbnN0IHByb3Bvc2VkID0gQXJyYXkuZnJvbShwcm90b2NvbHMpO1xuICAgICAgICAgICAgY29uc3QgY2hvc2VuID0gY2hvb3NlUHJvdG9jb2wocHJvcG9zZWQsIG91ck5vZGVJZCwgeyBsejQ6IHRydWUgfSk7XG4gICAgICAgICAgICBpZiAoIWNob3Nlbikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHByb3Bvc2VkRGVjb2RlZCA9IHByb3Bvc2VkLm1hcChwID0+IGRlY29kZVByb3RvY29sKHApKTtcbiAgICAgICAgICAgICAgICBsZXQgdGFyZ2V0ID0gcHJvcG9zZWREZWNvZGVkWzBdPy50YXJnZXQ7XG4gICAgICAgICAgICAgICAgbGV0IGdldE1hY2hpbmVJZCA9ICh4OiBzdHJpbmcpID0+IHguc3BsaXQoXCIuXCIpLnNsaWNlKC0zKS5qb2luKFwiLlwiKTtcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0ICYmIGdldE1hY2hpbmVJZCh0YXJnZXQpID09PSBnZXRNYWNoaW5lSWQob3VyTm9kZUlkKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgUmVqZWN0aW5nIGhhbmRzaGFrZSBmcm9tIG9sZCB0aHJlYWQsICR7dGFyZ2V0fSAhPT0gJHtvdXJOb2RlSWR9YCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFJlamVjdGluZyBoYW5kc2hha2Ugb24gJHtvdXJOb2RlSWR9OiBub25lIG9mIHRoZSAke3Byb3Bvc2VkLmxlbmd0aH0gcHJvcG9zZWQgcHJvdG9jb2xzIHRhcmdldCB1c2AsIHsgb3VyTm9kZUlkLCBwcm9wb3NlZERlY29kZWQgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBjaG9zZW47XG4gICAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBhc3luYyBmdW5jdGlvbiBzZXR1cEhUVFBTU2VydmVyKHdhdGNoT3B0aW9uczogV2F0Y2hhYmxlPGh0dHBzLlNlcnZlck9wdGlvbnM+KSB7XG4gICAgICAgIGxldCBodHRwc1NlcnZlckxhc3Q6IGh0dHBzLlNlcnZlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IG9uSHR0cFNlcnZlcjogKHNlcnZlcjogaHR0cHMuU2VydmVyKSA9PiB2b2lkO1xuICAgICAgICBsZXQgaHR0cFNlcnZlclByb21pc2UgPSBuZXcgUHJvbWlzZTxodHRwcy5TZXJ2ZXI+KHIgPT4gb25IdHRwU2VydmVyID0gcik7XG4gICAgICAgIGxldCBsYXN0T3B0aW9ucyE6IGh0dHBzLlNlcnZlck9wdGlvbnM7XG4gICAgICAgIGF3YWl0IHdhdGNoT3B0aW9ucyh2YWx1ZSA9PiB7XG4gICAgICAgICAgICAvLyBOT1RFOiBJZiB0aGlzIGlzIGNhbGxlZCBhIGxvdC4uLiBTVE9QIENBTExJTkcgSVQgQSBMT1QhIENhbGxpbmcgc2V0U2VjdXJlQ29udGV4dFxuICAgICAgICAgICAgLy8gIHNvIGZyZXF1ZW50bHkgbGlrZWx5IGxlYWtzIG1lbW9yeSFcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBVcGRhdGluZyB3ZWJzb2NrZXQgc2VydmVyIG9wdGlvbnNgKTtcbiAgICAgICAgICAgIGxhc3RPcHRpb25zID0ge1xuICAgICAgICAgICAgICAgIC4uLnZhbHVlLFxuICAgICAgICAgICAgICAgIGNhOiBnZXRUcnVzdGVkQ2VydGlmaWNhdGVzKCksXG4gICAgICAgICAgICAgICAgLy8gQXR0ZW1wdCB0byBkaXNhYmxlIHNlc3Npb25zLCBiZWNhdXNlIHRoZXkgbWFrZSBTTkkgc2lnbmlmaWNhbnRseSBoYXJkZXIgdG8gcGFyc2UuXG4gICAgICAgICAgICAgICAgc2VjdXJlT3B0aW9uczogcmVxdWlyZShcIm5vZGU6Y29uc3RhbnRzXCIpLlNTTF9PUF9OT19USUNLRVQsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKCFodHRwc1NlcnZlckxhc3QpIHtcbiAgICAgICAgICAgICAgICBodHRwc1NlcnZlckxhc3QgPSBodHRwcy5jcmVhdGVTZXJ2ZXIobGFzdE9wdGlvbnMpO1xuICAgICAgICAgICAgICAgIC8vIE5PVEU6IFRoaXMgTUlHSFQgYmUgZGlmZmVyZW50IHRoYW4gdGhlIGtlZXAgYWxpdmUgb3B0aW9uPyBQcm9iYWJseSBub3QsIGJ1dCBhbHNvLi4uXG4gICAgICAgICAgICAgICAgLy8gIHNvbWV0aGluZyB3ZWlyZCBpcyBoYXBwZW5pbmcgd2l0aCBjb25uZWN0aW9ucy4uLlxuICAgICAgICAgICAgICAgIGh0dHBzU2VydmVyTGFzdC5rZWVwQWxpdmVUaW1lb3V0ID0gMDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaHR0cHNTZXJ2ZXJMYXN0LnNldFNlY3VyZUNvbnRleHQobGFzdE9wdGlvbnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb25IdHRwU2VydmVyKGh0dHBzU2VydmVyTGFzdCk7XG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgaHR0cHNTZXJ2ZXIgPSBhd2FpdCBodHRwU2VydmVyUHJvbWlzZTtcblxuICAgICAgICBsZXQgYWxsb3dlZEhvc3RuYW1lcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICBmb3IgKGxldCBob3N0bmFtZSBvZiBjb25maWcuYWxsb3dIb3N0bmFtZXMgfHwgW10pIHtcbiAgICAgICAgICAgIGFsbG93ZWRIb3N0bmFtZXMuYWRkKGhvc3RuYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHdhdGNoVHJ1c3RlZENlcnRpZmljYXRlcygoKSA9PiB7XG4gICAgICAgICAgICAvLyBOT1RFOiBJZiB0aGlzIGlzIGNhbGxlZCBhIGxvdC4uLiBTVE9QIENBTExJTkcgSVQgQSBMT1QhIENhbGxpbmcgc2V0U2VjdXJlQ29udGV4dCBmcmVxdWVudGx5IGxlYWtzIG1lbW9yeSEgKEFzIGluLCBvbmNlIGEgbWludXRlIGlzIG1heWJlIHRvbyBtdWNoLCBvbmNlIGEgc2Vjb25kIGlzIGRlZmluaXRlbHkgdG9vIG11Y2gpXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgVXBkYXRpbmcgd2Vic29ja2V0IHNlcnZlciB0cnVzdGVkIGNlcnRpZmljYXRlc2ApO1xuICAgICAgICAgICAgbGFzdE9wdGlvbnMuY2EgPSBnZXRUcnVzdGVkQ2VydGlmaWNhdGVzKCk7XG4gICAgICAgICAgICBodHRwc1NlcnZlci5zZXRTZWN1cmVDb250ZXh0KGxhc3RPcHRpb25zKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaHR0cHNTZXJ2ZXIub24oXCJjb25uZWN0aW9uXCIsIHNvY2tldCA9PiB7XG4gICAgICAgICAgICBsZXQgZGVidWcgPSAoc29ja2V0IGFzIGFueSkucmVtb3RlQWRkcmVzcyArIFwiOlwiICsgKHNvY2tldCBhcyBhbnkpLnJlbW90ZVBvcnQ7XG4gICAgICAgICAgICBpZiAoIVNvY2tldEZ1bmN0aW9uLnNpbGVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBIVFRQIHNlcnZlciBjb25uZWN0aW9uIGVzdGFibGlzaGVkICR7ZGVidWd9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzb2NrZXQub24oXCJlcnJvclwiLCBlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoIVNvY2tldEZ1bmN0aW9uLnNpbGVudCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgSFRUUCBzZXJ2ZXIgc29ja2V0IGVycm9yIGZvciAke2RlYnVnfSwgJHtlLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzb2NrZXQub24oXCJjbG9zZVwiLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFTb2NrZXRGdW5jdGlvbi5zaWxlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYEhUVFAgc2VydmVyIHNvY2tldCBjbG9zZWQgZm9yICR7ZGVidWd9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICBodHRwc1NlcnZlci5vbihcImVycm9yXCIsIGUgPT4ge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgQ29ubmVjdGlvbiBhdHRlbXB0IGVycm9yICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICB9KTtcbiAgICAgICAgaHR0cHNTZXJ2ZXIub24oXCJ0bHNDbGllbnRFcnJvclwiLCBlID0+IHtcbiAgICAgICAgICAgIC8vIE5PVEU6IFRoaXMgaGFwcGVucyBhIGxvdCB3aGVuIHdlIGhhdmUgdGFicyBvcGVuIHRoYXQgY29ubmVjdGVkIHRvIGFuIG9sZFxuICAgICAgICAgICAgLy8gIHNlcnZlciAod2l0aCBvbGQgY2VydHMsIHRoYXQgdGhlIGJyb3dzZXIgd2lsbCByZWplY3Q/KVxuICAgICAgICAgICAgaWYgKCFTb2NrZXRGdW5jdGlvbi5zaWxlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBUTFMgY2xpZW50IGVycm9yICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICBodHRwc1NlcnZlci5vbihcInJlcXVlc3RcIiwgaHR0cENhbGxIYW5kbGVyKTtcblxuICAgICAgICBodHRwc1NlcnZlci5vbihcInVwZ3JhZGVcIiwgKHJlcXVlc3QsIHNvY2tldCwgdXBncmFkZUhlYWQpID0+IHtcbiAgICAgICAgICAgIGxldCBvcmlnaW5IZWFkZXIgPSByZXF1ZXN0LmhlYWRlcnNbXCJvcmlnaW5cIl07XG4gICAgICAgICAgICBpZiAob3JpZ2luSGVhZGVyKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhvc3QgPSBnZXRSb290RG9tYWluKG5ldyBVUkwoXCJ3czovL1wiICsgcmVxdWVzdC5oZWFkZXJzW1wiaG9zdFwiXSkuaG9zdG5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgb3JpZ2luID0gZ2V0Um9vdERvbWFpbihuZXcgVVJMKG9yaWdpbkhlYWRlcikuaG9zdG5hbWUpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgYWxsb3dlZCA9IGhvc3QgPT09IG9yaWdpbiB8fCBhbGxvd2VkSG9zdG5hbWVzLmhhcyhvcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWFsbG93ZWQgJiYgY29uZmlnLmFsbG93SG9zdG5hbWVGbmMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbG93ZWQgPSBjb25maWcuYWxsb3dIb3N0bmFtZUZuYyhvcmlnaW4pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGNyb3NzIGRvbWFpbiByZXF1ZXN0LCAke0pTT04uc3RyaW5naWZ5KGhvc3QpfSAhPT0gJHtKU09OLnN0cmluZ2lmeShvcmlnaW4pfSAoYWxzbyBub3QgaW4gY29uZmlnLmFsbG93ZWRIb3N0bmFtZXMgJHtKU09OLnN0cmluZ2lmeShjb25maWcuYWxsb3dIb3N0bmFtZXMpfSlgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRGVzdHJveSB0aGUgc29ja2V0LCBzbyB3ZSBkb24ndCBsb2NrIHVwIHRoZSBjbGllbnRcbiAgICAgICAgICAgICAgICAgICAgc29ja2V0LmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogSnVzdCBsb2csIGJlY2F1c2UgaW52YWxpZCByZXF1ZXN0cyBhcmUgZ3VhcmFudGVlZCB0byBoYXBwZW4sIGFuZFxuICAgICAgICAgICAgICAgICAgICAvLyAgdGhlcmUncyBubyBwb2ludCB3YXN0aW5nIHRpbWUgbG9va2luZyBhdCB0aGVtLlxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHdlYlNvY2tldFNlcnZlci5oYW5kbGVVcGdyYWRlKHJlcXVlc3QsIHNvY2tldCwgdXBncmFkZUhlYWQsICh3cykgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHsgbm9kZUlkLCBsb2NhbE5vZGVJZCB9ID0gZ2V0Tm9kZUlkc0Zyb21SZXF1ZXN0KHJlcXVlc3QpO1xuICAgICAgICAgICAgICAgIGNyZWF0ZUNhbGxGYWN0b3J5KHdzLCBub2RlSWQsIGxvY2FsTm9kZUlkKS5jYXRjaChlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgaW4gY3JlYXRpbmcgY2FsbCBmYWN0b3J5LCAke2Uuc3RhY2t9YCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBodHRwc1NlcnZlcjtcbiAgICB9XG5cbiAgICAvLyBUT0RPOiBPbmx5IGFsbG93IHVuYXV0aG9yaXplZCBmb3IgaXAgY2VydGlmaWNhdGVzLCBhbmQgdGhlbiBmb3IgZG9tYWlucyB1c2UgdGhlIGRvbWFpbiBhcyB0aGUgbm9kZUlkLFxuICAgIC8vICBzbyBpdCBpcyBlYXN5IHRvIHJlYWQsIGFuZCBjb25zaXN0ZW50LlxuICAgIGxldCBvcHRpb25zOiBodHRwcy5TZXJ2ZXJPcHRpb25zID0ge1xuICAgICAgICAuLi5jb25maWcsXG4gICAgICAgIC8vIEtlZXAgYWxpdmUgY2F1c2VzIHByb2JsZW1zIHdpdGggb3VyIEhUVFAgcmVxdWVzdHMuIEFORC4uLiBhbG1vc3QgYWxsIG9mIG91ciBkYXRhIHVzZXNcbiAgICAgICAgLy8gIG91ciB3ZWJzb2NrZXRzLCBzby4uLiB3ZSByZWFsbHkgZG9uJ3QgbmVlZCB0byBrZWVwIGFsaXZlIG91ciBIVFRQIHJlcXVlc3RzXG4gICAgICAgIC8vICAoYW5kIG91ciBpbWFnZXMgZ28gdGhyb3VnaCBjbG91ZGZsYXJlLCBzbyB3ZSBkb24ndCBldmVuIG5lZWQga2VlcCBhbGl2ZSBmb3IgdGhhdClcbiAgICAgICAga2VlcEFsaXZlOiBmYWxzZSxcbiAgICAgICAga2VlcEFsaXZlSW5pdGlhbERlbGF5OiAwLFxuICAgICAgICBub0RlbGF5OiB0cnVlLFxuICAgIH07XG4gICAgaWYgKCFjb25maWcuY2VydCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBjZXJ0IHNwZWNpZmllZFwiKTtcbiAgICB9XG4gICAgaWYgKCFjb25maWcua2V5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGtleSBzcGVjaWZpZWRcIik7XG4gICAgfVxuXG4gICAgY29uc3QgbWFpbkhUVFBTU2VydmVyID0gYXdhaXQgc2V0dXBIVFRQU1NlcnZlcihjYWxsYmFjayA9PiBjYWxsYmFjayhvcHRpb25zKSk7XG4gICAgbGV0IHNuaVNlcnZlcnMgPSBuZXcgTWFwPHN0cmluZywgaHR0cHMuU2VydmVyPigpO1xuICAgIGZvciAobGV0IFtkb21haW4sIG9ial0gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnLlNOSUNlcnRzIHx8IHt9KSkge1xuICAgICAgICBzbmlTZXJ2ZXJzLnNldChkb21haW4sIGF3YWl0IHNldHVwSFRUUFNTZXJ2ZXIob2JqKSk7XG4gICAgfVxuXG4gICAgbGV0IGh0dHBTZXJ2ZXIgPSBodHRwLmNyZWF0ZVNlcnZlcih7IGtlZXBBbGl2ZTogZmFsc2UsIH0sIGFzeW5jIGZ1bmN0aW9uIChyZXEsIHJlcykge1xuICAgICAgICBsZXQgdXJsID0gbmV3IFVSTChcImh0dHA6Ly9cIiArIHJlcS5oZWFkZXJzLmhvc3QgKyByZXEudXJsKTtcbiAgICAgICAgdXJsLnByb3RvY29sID0gXCJodHRwczpcIjtcbiAgICAgICAgLy91cmwuaG9zdG5hbWUgPSBvcHRzLmhvc3RuYW1lO1xuICAgICAgICB1cmwuaG9zdG5hbWUgPSByZXEuaGVhZGVycy5ob3N0IHx8IFwiXCI7XG4gICAgICAgIHJlcy53cml0ZUhlYWQoMzAxLCB7IExvY2F0aW9uOiB1cmwgKyBcIlwiIH0pO1xuICAgICAgICByZXMuZW5kKCk7XG4gICAgfSk7XG4gICAgaHR0cFNlcnZlci5rZWVwQWxpdmVUaW1lb3V0ID0gMDtcbiAgICBodHRwU2VydmVyLm9uKFwiZXJyb3JcIiwgZSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYEhUVFAgZXJyb3IgJHtlLnN0YWNrfWApO1xuICAgIH0pO1xuXG4gICAgbGV0IHJlYWxTZXJ2ZXIgPSBuZXQuY3JlYXRlU2VydmVyKHNvY2tldCA9PiB7XG4gICAgICAgIGNvbnN0IGRlYnVnID0gc29ja2V0LnJlbW90ZUFkZHJlc3MgKyBcIjpcIiArIHNvY2tldC5yZW1vdGVQb3J0O1xuICAgICAgICBpZiAoIVNvY2tldEZ1bmN0aW9uLnNpbGVudCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFJlY2VpdmVkIFRDUCBjb25uZWN0aW9uIGZyb20gJHtkZWJ1Z31gKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBoYW5kbGVUTFNIZWxsbyhidWZmZXI6IEJ1ZmZlciwgcGFja2V0Q291bnQ6IG51bWJlcik6IHZvaWQgfCBcIm1vcmVcIiB7XG4gICAgICAgICAgICBpZiAoIVNvY2tldEZ1bmN0aW9uLnNpbGVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBSZWNlaXZlZCBUQ1AgaGVhZGVyIHBhY2tldCBmcm9tICR7ZGVidWd9LCBoYXZlICR7YnVmZmVyLmxlbmd0aH0gYnl0ZXMgc28gZmFyLCAke3BhY2tldENvdW50fSBwYWNrZXRzYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBBbGwgSFRUUFMgcmVxdWVzdHMgc3RhcnQgd2l0aCAyMiwgYW5kIG5vIEhUVFAgcmVxdWVzdHMgc3RhcnQgd2l0aCAyMixcbiAgICAgICAgICAgIC8vICBzbyB3ZSBqdXN0IG5lZWQgdG8gcmVhZCB0aGUgZmlyc3QgYnl0ZS5cbiAgICAgICAgICAgIGxldCBzZXJ2ZXI6IGh0dHBzLlNlcnZlciB8IGh0dHAuU2VydmVyO1xuICAgICAgICAgICAgaWYgKGJ1ZmZlclswXSAhPT0gMjIpIHtcbiAgICAgICAgICAgICAgICBzZXJ2ZXIgPSBodHRwU2VydmVyO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsZXQgZGF0YSA9IHBhcnNlVExTSGVsbG8oYnVmZmVyKTtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5taXNzaW5nQnl0ZXMgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm1vcmVcIjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IHNuaSA9IGRhdGEuZXh0ZW5zaW9ucy5maWx0ZXIoeCA9PiB4LnR5cGUgPT09IFNOSVR5cGUpLmZsYXRNYXAoeCA9PiBwYXJzZVNOSUV4dGVuc2lvbih4LmRhdGEpKVswXTtcbiAgICAgICAgICAgICAgICBpZiAoIVNvY2tldEZ1bmN0aW9uLnNpbGVudCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgUmVjZWl2ZWQgVENQIGNvbm5lY3Rpb24gd2l0aCBTTkkgJHtKU09OLnN0cmluZ2lmeShzbmkpfS4gSGF2ZSBoYW5kbGVycyBmb3I6ICR7QXJyYXkuZnJvbShzbmlTZXJ2ZXJzLmtleXMoKSkuam9pbihcIiwgXCIpfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXNuaSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYE5vIFNOSSBmb3VuZCBpbiBUTFMgaGVsbG8gZnJvbSAke2RlYnVnfSwgdXNpbmcgbWFpbiBzZXJ2ZXIuIFBhY2tldHMgJHtwYWNrZXRDb3VudH1gKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYnVmZmVyLnRvU3RyaW5nKFwiYmFzZTY0XCIpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbGV0IG9yaWdpbmFsU05JID0gc25pO1xuICAgICAgICAgICAgICAgIGlmIChzbmkpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHN1YmRvbWFpbnMgdW50aWwgd2UgY2FuIGZpbmQgYSBkb21haW5cbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKCFzbmlTZXJ2ZXJzLmhhcyhzbmkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgcGFydHMgPSBzbmkuc3BsaXQoXCIuXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnRzLmxlbmd0aCA8PSAyKSBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIHNuaSA9IHBhcnRzLnNsaWNlKDEpLmpvaW4oXCIuXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFzbmlTZXJ2ZXJzLmhhcyhzbmkpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgTm8gU05JIHNlcnZlciBmb3VuZCBmb3IgJHtvcmlnaW5hbFNOSX0sIHVzaW5nIG1haW4gc2VydmVyLiBTTkkgY2FuZGlkYXRlcyAke0FycmF5LmZyb20oc25pU2VydmVycy5rZXlzKCkpLmpvaW4oXCIsIFwiKX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2VydmVyID0gc25pU2VydmVycy5nZXQoc25pKSB8fCBtYWluSFRUUFNTZXJ2ZXI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE5PVEU6IE1lc3NhZ2VzIGFyZW4ndCBkZXF1ZXVlZCB1bnRpbCB0aGUgY3VycmVudCBoYW5kbGVyIGZpbmlzaGVzLCBzbyB3ZSBkb24ndCBuZWVkIHRvIHBhdXNlIHRoZSBzb2NrZXQgb3IgYW55dGhpbmcuXG4gICAgICAgICAgICBzZXJ2ZXIuZW1pdChcImNvbm5lY3Rpb25cIiwgc29ja2V0KTtcbiAgICAgICAgICAgIHNvY2tldC51bnNoaWZ0KGJ1ZmZlcik7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGJ1ZmZlcnM6IEJ1ZmZlcltdID0gW107XG4gICAgICAgIGZ1bmN0aW9uIGdldE5leHREYXRhKCkge1xuICAgICAgICAgICAgLy8gTk9URTogT05DRSBpcyB1c2VkLCBzbyB3ZSBvbmx5IGxvb2sgYXQgdGhlIGZpcnN0IGJ1ZmZlciwgYW5kIHRoZW4gYWZ0ZXIgdGhhdFxuICAgICAgICAgICAgLy8gIHdlIHBpcGUuIFRoaXMgc2hvdWxkIGJlIHZlcnkgZWZmaWNpZW50LCBhcyBwaXBlIGhhcyBpbnNhbmUgdGhyb3VnaHB1dFxuICAgICAgICAgICAgLy8gICgxMDBzIG9mIE1CL3MsIGVhc2lseSwgZXZlbiBvbiBhIHRlcnJpYmxlIG1hY2hpbmUpLlxuICAgICAgICAgICAgc29ja2V0Lm9uY2UoXCJkYXRhXCIsIGJ1ZmZlciA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBidWZmZXIgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyID0gQnVmZmVyLmZyb20oYnVmZmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnVmZmVycy5wdXNoKGJ1ZmZlcik7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGhhbmRsZVRMU0hlbGxvKEJ1ZmZlci5jb25jYXQoYnVmZmVycyksIGJ1ZmZlcnMubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICBpZiAocmVzdWx0ID09PSBcIm1vcmVcIikge1xuICAgICAgICAgICAgICAgICAgICBnZXROZXh0RGF0YSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGdldE5leHREYXRhKCk7XG4gICAgICAgIHNvY2tldC5vbihcImVycm9yXCIsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBUQ1Agc29ja2V0IGVycm9yIGZvciAke2RlYnVnfSwgJHtlLnN0YWNrfWApO1xuICAgICAgICB9KTtcbiAgICAgICAgc29ja2V0Lm9uKFwiY2xvc2VcIiwgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFTb2NrZXRGdW5jdGlvbi5zaWxlbnQpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgVENQIHNvY2tldCBjbG9zZWQgZm9yICR7ZGVidWd9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0pO1xuXG5cbiAgICBsZXQgaG9zdCA9IGNvbmZpZy5wdWJsaWMgPyBcIjAuMC4wLjBcIiA6IFwiMTI3LjAuMC4xXCI7XG4gICAgaWYgKGNvbmZpZy5pcCkge1xuICAgICAgICBob3N0ID0gY29uZmlnLmlwO1xuICAgIH1cblxuICAgIGxldCBwb3J0ID0gY29uZmlnLnBvcnQ7XG4gICAgaWYgKCFTb2NrZXRGdW5jdGlvbi5zaWxlbnQpIHtcbiAgICAgICAgY29uc29sZS5sb2coeWVsbG93KGBUcnlpbmcgdG8gbGlzdGVuaW5nIG9uICR7aG9zdH06JHtwb3J0fWApKTtcbiAgICB9XG5cbiAgICBsZXQgbGlzdGVuaW5nUHJvbWlzZSA9IHdhaXRVbnRpbExpc3RlbmluZygpO1xuICAgIGxpc3RlbmluZ1Byb21pc2UuY2F0Y2goZSA9PiB7IH0pO1xuXG4gICAgLy8gUmV0dXJuIHRydWUgaWYgd2UgYXJlIGxpc3RlbmluZywgZmFsc2UgaWYgdGhlIGFkZHJlc3MgaXMgaW4gdXNlLCBhbmQgdGhyb3dzIG9uIG90aGVyIGVycm9yc1xuICAgIGFzeW5jIGZ1bmN0aW9uIHdhaXRVbnRpbExpc3RlbmluZygpIHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlPGJvb2xlYW4+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlYWxTZXJ2ZXIub25jZShcImVycm9yXCIsIGUgPT4ge1xuICAgICAgICAgICAgICAgIHJlamVjdChlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVhbFNlcnZlci5vbmNlKFwibGlzdGVuaW5nXCIsICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLnVzZUF2YWlsYWJsZVBvcnRJZlBvcnRJblVzZSAmJiBwb3J0KSB7XG4gICAgICAgIHJlYWxTZXJ2ZXIubGlzdGVuKHBvcnQsIGhvc3QpO1xuICAgICAgICBsZXQgaXNMaXN0ZW5pbmcgPSBhd2FpdCBuZXcgUHJvbWlzZTxib29sZWFuPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVhbFNlcnZlci5saXN0ZW5pbmcpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHRydWUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlYWxTZXJ2ZXIub25jZShcImVycm9yXCIsIGUgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlLm1lc3NhZ2UuaW5jbHVkZXMoXCJFQUREUklOVVNFXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVhbFNlcnZlci5vbmNlKFwibGlzdGVuaW5nXCIsICgpID0+IHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKGZhbHNlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFpc0xpc3RlbmluZykge1xuICAgICAgICAgICAgcG9ydCA9IDA7XG4gICAgICAgICAgICByZWFsU2VydmVyLmxpc3Rlbihwb3J0LCBob3N0KTtcbiAgICAgICAgICAgIGxpc3RlbmluZ1Byb21pc2UgPSB3YWl0VW50aWxMaXN0ZW5pbmcoKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJlYWxTZXJ2ZXIubGlzdGVuKHBvcnQsIGhvc3QpO1xuICAgIH1cblxuICAgIGF3YWl0IGxpc3RlbmluZ1Byb21pc2U7XG4gICAgcG9ydCA9IChyZWFsU2VydmVyLmFkZHJlc3MoKSBhcyBuZXQuQWRkcmVzc0luZm8pLnBvcnQ7XG5cbiAgICBpZiAoY29uZmlnLmF1dG9Gb3J3YXJkUG9ydCAmJiBjb25maWcucHVibGljKSB7XG4gICAgICAgIC8vIGxldCBleHRlcm5hbElQID0gYXdhaXQgZ2V0RXh0ZXJuYWxJUCgpO1xuICAgICAgICAvLyBsZXQgaXNMaXN0ZW5pbmcgPSBhd2FpdCB0ZXN0VENQSXNMaXN0ZW5pbmcoZXh0ZXJuYWxJUCwgcG9ydCk7XG4gICAgICAgIC8vIGlmICghaXNMaXN0ZW5pbmcpIHtcbiAgICAgICAgLy8gICAgIGNvbnNvbGUubG9nKG1hZ2VudGEoYFBvcnQgJHtwb3J0fSBpcyBub3QgZXh0ZXJuYWxseSByZWFjaGFibGUsIHRyeWluZyB0byBmb3J3YXJkIGl0YCkpO1xuICAgICAgICAvLyAgICAgYXdhaXQgZm9yd2FyZFBvcnQoeyBleHRlcm5hbFBvcnQ6IHBvcnQsIGludGVybmFsUG9ydDogcG9ydCB9KTtcbiAgICAgICAgLy8gfVxuICAgICAgICAvLyBFdmVuIGlmIHRoZXkgYXJlIGxpc3RlbmluZywgdGhleSBtaWdodCBub3Qgc3RheSBsaXN0ZW5pbmcuIEZvcndhcmQgZXZlcnkgOCBob3Vyc1xuICAgICAgICAvLyAgICAgIChpbmNsdWRpbmcgYXQgdGhlIHN0YXJ0LCBpbiBjYXNlIHRoZSBmb3J3YXJkIGlzIGFib3V0IHRvIGV4cGlyZSkuXG4gICAgICAgIGFzeW5jIGZ1bmN0aW9uIGZvcndhcmQoKSB7XG4gICAgICAgICAgICBhd2FpdCBmb3J3YXJkUG9ydCh7IGV4dGVybmFsUG9ydDogcG9ydCwgaW50ZXJuYWxQb3J0OiBwb3J0IH0pO1xuICAgICAgICAgICAgY29uc29sZS5sb2cobWFnZW50YShgRm9yd2FyZGVkIHBvcnQgJHtwb3J0fSB0byBvdXIgbWFjaGluZWApKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBFdmVyeSBob3VyLCBpbiBjYXNlIG91ciBuZXR3b3JrIGNvbmZpZ3VyYXRpb24gY2hhbmdlc1xuICAgICAgICBydW5JbmZpbml0ZVBvbGxDYWxsQXRTdGFydCh0aW1lSW5NaW51dGUgKiAzMCwgZm9yd2FyZCkuY2F0Y2goZSA9PiBjb25zb2xlLmVycm9yKHJlZChgRXJyb3IgaW4gcG9ydCBmb3J3YXJkaW5nICR7ZS5zdGFja31gKSkpO1xuICAgIH1cblxuICAgIGxldCBub2RlSWQgPSBnZXROb2RlSWQoZ2V0Q29tbW9uTmFtZShjb25maWcuY2VydCksIHBvcnQpO1xuICAgIGNvbnNvbGUubG9nKGdyZWVuKGBTdGFydGVkIExpc3RlbmluZyBvbiAke25vZGVJZH0gKCR7aG9zdH0pIGFmdGVyICR7Zm9ybWF0VGltZShwcm9jZXNzLnVwdGltZSgpICogMTAwMCl9YCkpO1xuXG4gICAgcmV0dXJuIG5vZGVJZDtcbn1cblxuZnVuY3Rpb24gZ2V0Q29tbW9uTmFtZShjZXJ0OiBCdWZmZXIgfCBzdHJpbmcpIHtcbiAgICBsZXQgc3ViamVjdCA9IG5ldyBjcnlwdG8uWDUwOUNlcnRpZmljYXRlKGNlcnQpLnN1YmplY3Q7XG4gICAgbGV0IHN1YmplY3RLVlBzID0gbmV3IE1hcChzdWJqZWN0LnNwbGl0KFwiLFwiKS5tYXAoeCA9PiB4LnRyaW0oKS5zcGxpdChcIj1cIikpLm1hcCh4ID0+IFt4WzBdLCB4LnNsaWNlKDEpLmpvaW4oXCI9XCIpXSkpO1xuICAgIGxldCBjb21tb25OYW1lID0gc3ViamVjdEtWUHMuZ2V0KFwiQ05cIik7XG4gICAgaWYgKCFjb21tb25OYW1lKSB0aHJvdyBuZXcgRXJyb3IoYE5vIGNvbW1vbiBuYW1lIGluIHN1YmplY3Q6ICR7c3ViamVjdH1gKTtcbiAgICByZXR1cm4gY29tbW9uTmFtZTtcbn1cbiJdfQ==
365
+ /* _JS_SOURCE_HASH = "85f78c2705c67c438736081567eb3903aa85954b6fdbf4bdce70f677349077ab"; */
@@ -0,0 +1,53 @@
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.createWebsocketFactory = exports.getTLSSocket = void 0;
4
+ const misc_1 = require("./misc");
5
+ const certStore_1 = require("./certStore");
6
+ const nodeCache_1 = require("./nodeCache");
7
+ const SocketFunction_1 = require("../SocketFunction");
8
+ function getTLSSocket(webSocket) {
9
+ return webSocket._socket;
10
+ }
11
+ exports.getTLSSocket = getTLSSocket;
12
+ /** NOTE: We create a factory, which embeds the key/cert information. Otherwise retries might use
13
+ * a different key/cert context.
14
+ */
15
+ function createWebsocketFactory() {
16
+ if (!(0, misc_1.isNode)()) {
17
+ return (nodeId, proposedProtocols) => {
18
+ let location = (0, nodeCache_1.getNodeIdLocation)(nodeId);
19
+ if (!location)
20
+ throw new Error(`Cannot connect to ${nodeId}, no address known`);
21
+ let { address, port } = location;
22
+ if (!SocketFunction_1.SocketFunction.silent) {
23
+ console.log(`Connecting to ${address}:${port}`);
24
+ }
25
+ if (proposedProtocols && proposedProtocols.length > 0) {
26
+ return new WebSocket(`wss://${address}:${port}`, proposedProtocols);
27
+ }
28
+ return new WebSocket(`wss://${address}:${port}`);
29
+ };
30
+ }
31
+ else {
32
+ return (nodeId, proposedProtocols) => {
33
+ let location = (0, nodeCache_1.getNodeIdLocation)(nodeId);
34
+ if (!location)
35
+ throw new Error(`Cannot connect to ${nodeId}, no address known`);
36
+ let { address, port } = location;
37
+ if (!SocketFunction_1.SocketFunction.silent) {
38
+ console.log(`Connecting to ${address}:${port}`);
39
+ }
40
+ const ws = require("ws");
41
+ let webSocket = new ws.WebSocket(`wss://${address}:${port}`, proposedProtocols, {
42
+ ca: (0, certStore_1.getTrustedCertificates)(),
43
+ });
44
+ // NOTE: Little setup is done here, because Sometimes websockets are created here,
45
+ // and sometimes via incoming connections, We should do most setup in
46
+ // CallFactory.ts:initializeWebsocket
47
+ return webSocket;
48
+ };
49
+ }
50
+ }
51
+ exports.createWebsocketFactory = createWebsocketFactory;
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0RmFjdG9yeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndlYnNvY2tldEZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsaUNBQWdDO0FBRWhDLDJDQUFxRDtBQUNyRCwyQ0FBZ0Q7QUFFaEQsc0RBQW1EO0FBR25ELFNBQWdCLFlBQVksQ0FBQyxTQUF1QjtJQUNoRCxPQUFRLFNBQWlCLENBQUMsT0FBd0IsQ0FBQztBQUN2RCxDQUFDO0FBRkQsb0NBRUM7QUFJRDs7R0FFRztBQUNILFNBQWdCLHNCQUFzQjtJQUVsQyxJQUFJLENBQUMsSUFBQSxhQUFNLEdBQUUsRUFBRSxDQUFDO1FBQ1osT0FBTyxDQUFDLE1BQWMsRUFBRSxpQkFBNEIsRUFBRSxFQUFFO1lBQ3BELElBQUksUUFBUSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLFFBQVE7Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsTUFBTSxvQkFBb0IsQ0FBQyxDQUFDO1lBQ2hGLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFDO1lBRWpDLElBQUksQ0FBQywrQkFBYyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN6QixPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixPQUFPLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBQ0QsSUFBSSxpQkFBaUIsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3BELE9BQU8sSUFBSSxTQUFTLENBQUMsU0FBUyxPQUFPLElBQUksSUFBSSxFQUFFLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztZQUN4RSxDQUFDO1lBQ0QsT0FBTyxJQUFJLFNBQVMsQ0FBQyxTQUFTLE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQ3JELENBQUMsQ0FBQztJQUNOLENBQUM7U0FBTSxDQUFDO1FBQ0osT0FBTyxDQUFDLE1BQWMsRUFBRSxpQkFBNEIsRUFBRSxFQUFFO1lBQ3BELElBQUksUUFBUSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsTUFBTSxDQUFDLENBQUM7WUFDekMsSUFBSSxDQUFDLFFBQVE7Z0JBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsTUFBTSxvQkFBb0IsQ0FBQyxDQUFDO1lBQ2hGLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFDO1lBRWpDLElBQUksQ0FBQywrQkFBYyxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUN6QixPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixPQUFPLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNwRCxDQUFDO1lBQ0QsTUFBTSxFQUFFLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBd0IsQ0FBQztZQUNoRCxJQUFJLFNBQVMsR0FBRyxJQUFJLEVBQUUsQ0FBQyxTQUFTLENBQUMsU0FBUyxPQUFPLElBQUksSUFBSSxFQUFFLEVBQUUsaUJBQWlCLEVBQUU7Z0JBQzVFLEVBQUUsRUFBRSxJQUFBLGtDQUFzQixHQUFFO2FBQy9CLENBQUMsQ0FBQztZQUVILGtGQUFrRjtZQUNsRiwwRUFBMEU7WUFDMUUsMENBQTBDO1lBRTFDLE9BQU8sU0FBUyxDQUFDO1FBQ3JCLENBQUMsQ0FBQztJQUNOLENBQUM7QUFDTCxDQUFDO0FBckNELHdEQXFDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0bHMgZnJvbSBcInRsc1wiO1xuaW1wb3J0IHsgaXNOb2RlIH0gZnJvbSBcIi4vbWlzY1wiO1xuaW1wb3J0IHsgU2VuZGVySW50ZXJmYWNlIH0gZnJvbSBcIi4vQ2FsbEZhY3RvcnlcIjtcbmltcG9ydCB7IGdldFRydXN0ZWRDZXJ0aWZpY2F0ZXMgfSBmcm9tIFwiLi9jZXJ0U3RvcmVcIjtcbmltcG9ydCB7IGdldE5vZGVJZExvY2F0aW9uIH0gZnJvbSBcIi4vbm9kZUNhY2hlXCI7XG5pbXBvcnQgZGVidWdicmVhayBmcm9tIFwiZGVidWdicmVha1wiO1xuaW1wb3J0IHsgU29ja2V0RnVuY3Rpb24gfSBmcm9tIFwiLi4vU29ja2V0RnVuY3Rpb25cIjtcbmltcG9ydCB0eXBlICogYXMgd3MgZnJvbSBcIndzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUTFNTb2NrZXQod2ViU29ja2V0OiB3cy5XZWJTb2NrZXQpIHtcbiAgICByZXR1cm4gKHdlYlNvY2tldCBhcyBhbnkpLl9zb2NrZXQgYXMgdGxzLlRMU1NvY2tldDtcbn1cblxuZXhwb3J0IHR5cGUgV2Vic29ja2V0RmFjdG9yeSA9IChub2RlSWQ6IHN0cmluZywgcHJvcG9zZWRQcm90b2NvbHM/OiBzdHJpbmdbXSkgPT4gU2VuZGVySW50ZXJmYWNlO1xuXG4vKiogTk9URTogV2UgY3JlYXRlIGEgZmFjdG9yeSwgd2hpY2ggZW1iZWRzIHRoZSBrZXkvY2VydCBpbmZvcm1hdGlvbi4gT3RoZXJ3aXNlIHJldHJpZXMgbWlnaHQgdXNlXG4gKiAgICAgIGEgZGlmZmVyZW50IGtleS9jZXJ0IGNvbnRleHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJzb2NrZXRGYWN0b3J5KCk6IFdlYnNvY2tldEZhY3Rvcnkge1xuXG4gICAgaWYgKCFpc05vZGUoKSkge1xuICAgICAgICByZXR1cm4gKG5vZGVJZDogc3RyaW5nLCBwcm9wb3NlZFByb3RvY29scz86IHN0cmluZ1tdKSA9PiB7XG4gICAgICAgICAgICBsZXQgbG9jYXRpb24gPSBnZXROb2RlSWRMb2NhdGlvbihub2RlSWQpO1xuICAgICAgICAgICAgaWYgKCFsb2NhdGlvbikgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29ubmVjdCB0byAke25vZGVJZH0sIG5vIGFkZHJlc3Mga25vd25gKTtcbiAgICAgICAgICAgIGxldCB7IGFkZHJlc3MsIHBvcnQgfSA9IGxvY2F0aW9uO1xuXG4gICAgICAgICAgICBpZiAoIVNvY2tldEZ1bmN0aW9uLnNpbGVudCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBDb25uZWN0aW5nIHRvICR7YWRkcmVzc306JHtwb3J0fWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHByb3Bvc2VkUHJvdG9jb2xzICYmIHByb3Bvc2VkUHJvdG9jb2xzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdlYlNvY2tldChgd3NzOi8vJHthZGRyZXNzfToke3BvcnR9YCwgcHJvcG9zZWRQcm90b2NvbHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5ldyBXZWJTb2NrZXQoYHdzczovLyR7YWRkcmVzc306JHtwb3J0fWApO1xuICAgICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiAobm9kZUlkOiBzdHJpbmcsIHByb3Bvc2VkUHJvdG9jb2xzPzogc3RyaW5nW10pID0+IHtcbiAgICAgICAgICAgIGxldCBsb2NhdGlvbiA9IGdldE5vZGVJZExvY2F0aW9uKG5vZGVJZCk7XG4gICAgICAgICAgICBpZiAoIWxvY2F0aW9uKSB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb25uZWN0IHRvICR7bm9kZUlkfSwgbm8gYWRkcmVzcyBrbm93bmApO1xuICAgICAgICAgICAgbGV0IHsgYWRkcmVzcywgcG9ydCB9ID0gbG9jYXRpb247XG5cbiAgICAgICAgICAgIGlmICghU29ja2V0RnVuY3Rpb24uc2lsZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYENvbm5lY3RpbmcgdG8gJHthZGRyZXNzfToke3BvcnR9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB3cyA9IHJlcXVpcmUoXCJ3c1wiKSBhcyB0eXBlb2YgaW1wb3J0KFwid3NcIik7XG4gICAgICAgICAgICBsZXQgd2ViU29ja2V0ID0gbmV3IHdzLldlYlNvY2tldChgd3NzOi8vJHthZGRyZXNzfToke3BvcnR9YCwgcHJvcG9zZWRQcm90b2NvbHMsIHtcbiAgICAgICAgICAgICAgICBjYTogZ2V0VHJ1c3RlZENlcnRpZmljYXRlcygpLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIE5PVEU6IExpdHRsZSBzZXR1cCBpcyBkb25lIGhlcmUsIGJlY2F1c2UgU29tZXRpbWVzIHdlYnNvY2tldHMgYXJlIGNyZWF0ZWQgaGVyZSxcbiAgICAgICAgICAgIC8vICAgICAgYW5kIHNvbWV0aW1lcyB2aWEgaW5jb21pbmcgY29ubmVjdGlvbnMsIFdlIHNob3VsZCBkbyBtb3N0IHNldHVwIGluXG4gICAgICAgICAgICAvLyAgICAgIENhbGxGYWN0b3J5LnRzOmluaXRpYWxpemVXZWJzb2NrZXRcblxuICAgICAgICAgICAgcmV0dXJuIHdlYlNvY2tldDtcbiAgICAgICAgfTtcbiAgICB9XG59XG4iXX0=
53
+ /* _JS_SOURCE_HASH = "cc6c144726cbe9b77a75d3be5d5b44d840387337e85b8dceb579d4a4efc7e33d"; */
@@ -0,0 +1,98 @@
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.hslSetSaturate = exports.hslAddSaturate = exports.hslDarkenLinear = exports.hslDarkenGamma = exports.hslLightenLinear = exports.hslLightenGamma = exports.hslToHex = exports.hslToRGB = exports.hslText = void 0;
4
+ function hslText(color) {
5
+ return `hsl(${color.h}, ${color.s}%, ${color.l}%)`;
6
+ }
7
+ exports.hslText = hslText;
8
+ function hslToRGB(color) {
9
+ let { h, s, l } = color;
10
+ h /= 360;
11
+ s /= 100;
12
+ l /= 100;
13
+ let r, g, b;
14
+ if (s === 0) {
15
+ r = g = b = l; // achromatic
16
+ }
17
+ else {
18
+ const hue2rgb = (p, q, t) => {
19
+ if (t < 0)
20
+ t += 1;
21
+ if (t > 1)
22
+ t -= 1;
23
+ if (t < 1 / 6)
24
+ return p + (q - p) * 6 * t;
25
+ if (t < 1 / 2)
26
+ return q;
27
+ if (t < 2 / 3)
28
+ return p + (q - p) * (2 / 3 - t) * 6;
29
+ return p;
30
+ };
31
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
32
+ const p = 2 * l - q;
33
+ r = hue2rgb(p, q, h + 1 / 3);
34
+ g = hue2rgb(p, q, h);
35
+ b = hue2rgb(p, q, h - 1 / 3);
36
+ if (b < 0) {
37
+ b = 0;
38
+ }
39
+ }
40
+ return { r: Math.floor(r * 255), g: Math.floor(g * 255), b: Math.floor(b * 255) };
41
+ }
42
+ exports.hslToRGB = hslToRGB;
43
+ function hslToHex(color) {
44
+ let { r, g, b } = hslToRGB(color);
45
+ const toHex = (x) => {
46
+ const hex = x.toString(16);
47
+ return hex.length === 1 ? "0" + hex : hex;
48
+ };
49
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
50
+ }
51
+ exports.hslToHex = hslToHex;
52
+ // Consider
53
+ function hslLightenGamma(hsl, fraction) {
54
+ let l = ((hsl.l ** 2) * (1 + fraction)) ** 0.5;
55
+ if (l > 255)
56
+ l = 255;
57
+ if (!l || l < 0)
58
+ l = 0;
59
+ return { h: hsl.h, s: hsl.s, l };
60
+ }
61
+ exports.hslLightenGamma = hslLightenGamma;
62
+ function hslLightenLinear(hsl, lightness) {
63
+ let l = hsl.l + lightness;
64
+ if (l > 255)
65
+ l = 255;
66
+ if (!l || l < 0)
67
+ l = 0;
68
+ return { h: hsl.h, s: hsl.s, l };
69
+ }
70
+ exports.hslLightenLinear = hslLightenLinear;
71
+ function hslDarkenGamma(hsl, fraction) {
72
+ return hslLightenGamma(hsl, -fraction);
73
+ }
74
+ exports.hslDarkenGamma = hslDarkenGamma;
75
+ function hslDarkenLinear(hsl, lightness) {
76
+ return hslLightenLinear(hsl, -lightness);
77
+ }
78
+ exports.hslDarkenLinear = hslDarkenLinear;
79
+ function hslAddSaturate(hsl, saturation) {
80
+ // If something has ZERO saturation, the color is meaningless, so increasing the saturation
81
+ // will likely not give the desired impact. Instead, darken the grey, which should give the desire effect.
82
+ if (hsl.s === 0) {
83
+ return hslDarkenGamma(hsl, 0.2);
84
+ }
85
+ return { h: hsl.h, s: hsl.s + saturation, l: hsl.l };
86
+ }
87
+ exports.hslAddSaturate = hslAddSaturate;
88
+ function hslSetSaturate(hsl, saturation) {
89
+ // If something has ZERO saturation, the color is meaningless, so increasing the saturation
90
+ // will likely not give the desired impact. Instead, set the lightness.
91
+ if (hsl.s === 0) {
92
+ return { h: hsl.h, s: hsl.s, l: 100 - saturation };
93
+ }
94
+ return { h: hsl.h, s: saturation, l: hsl.l };
95
+ }
96
+ exports.hslSetSaturate = hslSetSaturate;
97
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29sb3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLFNBQWdCLE9BQU8sQ0FBQyxLQUFVO0lBQzlCLE9BQU8sT0FBTyxLQUFLLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ3ZELENBQUM7QUFGRCwwQkFFQztBQUVELFNBQWdCLFFBQVEsQ0FBQyxLQUFVO0lBQy9CLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQztJQUN4QixDQUFDLElBQUksR0FBRyxDQUFDO0lBQ1QsQ0FBQyxJQUFJLEdBQUcsQ0FBQztJQUNULENBQUMsSUFBSSxHQUFHLENBQUM7SUFDVCxJQUFJLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ1osSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDVixDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxhQUFhO0lBQ2hDLENBQUM7U0FBTSxDQUFDO1FBQ0osTUFBTSxPQUFPLEdBQUcsQ0FBQyxDQUFTLEVBQUUsQ0FBUyxFQUFFLENBQVMsRUFBRSxFQUFFO1lBQ2hELElBQUksQ0FBQyxHQUFHLENBQUM7Z0JBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsQixJQUFJLENBQUMsR0FBRyxDQUFDO2dCQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUM7Z0JBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMxQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztnQkFBRSxPQUFPLENBQUMsQ0FBQztZQUN4QixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztnQkFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BELE9BQU8sQ0FBQyxDQUFDO1FBQ2IsQ0FBQyxDQUFDO1FBQ0YsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDcEIsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDN0IsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdCLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ1IsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNWLENBQUM7SUFDTCxDQUFDO0lBQ0QsT0FBTyxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7QUFDdEYsQ0FBQztBQTNCRCw0QkEyQkM7QUFFRCxTQUFnQixRQUFRLENBQUMsS0FBVTtJQUMvQixJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbEMsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUN4QixNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzNCLE9BQU8sR0FBRyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUM5QyxDQUFDLENBQUM7SUFDRixPQUFPLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztBQUNoRCxDQUFDO0FBUEQsNEJBT0M7QUFFRCxZQUFZO0FBQ1osU0FBZ0IsZUFBZSxDQUFDLEdBQVEsRUFBRSxRQUFnQjtJQUN0RCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQztJQUMvQyxJQUFJLENBQUMsR0FBRyxHQUFHO1FBQUUsQ0FBQyxHQUFHLEdBQUcsQ0FBQztJQUNyQixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN2QixPQUFPLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7QUFDckMsQ0FBQztBQUxELDBDQUtDO0FBQ0QsU0FBZ0IsZ0JBQWdCLENBQUMsR0FBUSxFQUFFLFNBQWlCO0lBQ3hELElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsU0FBUyxDQUFDO0lBQzFCLElBQUksQ0FBQyxHQUFHLEdBQUc7UUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO0lBQ3JCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7UUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZCLE9BQU8sRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUNyQyxDQUFDO0FBTEQsNENBS0M7QUFDRCxTQUFnQixjQUFjLENBQUMsR0FBUSxFQUFFLFFBQWdCO0lBQ3JELE9BQU8sZUFBZSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBQzNDLENBQUM7QUFGRCx3Q0FFQztBQUNELFNBQWdCLGVBQWUsQ0FBQyxHQUFRLEVBQUUsU0FBaUI7SUFDdkQsT0FBTyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUM3QyxDQUFDO0FBRkQsMENBRUM7QUFFRCxTQUFnQixjQUFjLENBQUMsR0FBUSxFQUFFLFVBQWtCO0lBQ3ZELDJGQUEyRjtJQUMzRiwyR0FBMkc7SUFDM0csSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ2QsT0FBTyxjQUFjLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsVUFBVSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDekQsQ0FBQztBQVBELHdDQU9DO0FBQ0QsU0FBZ0IsY0FBYyxDQUFDLEdBQVEsRUFBRSxVQUFrQjtJQUN2RCwyRkFBMkY7SUFDM0Ysd0VBQXdFO0lBQ3hFLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUNkLE9BQU8sRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxHQUFHLFVBQVUsRUFBRSxDQUFDO0lBQ3ZELENBQUM7SUFDRCxPQUFPLEVBQUUsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO0FBQ2pELENBQUM7QUFQRCx3Q0FPQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIEhTTCA9IHsgaDogbnVtYmVyLCBzOiBudW1iZXIsIGw6IG51bWJlciB9O1xuZXhwb3J0IGZ1bmN0aW9uIGhzbFRleHQoY29sb3I6IEhTTCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBoc2woJHtjb2xvci5ofSwgJHtjb2xvci5zfSUsICR7Y29sb3IubH0lKWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoc2xUb1JHQihjb2xvcjogSFNMKSB7XG4gICAgbGV0IHsgaCwgcywgbCB9ID0gY29sb3I7XG4gICAgaCAvPSAzNjA7XG4gICAgcyAvPSAxMDA7XG4gICAgbCAvPSAxMDA7XG4gICAgbGV0IHIsIGcsIGI7XG4gICAgaWYgKHMgPT09IDApIHtcbiAgICAgICAgciA9IGcgPSBiID0gbDsgLy8gYWNocm9tYXRpY1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGh1ZTJyZ2IgPSAocDogbnVtYmVyLCBxOiBudW1iZXIsIHQ6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgaWYgKHQgPCAwKSB0ICs9IDE7XG4gICAgICAgICAgICBpZiAodCA+IDEpIHQgLT0gMTtcbiAgICAgICAgICAgIGlmICh0IDwgMSAvIDYpIHJldHVybiBwICsgKHEgLSBwKSAqIDYgKiB0O1xuICAgICAgICAgICAgaWYgKHQgPCAxIC8gMikgcmV0dXJuIHE7XG4gICAgICAgICAgICBpZiAodCA8IDIgLyAzKSByZXR1cm4gcCArIChxIC0gcCkgKiAoMiAvIDMgLSB0KSAqIDY7XG4gICAgICAgICAgICByZXR1cm4gcDtcbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgcSA9IGwgPCAwLjUgPyBsICogKDEgKyBzKSA6IGwgKyBzIC0gbCAqIHM7XG4gICAgICAgIGNvbnN0IHAgPSAyICogbCAtIHE7XG4gICAgICAgIHIgPSBodWUycmdiKHAsIHEsIGggKyAxIC8gMyk7XG4gICAgICAgIGcgPSBodWUycmdiKHAsIHEsIGgpO1xuICAgICAgICBiID0gaHVlMnJnYihwLCBxLCBoIC0gMSAvIDMpO1xuICAgICAgICBpZiAoYiA8IDApIHtcbiAgICAgICAgICAgIGIgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IHI6IE1hdGguZmxvb3IociAqIDI1NSksIGc6IE1hdGguZmxvb3IoZyAqIDI1NSksIGI6IE1hdGguZmxvb3IoYiAqIDI1NSkgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhzbFRvSGV4KGNvbG9yOiBIU0wpIHtcbiAgICBsZXQgeyByLCBnLCBiIH0gPSBoc2xUb1JHQihjb2xvcik7XG4gICAgY29uc3QgdG9IZXggPSAoeDogbnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IGhleCA9IHgudG9TdHJpbmcoMTYpO1xuICAgICAgICByZXR1cm4gaGV4Lmxlbmd0aCA9PT0gMSA/IFwiMFwiICsgaGV4IDogaGV4O1xuICAgIH07XG4gICAgcmV0dXJuIGAjJHt0b0hleChyKX0ke3RvSGV4KGcpfSR7dG9IZXgoYil9YDtcbn1cblxuLy8gQ29uc2lkZXIgXG5leHBvcnQgZnVuY3Rpb24gaHNsTGlnaHRlbkdhbW1hKGhzbDogSFNMLCBmcmFjdGlvbjogbnVtYmVyKSB7XG4gICAgbGV0IGwgPSAoKGhzbC5sICoqIDIpICogKDEgKyBmcmFjdGlvbikpICoqIDAuNTtcbiAgICBpZiAobCA+IDI1NSkgbCA9IDI1NTtcbiAgICBpZiAoIWwgfHwgbCA8IDApIGwgPSAwO1xuICAgIHJldHVybiB7IGg6IGhzbC5oLCBzOiBoc2wucywgbCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGhzbExpZ2h0ZW5MaW5lYXIoaHNsOiBIU0wsIGxpZ2h0bmVzczogbnVtYmVyKSB7XG4gICAgbGV0IGwgPSBoc2wubCArIGxpZ2h0bmVzcztcbiAgICBpZiAobCA+IDI1NSkgbCA9IDI1NTtcbiAgICBpZiAoIWwgfHwgbCA8IDApIGwgPSAwO1xuICAgIHJldHVybiB7IGg6IGhzbC5oLCBzOiBoc2wucywgbCB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGhzbERhcmtlbkdhbW1hKGhzbDogSFNMLCBmcmFjdGlvbjogbnVtYmVyKSB7XG4gICAgcmV0dXJuIGhzbExpZ2h0ZW5HYW1tYShoc2wsIC1mcmFjdGlvbik7XG59XG5leHBvcnQgZnVuY3Rpb24gaHNsRGFya2VuTGluZWFyKGhzbDogSFNMLCBsaWdodG5lc3M6IG51bWJlcikge1xuICAgIHJldHVybiBoc2xMaWdodGVuTGluZWFyKGhzbCwgLWxpZ2h0bmVzcyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoc2xBZGRTYXR1cmF0ZShoc2w6IEhTTCwgc2F0dXJhdGlvbjogbnVtYmVyKSB7XG4gICAgLy8gSWYgc29tZXRoaW5nIGhhcyBaRVJPIHNhdHVyYXRpb24sIHRoZSBjb2xvciBpcyBtZWFuaW5nbGVzcywgc28gaW5jcmVhc2luZyB0aGUgc2F0dXJhdGlvblxuICAgIC8vICB3aWxsIGxpa2VseSBub3QgZ2l2ZSB0aGUgZGVzaXJlZCBpbXBhY3QuIEluc3RlYWQsIGRhcmtlbiB0aGUgZ3JleSwgd2hpY2ggc2hvdWxkIGdpdmUgdGhlIGRlc2lyZSBlZmZlY3QuXG4gICAgaWYgKGhzbC5zID09PSAwKSB7XG4gICAgICAgIHJldHVybiBoc2xEYXJrZW5HYW1tYShoc2wsIDAuMik7XG4gICAgfVxuICAgIHJldHVybiB7IGg6IGhzbC5oLCBzOiBoc2wucyArIHNhdHVyYXRpb24sIGw6IGhzbC5sIH07XG59XG5leHBvcnQgZnVuY3Rpb24gaHNsU2V0U2F0dXJhdGUoaHNsOiBIU0wsIHNhdHVyYXRpb246IG51bWJlcikge1xuICAgIC8vIElmIHNvbWV0aGluZyBoYXMgWkVSTyBzYXR1cmF0aW9uLCB0aGUgY29sb3IgaXMgbWVhbmluZ2xlc3MsIHNvIGluY3JlYXNpbmcgdGhlIHNhdHVyYXRpb25cbiAgICAvLyAgd2lsbCBsaWtlbHkgbm90IGdpdmUgdGhlIGRlc2lyZWQgaW1wYWN0LiBJbnN0ZWFkLCBzZXQgdGhlIGxpZ2h0bmVzcy5cbiAgICBpZiAoaHNsLnMgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHsgaDogaHNsLmgsIHM6IGhzbC5zLCBsOiAxMDAgLSBzYXR1cmF0aW9uIH07XG4gICAgfVxuICAgIHJldHVybiB7IGg6IGhzbC5oLCBzOiBzYXR1cmF0aW9uLCBsOiBoc2wubCB9O1xufSJdfQ==
98
+ /* _JS_SOURCE_HASH = "5f6264067db0d8d369dfb586ba7d3a1cb3888a1196a6dac4c9ef6c835b2337cc"; */