sliftutils 1.7.10 → 1.7.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/examplestorage/exampleserver.ts +0 -2
  2. package/index.d.ts +290 -54
  3. package/misc/dist/environment.ts.cache +3 -3
  4. package/misc/dist/getSecret.ts.cache +139 -0
  5. package/misc/dist/strings.ts.cache +13 -0
  6. package/misc/dist/zip.ts.cache +9 -0
  7. package/misc/getSecret.ts +38 -16
  8. package/misc/https/cloudflareHelpers.d.ts +19 -0
  9. package/misc/https/cloudflareHelpers.ts +69 -0
  10. package/misc/https/dist/certs.ts.cache +115 -179
  11. package/misc/https/dist/cloudflareHelpers.ts.cache +68 -0
  12. package/misc/https/dist/dns.ts.cache +112 -100
  13. package/misc/https/dist/hostServer.ts.cache +130 -0
  14. package/misc/https/dist/httpsCerts.ts.cache +24 -5
  15. package/misc/https/dist/persistentLocalStorage.ts.cache +3 -2
  16. package/misc/https/dns.d.ts +41 -12
  17. package/misc/https/dns.ts +104 -101
  18. package/misc/https/hostServer.d.ts +0 -6
  19. package/misc/https/hostServer.ts +9 -5
  20. package/package.json +2 -2
  21. package/render-utils/dist/observer.tsx.cache +3 -2
  22. package/spec.txt +0 -90
  23. package/storage/ArchivesDisk.d.ts +2 -0
  24. package/storage/ArchivesDisk.ts +7 -3
  25. package/storage/BulkDatabase2/dist/BulkDatabaseBase.ts.cache +1242 -0
  26. package/storage/BulkDatabase2/dist/BulkDatabaseFormat.ts.cache +513 -0
  27. package/storage/BulkDatabase2/dist/BulkDatabaseMerge.ts.cache +352 -0
  28. package/storage/BulkDatabase2/dist/BulkDatabaseReader.ts.cache +306 -0
  29. package/storage/BulkDatabase2/dist/LoadedIndex.ts.cache +435 -0
  30. package/storage/BulkDatabase2/dist/WriteOverlay.ts.cache +58 -0
  31. package/storage/BulkDatabase2/dist/blockCache.ts.cache +179 -0
  32. package/storage/BulkDatabase2/dist/mergeLock.ts.cache +149 -0
  33. package/storage/BulkDatabase2/dist/mergeMarkers.ts.cache +101 -0
  34. package/storage/BulkDatabase2/dist/streamLog.ts.cache +227 -0
  35. package/storage/BulkDatabase2/dist/syncClient.ts.cache +104 -0
  36. package/storage/IArchives.d.ts +47 -15
  37. package/storage/IArchives.ts +86 -31
  38. package/storage/backblaze.d.ts +15 -0
  39. package/storage/backblaze.ts +199 -79
  40. package/storage/dist/ArchivesDisk.ts.cache +373 -0
  41. package/storage/dist/FileFolderAPI.tsx.cache +508 -65
  42. package/storage/dist/IArchives.ts.cache +44 -0
  43. package/storage/dist/IndexedDBFileFolderAPI.ts.cache +8 -2
  44. package/storage/dist/JSONStorage.ts.cache +6 -2
  45. package/storage/dist/PendingManager.tsx.cache +1 -1
  46. package/storage/dist/TransactionStorage.ts.cache +231 -92
  47. package/storage/dist/backblaze.ts.cache +797 -0
  48. package/storage/dist/fileSystemPointer.ts.cache +36 -3
  49. package/storage/dist/remoteFileStorage.ts.cache +495 -0
  50. package/storage/remoteStorage/ArchivesRemote.d.ts +5 -1
  51. package/storage/remoteStorage/ArchivesRemote.ts +28 -8
  52. package/storage/remoteStorage/ArchivesUrl.d.ts +2 -0
  53. package/storage/remoteStorage/ArchivesUrl.ts +16 -4
  54. package/storage/remoteStorage/blobStore.d.ts +52 -3
  55. package/storage/remoteStorage/blobStore.ts +414 -101
  56. package/storage/remoteStorage/createArchives.d.ts +31 -10
  57. package/storage/remoteStorage/createArchives.ts +470 -253
  58. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +197 -0
  59. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +85 -0
  60. package/storage/remoteStorage/dist/accessPage.tsx.cache +222 -0
  61. package/storage/remoteStorage/dist/blobStore.ts.cache +837 -0
  62. package/storage/remoteStorage/dist/cliArgs.ts.cache +16 -0
  63. package/storage/remoteStorage/dist/createArchives.ts.cache +610 -0
  64. package/storage/remoteStorage/dist/remoteConfig.ts.cache +206 -0
  65. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +223 -0
  66. package/storage/remoteStorage/dist/storageController.ts.cache +500 -0
  67. package/storage/remoteStorage/dist/storageServer.ts.cache +106 -0
  68. package/storage/remoteStorage/dist/storageServerCli.ts.cache +39 -0
  69. package/storage/remoteStorage/dist/storageServerState.ts.cache +518 -0
  70. package/storage/remoteStorage/remoteConfig.d.ts +8 -0
  71. package/storage/remoteStorage/remoteConfig.ts +105 -5
  72. package/storage/remoteStorage/sourceWrapper.d.ts +41 -0
  73. package/storage/remoteStorage/sourceWrapper.ts +223 -0
  74. package/storage/remoteStorage/spec.md +31 -0
  75. package/storage/remoteStorage/storageController.d.ts +11 -0
  76. package/storage/remoteStorage/storageController.ts +109 -40
  77. package/storage/remoteStorage/storageServer.d.ts +0 -5
  78. package/storage/remoteStorage/storageServer.ts +17 -10
  79. package/storage/remoteStorage/storageServerCli.ts +0 -3
  80. package/storage/remoteStorage/storageServerState.d.ts +7 -1
  81. package/storage/remoteStorage/storageServerState.ts +230 -48
  82. package/testsite/server.ts +0 -2
  83. package/yarn.lock +11 -6
@@ -27,13 +27,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  return (mod && mod.__esModule && mod.default) ? mod : { "default": mod };
28
28
  };
29
29
  Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
30
- exports.getOwnNodeIdAllowUndefined = exports.getOwnNodeId = exports.createTestBrowserKeyCert = exports.getThreadKeyCert = exports.verifyMachineIdForPublicKey = exports.getOwnMachineId = exports.getIdentityCAPromise = exports.getIdentityCA = exports.loadIdentityCA = exports.setIdentityCARaw = exports.encodeNodeId = exports.decodeNodeIdAssert = exports.decodeNodeId = exports.getMachineId = exports.createCertFromCA = exports.generateTestCA = exports.generateRSAKeyPair = exports.generateKeyPair = exports.validateCertificate = exports.validateCACert = exports.verify = exports.sign = exports.getPublicIdentifier = exports.parseCert = exports.privateKeyToPem = exports.createX509 = exports.getCommonName = exports.identityStorageKey = exports.CA_NOT_FOUND_ERROR = void 0;
30
+ exports.getOwnNodeIdAllowUndefined = exports.getOwnNodeId = exports.getThreadKeyCert = exports.verifyMachineIdForPublicKey = exports.getOwnThreadId = exports.getOwnMachineId = exports.getIdentityCAPromise = exports.getIdentityCA = exports.loadIdentityCA = exports.setIdentityCARaw = exports.encodeNodeId = exports.decodeNodeIdAssert = exports.decodeNodeId = exports.getMachineId = exports.createCertFromCA = exports.generateTestCA = exports.generateKeyPair = exports.validateCertificate = exports.validateCACert = exports.verify = exports.sign = exports.getPublicIdentifier = exports.parseCert = exports.privateKeyToPem = exports.createX509 = exports.getCommonName = exports.identityStorageKey = exports.CA_NOT_FOUND_ERROR = void 0;
31
31
  module.allowclient = true;
32
+ // NOTE: We can't use crypto.subtle (non-extractable CryptoKeys) for our keys, because subtle is asynchronous, and everything here (key generation, cert creation, signing) must be available synchronously. The only real benefit of subtle is that a cross-site scripting attack can't exfiltrate the key. Which, while nice, is of minor benefit, as the cross-site script can already do quite a bit of damage anyway with access. And if that happens, the first thing the user is probably going to do is reset all their credentials, which solves the case of the key being exfiltrated anyway (by telling the server to stop trusting all identities).
33
+ // NOTE: We are just not going to support HTTPS browser certs. Our code is purely for identification, and so it only supports ED25519.
32
34
  // https://www.rfc-editor.org/rfc/rfc5280#page-42
33
35
  const compileFlags_1 = require("socket-function/require/compileFlags");
34
36
  const forge = __importStar(require("node-forge"));
35
37
  const caching_1 = require("socket-function/src/caching");
36
- const misc_1 = require("socket-function/src/misc");
37
38
  const js_sha256_1 = __importDefault(require("js-sha256"));
38
39
  const crypto_1 = __importDefault(require("crypto"));
39
40
  const certStore_1 = require("socket-function/src/certStore");
@@ -42,11 +43,12 @@ const nodeCache_1 = require("socket-function/src/nodeCache");
42
43
  const SocketFunction_1 = require("socket-function/SocketFunction");
43
44
  const nodeCache_2 = require("socket-function/src/nodeCache");
44
45
  const persistentLocalStorage_1 = require("./persistentLocalStorage");
46
+ const strings_1 = require("../strings");
45
47
  (0, compileFlags_1.setFlag)(require, "node-forge", "allowclient", true);
46
48
  (0, compileFlags_1.setFlag)(require, "js-sha256", "allowclient", true);
47
49
  const timeInDay = 1000 * 60 * 60 * 24;
48
50
  exports.CA_NOT_FOUND_ERROR = "18aa7318-f88f-4d2d-b41f-3daf4a433827";
49
- exports.identityStorageKey = "machineCA_10";
51
+ exports.identityStorageKey = "machineCA_14";
50
52
  function getIdentityStore(domain) {
51
53
  return (0, persistentLocalStorage_1.getKeyStore)(domain, exports.identityStorageKey);
52
54
  }
@@ -65,10 +67,7 @@ function createX509(config) {
65
67
  let certObj = forge.pki.createCertificate();
66
68
  certObj.publicKey = keyPair.publicKey;
67
69
  certObj.serialNumber = "01";
68
- // Give it 5 minutes before now. If we give it too much time, it can look like the cert is really
69
- // old, which will trigger various processes to try to get a fresher one (as if it lasts for
70
- // 1 hour, but we set notBefore to 1 month ago, it looks 1 month old, and so almost expired,
71
- // when it isn't...)
70
+ // Give it 5 minutes before now. If we give it too much time, it can look like the cert is really old, which will trigger various processes to try to get a fresher one (as if it lasts for 1 hour, but we set notBefore to 1 month ago, it looks 1 month old, and so almost expired, when it isn't...)
72
71
  certObj.validity.notBefore = new Date(Date.now() - 1000 * 60 * 5);
73
72
  certObj.validity.notAfter = new Date(Date.now() + lifeSpan);
74
73
  const commonNameAttrs = [{ name: "commonName", value: domain }];
@@ -94,34 +93,25 @@ function createX509(config) {
94
93
  { type: 2, value: domain },
95
94
  { type: 2, value: "*." + domain },
96
95
  { type: 2, value: localHostDomain },
97
- // NOTE: No longer allow 127.0.0.1, to make this more secure. We might enable this
98
- // behavior behind a flag, for development.
99
- //{ type: 7, ip: "127.0.0.1" }
96
+ // NOTE: No longer allow 127.0.0.1 ({ type: 7, ip: "127.0.0.1" }), to make this more secure. We might enable this behavior behind a flag, for development.
97
+ ]
98
+ },
99
+ // NOTE: nameConstraints require our forked node-forge ("node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6"). Chrome ignores them (https://bugs.chromium.org/p/chromium/issues/detail?id=1072083), but our own validation (validateCACert/validateCertificate) enforces them.
100
+ {
101
+ name: "nameConstraints",
102
+ permittedSubtrees: [
103
+ { type: 2, value: forge.util.encodeUtf8(domain) },
104
+ { type: 2, value: forge.util.encodeUtf8(localHostDomain) },
100
105
  ]
101
106
  },
102
- // NOTE: nameConstraints are supported with our branch. But... chrome doesn't support them, so there's no point in using them.
103
- // "node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
104
- // {
105
- // name: "nameConstraints",
106
- // permittedSubtrees: [
107
- // // Chrome doesn't respect nameConstraints per https://bugs.chromium.org/p/chromium/issues/detail?id=1072083,
108
- // // as the spec decided that "free to process or ignore such information" (when present in self
109
- // // signed certificates), and therefore the chrome implementation decided "The first order is to behave predictably",
110
- // // so... they're not going to support it, because why have a feature in one place, if it isn't
111
- // // on android as well... ugh...
112
- // // Works fine on Edge though
113
- // { type: 2, value: forge.util.encodeUtf8(domain) },
114
- // { type: 2, value: forge.util.encodeUtf8(localHostDomain) },
115
- // ]
116
- // },
117
107
  ]);
118
108
  certObj.setExtensions(extensions);
119
109
  (0, measure_1.measureBlock)(function sign() {
120
110
  if (issuer === "self") {
121
- certObj.sign(keyPair.privateKey, forge.md.sha256.create());
111
+ certObj.sign(keyPair.privateKey);
122
112
  }
123
113
  else {
124
- certObj.sign(privateKeyFromPem(issuer.key.toString()), forge.md.sha256.create());
114
+ certObj.sign(forge.ed25519.privateKeyFromPem(issuer.key.toString()));
125
115
  }
126
116
  });
127
117
  return (0, measure_1.measureBlock)(function toPems() {
@@ -134,65 +124,39 @@ function createX509(config) {
134
124
  });
135
125
  }
136
126
  exports.createX509 = createX509;
137
- function privateKeyToPem(buffer) {
138
- if ("privateKeyBytes" in buffer) {
139
- return forge.ed25519.privateKeyToPem(buffer);
140
- }
141
- return forge.pki.privateKeyToPem(buffer);
127
+ function privateKeyToPem(key) {
128
+ return forge.ed25519.privateKeyToPem(key);
142
129
  }
143
130
  exports.privateKeyToPem = privateKeyToPem;
144
- function privateKeyFromPem(pem) {
145
- // We want to guess the type correctly, as caught exceptions make debugging annoying
146
- if (pem.length < 200) {
147
- try {
148
- return forge.ed25519.privateKeyFromPem(pem);
149
- }
150
- catch (_a) { }
151
- }
152
- try {
153
- return forge.pki.privateKeyFromPem(pem);
154
- }
155
- catch (_b) {
156
- return forge.ed25519.privateKeyFromPem(pem);
157
- }
158
- }
159
- function publicKeyFromCert(cert) {
160
- return parseCert(cert).publicKey;
161
- }
162
131
  function parseCert(PEMorDER) {
163
132
  return forge.pki.certificateFromPem(normalizeCertToPEM(PEMorDER));
164
133
  }
165
134
  exports.parseCert = parseCert;
135
+ function getED25519PublicKey(certParsed) {
136
+ var _a;
137
+ let publicKey = certParsed.publicKey;
138
+ if (!("publicKeyBytes" in publicKey)) {
139
+ throw new Error(`Only ED25519 certificates are supported, the certificate public key is not ED25519 (subject: ${(_a = certParsed.subject.getField("CN")) === null || _a === void 0 ? void 0 : _a.value})`);
140
+ }
141
+ return publicKey;
142
+ }
166
143
  // Gets a unique value to represent the public key
167
144
  function getPublicIdentifier(PEMorDER) {
168
- let obj = parseCert(PEMorDER);
169
- let publicKey = obj.publicKey;
170
- if ("publicKeyBytes" in publicKey) {
171
- return Buffer.from(publicKey.publicKeyBytes);
172
- }
173
- return Buffer.from(new Uint32Array(publicKey.n.data).buffer);
145
+ return Buffer.from(getED25519PublicKey(parseCert(PEMorDER)).publicKeyBytes);
174
146
  }
175
147
  exports.getPublicIdentifier = getPublicIdentifier;
176
- function isED25519(key) {
177
- return key.length < 256;
178
- }
179
- // EQUIVALENT TO: `crypto.createSign("SHA256").update(JSON.stringify(payload)).sign(keyCert.key, "binary")`
180
148
  exports.sign = (0, measure_1.measureWrap)(function sign(keyPair, data) {
181
149
  let dataStr = JSON.stringify(data);
182
- if (isED25519(keyPair.key)) {
183
- let privateKey = forge.pki.ed25519.privateKeyFromPem(keyPair.key.toString());
184
- return privateKey.sign(dataStr);
185
- }
186
- else {
187
- let privateKey = forge.pki.privateKeyFromPem(keyPair.key.toString());
188
- const md = forge.md.sha256.create();
189
- md.update(dataStr);
190
- return privateKey.sign(md);
191
- }
150
+ let privateKey = forge.ed25519.privateKeyFromPem(keyPair.key.toString());
151
+ return privateKey.sign(dataStr);
192
152
  });
193
153
  function verify(cert, signature, data) {
194
154
  let certObj = parseCert(cert);
195
- return certObj.publicKey.verify(JSON.stringify(data), signature);
155
+ let publicKey = getED25519PublicKey(certObj);
156
+ let dataStr = JSON.stringify(data);
157
+ if (!publicKey.verify(dataStr, signature)) {
158
+ throw new Error(`Signature verification failed. Signature: ${JSON.stringify(signature)} | Data: ${(0, strings_1.ellipsize)(dataStr, 1024)}`);
159
+ }
196
160
  }
197
161
  exports.verify = verify;
198
162
  function normalizeCertToPEM(PEMorDER) {
@@ -202,18 +166,34 @@ function normalizeCertToPEM(PEMorDER) {
202
166
  PEMorDER = PEMorDER.toString("base64");
203
167
  return "-----BEGIN CERTIFICATE-----\n" + PEMorDER + "\n-----END CERTIFICATE-----";
204
168
  }
169
+ // Base32 (RFC 4648, lowercase, unpadded), as domain names are case-insensitive, which rules out base64/hex-with-case
170
+ const base32Alphabet = "abcdefghijklmnopqrstuvwxyz234567";
171
+ function encodeBase32(bytes) {
172
+ let result = "";
173
+ let bitCount = 0;
174
+ let value = 0;
175
+ for (let byte of bytes) {
176
+ value = (value << 8) | byte;
177
+ bitCount += 8;
178
+ while (bitCount >= 5) {
179
+ result += base32Alphabet[(value >>> (bitCount - 5)) & 31];
180
+ bitCount -= 5;
181
+ }
182
+ }
183
+ if (bitCount > 0) {
184
+ result += base32Alphabet[(value << (5 - bitCount)) & 31];
185
+ }
186
+ return result;
187
+ }
205
188
  function getDomainPartFromPublicKey(publicKey) {
206
189
  let bytes;
207
190
  if ("publicKeyBytes" in publicKey) {
208
191
  bytes = publicKey.publicKeyBytes;
209
192
  }
210
- else if (publicKey instanceof Buffer) {
211
- bytes = publicKey;
212
- }
213
193
  else {
214
- bytes = Buffer.from(new Uint32Array(publicKey.n.data).buffer);
194
+ bytes = publicKey;
215
195
  }
216
- return "b" + js_sha256_1.default.sha256(Buffer.from(bytes)).slice(0, 16).replaceAll("+", "-").replaceAll("/", "_");
196
+ return "b" + encodeBase32(Buffer.from(js_sha256_1.default.sha256.array(Buffer.from(bytes)))).slice(0, 20);
217
197
  }
218
198
  function validateCACert(domain, cert) {
219
199
  let certParsed = parseCert(cert);
@@ -222,9 +202,7 @@ function validateCACert(domain, cert) {
222
202
  let domainParts = subject.split(".").reverse();
223
203
  let rootDomainParsed = [domainParts.shift(), domainParts.shift()].reverse().join(".");
224
204
  if (rootDomainParsed !== domain) {
225
- // This is important, as our trust store contains more then just OUR certificates,
226
- // so if we allow any domains then real domains can impersonate anyone! It has to
227
- // be one OUR domain to be trusted!
205
+ // This is important, as our trust store contains more then just OUR certificates, so if we allow any domains then real domains can impersonate anyone! It has to be OUR domain to be trusted!
228
206
  throw new Error(`Certificate root domain should be ${domain}, but is ${rootDomainParsed}`);
229
207
  }
230
208
  // TODO: Maybe just skip if it isn't a hash string?
@@ -232,7 +210,7 @@ function validateCACert(domain, cert) {
232
210
  domainParts.shift();
233
211
  }
234
212
  let certExpectedPublicKeyPart = (domainParts.shift() || "").split("-").slice(-1)[0];
235
- let certActualPublicKeyPart = getDomainPartFromPublicKey(certParsed.publicKey);
213
+ let certActualPublicKeyPart = getDomainPartFromPublicKey(getED25519PublicKey(certParsed));
236
214
  if (certExpectedPublicKeyPart !== certActualPublicKeyPart) {
237
215
  throw new Error(`Certificate public key in the url is ${certExpectedPublicKeyPart}, but in the cert is ${certActualPublicKeyPart}`);
238
216
  }
@@ -246,8 +224,7 @@ function validateCACert(domain, cert) {
246
224
  throw new Error(`Certificate must have nameConstraints.permittedSubtrees`);
247
225
  }
248
226
  let subtreeValues = subtrees.map((x) => x.value);
249
- // Ignore localhostDomain, as it can always safely be allowed (the same machine
250
- // is always allowed).
227
+ // Ignore localhostDomain, as it can always safely be allowed (the same machine is always allowed).
251
228
  subtreeValues = subtreeValues.filter((x) => x !== localhostDomain);
252
229
  if (subtreeValues.length !== 1 || subtreeValues[0] !== subject) {
253
230
  throw new Error(`Certificate must have a single constrained domain (had ${JSON.stringify(subtreeValues)})`);
@@ -271,13 +248,13 @@ function validateCertificate(domain, cert, issuerCert) {
271
248
  }
272
249
  let issuerCertParsed = parseCert(issuerCert);
273
250
  let issuerExpectedPublicKeyPart = domainParts.shift() || "";
274
- let issuerActualPublicKeyPart = getDomainPartFromPublicKey(issuerCertParsed.publicKey);
251
+ let issuerActualPublicKeyPart = getDomainPartFromPublicKey(getED25519PublicKey(issuerCertParsed));
275
252
  if (issuerExpectedPublicKeyPart !== issuerActualPublicKeyPart) {
276
253
  throw new Error(`Issuer public key in the url is ${issuerExpectedPublicKeyPart}, but in the cert is ${issuerActualPublicKeyPart}`);
277
254
  }
278
255
  // Take the last part
279
256
  let certExpectedPublicKeyPart = domainParts.shift() || "";
280
- let certActualPublicKeyPart = getDomainPartFromPublicKey(certParsed.publicKey);
257
+ let certActualPublicKeyPart = getDomainPartFromPublicKey(getED25519PublicKey(certParsed));
281
258
  if (certExpectedPublicKeyPart !== certActualPublicKeyPart) {
282
259
  throw new Error(`Certificate public key in the url is ${certExpectedPublicKeyPart}, but in the cert is ${certActualPublicKeyPart}`);
283
260
  }
@@ -290,8 +267,7 @@ function validateCertificate(domain, cert, issuerCert) {
290
267
  throw new Error(`CA must have nameConstraints.permittedSubtrees`);
291
268
  }
292
269
  let subtreeValues = subtrees.map((x) => x.value);
293
- // Ignore localhostDomain, as it can always safely be allowed (the same machine
294
- // is always allowed).
270
+ // Ignore localhostDomain, as it can always safely be allowed (the same machine is always allowed).
295
271
  subtreeValues = subtreeValues.filter((x) => x !== localhostDomain);
296
272
  if (subtreeValues.length !== 1) {
297
273
  throw new Error(`CA must have a single constrained domain (had ${JSON.stringify(subtreeValues)})`);
@@ -316,86 +292,50 @@ function validateAltNames(certParsed, subject) {
316
292
  altNames = altNames.filter((x) => x !== localhostDomain);
317
293
  if (altNames.some((x) => !(x === subject
318
294
  || x.endsWith("." + subject)
319
- // Commented out, because... it is so easy to publish a 127.0.0.1 A record,
320
- // and even to generate a real cert, so, we should jsut do that, and keep it secure.
321
- // If we need this for development we can put it behind a flag, so non-development
322
- // instances are still secure.
323
- // // Also allow 127.0.0.1, for local testing, for now?
324
- // // - This might be insecure if these are trusted by the browser,
325
- // // as then anyone that stores any cookies in this ip can have
326
- // // the cookies stolen. But... if this is just cross-server...
327
- // // I don't see how this could cause a security vulnerability.
328
- // || x === Buffer.from([127, 0, 0, 1]).toString()
295
+ // NOTE: We don't allow 127.0.0.1 (|| x === Buffer.from([127, 0, 0, 1]).toString()), because it is so easy to publish a 127.0.0.1 A record, and even to generate a real cert, so we should just do that, and keep it secure. If we need this for development we can put it behind a flag, so non-development instances are still secure.
329
296
  ))) {
330
297
  throw new Error(`Invalid alt names. Must be subtrees of the subject (CN) ${JSON.stringify(subject)}, was ${JSON.stringify(altNames)}`);
331
298
  }
332
299
  }
333
300
  function generateKeyPair() {
334
301
  return (0, measure_1.measureBlock)(function generateKeyPair() {
335
- // NOTE: We use ED25519 because it can generated keys about 10X faster, WHICH, is still slow
336
- // (~6ms on my machine). So we DEFINITELY don't want it to be 10X slower!
337
- // NOTE: ED25519 doens't have great support in browsers, but we shouldn't need self signed certificates
338
- // in the browser anyway.
339
- // - https://security.stackexchange.com/a/236943/282367
340
- //let keyPair = forge.ed25519.generateKeyPair();
341
- let keyPair = forge.pki.rsa.generateKeyPair();
342
- return keyPair;
302
+ // NOTE: We use ED25519 because it can generate keys about 10X faster than RSA (which is still slow, ~6ms on my machine, so we DEFINITELY don't want it to be 10X slower!) - https://security.stackexchange.com/a/236943/282367
303
+ return forge.ed25519.generateKeyPair();
343
304
  });
344
305
  }
345
306
  exports.generateKeyPair = generateKeyPair;
346
- function generateRSAKeyPair() {
347
- return (0, measure_1.measureBlock)(function generateKeyPair() {
348
- return forge.pki.rsa.generateKeyPair();
349
- });
350
- }
351
- exports.generateRSAKeyPair = generateRSAKeyPair;
352
307
  function generateTestCA(domain) {
353
308
  const keyPair = generateKeyPair();
354
309
  let caPublicKeyPart = getDomainPartFromPublicKey(keyPair.publicKey);
355
310
  let fullDomain = `${caPublicKeyPart}.${domain}`;
356
- if (!(0, misc_1.isNode)()) {
357
- fullDomain = `${caPublicKeyPart}.${domain}`;
358
- }
359
311
  return createX509({ domain: fullDomain, issuer: "self", keyPair, lifeSpan: timeInDay * 365 * 20 });
360
312
  }
361
313
  exports.generateTestCA = generateTestCA;
362
- let identityCA = (0, caching_1.cache)((domain) => {
363
- let identityCA = (0, caching_1.lazy)((async () => {
364
- let identityCACached = getIdentityStore(domain);
365
- let caCached = await identityCACached.get();
366
- if (!caCached) {
367
- console.log(`Generating new identity CA`);
368
- const keyPair = generateKeyPair();
369
- let caPublicKeyPart = getDomainPartFromPublicKey(keyPair.publicKey);
370
- let fullDomain = `${caPublicKeyPart}.${domain}`;
371
- if (!(0, misc_1.isNode)()) {
372
- fullDomain = `${caPublicKeyPart}.${domain}`;
373
- }
374
- let value = createX509({ domain: fullDomain, issuer: "self", keyPair, lifeSpan: timeInDay * 365 * 20 });
375
- caCached = {
376
- domain: value.domain,
377
- certB64: value.cert.toString("base64"),
378
- keyB64: value.key.toString("base64"),
379
- };
380
- await identityCACached.set(caCached);
381
- }
382
- let result = {
383
- domain: caCached.domain,
384
- cert: Buffer.from(caCached.certB64, "base64"),
385
- key: Buffer.from(caCached.keyB64, "base64"),
314
+ let identityCA = (0, caching_1.cache)((domain) => (0, caching_1.lazy)(() => {
315
+ let identityCACached = getIdentityStore(domain);
316
+ let caCached = identityCACached.get();
317
+ if (!caCached) {
318
+ console.log(`Generating new identity CA`);
319
+ const keyPair = generateKeyPair();
320
+ let caPublicKeyPart = getDomainPartFromPublicKey(keyPair.publicKey);
321
+ let fullDomain = `${caPublicKeyPart}.${domain}`;
322
+ let value = createX509({ domain: fullDomain, issuer: "self", keyPair, lifeSpan: timeInDay * 365 * 20 });
323
+ caCached = {
324
+ domain: value.domain,
325
+ certB64: value.cert.toString("base64"),
326
+ keyB64: value.key.toString("base64"),
386
327
  };
387
- (0, certStore_1.trustCertificate)(result.cert.toString());
388
- identityCA.set(result);
389
- return result;
390
- }));
391
- return identityCA;
392
- });
393
- // IMPORTANT! We do not embed any debug info in this domain. If we did, it would be useful,
394
- // but... potentally a security vulnerability, as if the debug info (such as a prefix)
395
- // is used to identify what a certificate is for, it would be easy for an attack to
396
- // forge this (as the debug info won't be secured). So it is much better to keep
397
- // the certificate opaque, and then require any metadata to be actually vetted
398
- // (and hopefully stored in a UI, showing IP, time, etc).
328
+ identityCACached.set(caCached);
329
+ }
330
+ let result = {
331
+ domain: caCached.domain,
332
+ cert: Buffer.from(caCached.certB64, "base64"),
333
+ key: Buffer.from(caCached.keyB64, "base64"),
334
+ };
335
+ (0, certStore_1.trustCertificate)(result.cert.toString());
336
+ return result;
337
+ }));
338
+ // IMPORTANT! We do not embed any debug info in this domain. If we did, it would be useful, but... potentally a security vulnerability, as if the debug info (such as a prefix) is used to identify what a certificate is for, it would be easy for an attack to forge this (as the debug info won't be secured). So it is much better to keep the certificate opaque, and then require any metadata to be actually vetted (and hopefully stored in a UI, showing IP, time, etc).
399
339
  function createCertFromCA(config) {
400
340
  return (0, measure_1.measureBlock)(function createCertFromCA() {
401
341
  let { CAKeyPair } = config;
@@ -411,17 +351,18 @@ function createCertFromCA(config) {
411
351
  });
412
352
  }
413
353
  exports.createCertFromCA = createCertFromCA;
414
- function getMachineId(domainName) {
415
- return domainName.split(".").slice(-3).join(".");
354
+ function getMachineId(domainNameOrNodeId, domain) {
355
+ return decodeNodeIdAssert(domainNameOrNodeId, domain, "allowMissingThreadId").machineId;
416
356
  }
417
357
  exports.getMachineId = getMachineId;
418
- function decodeNodeId(nodeId) {
358
+ function decodeNodeId(nodeId, domain, allowMissingThreadId) {
419
359
  let locationObj = (0, nodeCache_1.getNodeIdLocation)(nodeId);
420
360
  if (!locationObj) {
421
361
  return undefined;
422
362
  }
423
363
  let parts = locationObj.address.split(".");
424
- if (nodeId.startsWith("127-0-0-1.") && parts.length === 3) {
364
+ // NOTE: We have to only allow localhost domains on our own domain, as the underlying domain gets stripped when we're looking at the machineId. So if we allowed localhost domains on other domains, a server could trick us into connecting to it, and then once the connection is established, it could talk back and we would think it has a localhost machineId, which is implicitly trusted, which would then give it access to everything.
365
+ if (locationObj.address === `127-0-0-1.${domain}` && nodeId.includes(":")) {
425
366
  return {
426
367
  threadId: "",
427
368
  machineId: parts.at(-3) || "",
@@ -429,7 +370,8 @@ function decodeNodeId(nodeId) {
429
370
  port: locationObj.port,
430
371
  };
431
372
  }
432
- if (parts.length < 4) {
373
+ let isValid = parts.length >= 4 || allowMissingThreadId && parts.length === 3;
374
+ if (!isValid) {
433
375
  return undefined;
434
376
  }
435
377
  return {
@@ -440,10 +382,10 @@ function decodeNodeId(nodeId) {
440
382
  };
441
383
  }
442
384
  exports.decodeNodeId = decodeNodeId;
443
- function decodeNodeIdAssert(nodeId) {
444
- let result = decodeNodeId(nodeId);
385
+ function decodeNodeIdAssert(nodeId, domain, allowMissingThreadId) {
386
+ let result = decodeNodeId(nodeId, domain, allowMissingThreadId);
445
387
  if (!result) {
446
- throw new Error(`Invalid nodeId: ${nodeId}`);
388
+ throw new Error(`Invalid nodeId: ${JSON.stringify(nodeId)}`);
447
389
  }
448
390
  return result;
449
391
  }
@@ -463,45 +405,43 @@ async function setIdentityCARaw(domain, json) {
463
405
  (0, certStore_1.trustCertificate)(ca.cert.toString());
464
406
  identityCA(domain).set(ca);
465
407
  getThreadKeyCertBase(domain).reset();
466
- await identityCACached.set(obj);
408
+ identityCACached.set(obj);
467
409
  (0, nodeCache_2.resetAllNodeCallFactories)();
468
410
  }
469
411
  exports.setIdentityCARaw = setIdentityCARaw;
412
+ // NOTE: The identity CA is available synchronously (storage is fs/localStorage, both synchronous), so this only exists for backwards compatibility with startup code that awaits it.
470
413
  async function loadIdentityCA(domain) {
471
- await identityCA(domain)();
414
+ identityCA(domain)();
472
415
  }
473
416
  exports.loadIdentityCA = loadIdentityCA;
474
417
  function getIdentityCA(domain) {
475
- let value = identityCA(domain)();
476
- if (value instanceof Promise) {
477
- throw new Error("Identity CA is not yet loaded. Call and wait for loadIdentityCA() in your startup before accessing the identity (or call getIdentityCAPromise())");
478
- }
479
- return value;
418
+ return identityCA(domain)();
480
419
  }
481
420
  exports.getIdentityCA = getIdentityCA;
482
- // TODO: Replace this with a database, so it is easy for us to trust CAs
483
- // cross machine, and even have multiple users, etc, etc.
421
+ // TODO: Replace this with a database, so it is easy for us to trust CAs cross machine, and even have multiple users, etc, etc.
484
422
  function getIdentityCAPromise(domain) {
485
423
  return identityCA(domain)();
486
424
  }
487
425
  exports.getIdentityCAPromise = getIdentityCAPromise;
488
426
  function getOwnMachineId(domain) {
489
- return getMachineId(getIdentityCA(domain).domain);
427
+ return getMachineId(getIdentityCA(domain).domain, domain);
490
428
  }
491
429
  exports.getOwnMachineId = getOwnMachineId;
430
+ function getOwnThreadId(domain) {
431
+ return decodeNodeIdAssert(getThreadKeyCert(domain).domain, domain).threadId;
432
+ }
433
+ exports.getOwnThreadId = getOwnThreadId;
492
434
  /** Part of the machineId comes from the publicKey, so we can use it to verify */
493
435
  function verifyMachineIdForPublicKey(config) {
494
436
  let { machineId, publicKey } = config;
495
437
  let domainPart = getDomainPartFromPublicKey(publicKey);
496
- return machineId.split(".").at(-3) === domainPart;
438
+ // machineId is the bare key-hash label, but also accept legacy "hash.domain.tld" forms
439
+ return machineId.split(".")[0] === domainPart;
497
440
  }
498
441
  exports.verifyMachineIdForPublicKey = verifyMachineIdForPublicKey;
499
442
  // NOTE: We don't have a cache per CA, as... the CA should be set first
500
- // TODO: Maybe throw if they try to change the CA after they generate any certificates?
501
- // TODO: Regenerate certificates after enough time (as thread certs should be relatively short lived,
502
- // so it is plausible for them to expire)
503
- // - We will also need to provide a callback so that users of the cert can update the cert they
504
- // are using as well.
443
+ // TODO: Maybe throw if they try to change the CA after they generate any certificates?
444
+ // TODO: Regenerate certificates after enough time (as thread certs should be relatively short lived, so it is plausible for them to expire). We will also need to provide a callback so that users of the cert can update the cert they are using as well.
505
445
  function getThreadKeyCert(domain) {
506
446
  return getThreadKeyCertBase(domain)();
507
447
  }
@@ -510,10 +450,6 @@ const getThreadKeyCertBase = (0, caching_1.cache)((domain) => (0, caching_1.lazy
510
450
  let ca = getIdentityCA(domain);
511
451
  return createCertFromCA({ CAKeyPair: ca });
512
452
  }));
513
- exports.createTestBrowserKeyCert = (0, caching_1.lazy)(async () => {
514
- let keyPair = generateRSAKeyPair();
515
- return await createX509({ domain: "test", issuer: "self", keyPair, lifeSpan: timeInDay * 365 * 20 });
516
- });
517
453
  function getOwnNodeId() {
518
454
  let nodeId = SocketFunction_1.SocketFunction.mountedNodeId;
519
455
  if (!nodeId) {
@@ -526,5 +462,5 @@ function getOwnNodeIdAllowUndefined() {
526
462
  return SocketFunction_1.SocketFunction.mountedNodeId;
527
463
  }
528
464
  exports.getOwnNodeIdAllowUndefined = getOwnNodeIdAllowUndefined;
529
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjZXJ0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsa0RBQWtEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVsRCxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQixpREFBaUQ7QUFFakQsdUVBQStEO0FBQy9ELGtEQUFvQztBQUdwQyx5REFBMEQ7QUFDMUQsbURBQWtEO0FBQ2xELDBEQUErQjtBQUMvQixvREFBNEI7QUFDNUIsNkRBQWlFO0FBQ2pFLG1FQUE4RjtBQUM5Riw2REFBa0g7QUFFbEgsbUVBQWdFO0FBQ2hFLDZEQUEwRTtBQUMxRSxxRUFBdUQ7QUFFdkQsSUFBQSxzQkFBTyxFQUFDLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3BELElBQUEsc0JBQU8sRUFBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUVuRCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFFekIsUUFBQSxrQkFBa0IsR0FBRyxzQ0FBc0MsQ0FBQztBQUU1RCxRQUFBLGtCQUFrQixHQUFHLGNBQWMsQ0FBQztBQUdqRCxTQUFTLGdCQUFnQixDQUFDLE1BQWM7SUFDcEMsT0FBTyxJQUFBLG9DQUFXLEVBQXNCLE1BQU0sRUFBRSwwQkFBa0IsQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFJRCxTQUFnQixhQUFhLENBQUMsSUFBcUI7SUFDL0MsSUFBSSxPQUFPLEdBQUcsSUFBSSxnQkFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUM7SUFDdkQsSUFBSSxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFD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LDRDQUVDO0FBQ0QsTUFBTSxvQkFBb0IsR0FBRyxJQUFBLGVBQUssRUFBQyxDQUFDLE1BQWMsRUFBRSxFQUFFLENBQUMsSUFBQSxjQUFJLEVBQUMsR0FBRyxFQUFFO0lBQzdELElBQUksRUFBRSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvQixPQUFPLGdCQUFnQixDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDL0MsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVTLFFBQUEsd0JBQXdCLEdBQUcsSUFBQSxjQUFJLEVBQUMsS0FBSyxJQUFJLEVBQUU7SUFDcEQsSUFBSSxPQUFPLEdBQUcsa0JBQWtCLEVBQUUsQ0FBQztJQUNuQyxPQUFPLE1BQU0sVUFBVSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxHQUFHLEdBQUcsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3pHLENBQUMsQ0FBQyxDQUFDO0FBRUgsU0FBZ0IsWUFBWTtJQUN4QixJQUFJLE1BQU0sR0FBRywrQkFBYyxDQUFDLGFBQWEsQ0FBQztJQUMxQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2xCLENBQUM7QUFORCxvQ0FNQztBQUVELFNBQWdCLDBCQUEwQjtJQUN0QyxPQUFPLCtCQUFjLENBQUMsYUFBYSxDQUFDO0FBQ3hDLENBQUM7QUFGRCxnRUFFQyIsInNvdXJjZXNDb250ZW50IjpbIi8vLyA8cmVmZXJlbmNlIHBhdGg9XCIuL25vZGUtZm9yZ2UtZWQyNTUxOS5kLnRzXCIgLz5cblxubW9kdWxlLmFsbG93Y2xpZW50ID0gdHJ1ZTtcblxuLy8gaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzUyODAjcGFnZS00MlxuXG5pbXBvcnQgeyBzZXRGbGFnIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9yZXF1aXJlL2NvbXBpbGVGbGFnc1wiO1xuaW1wb3J0ICogYXMgZm9yZ2UgZnJvbSBcIm5vZGUtZm9yZ2VcIjtcbmltcG9ydCBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCBmc1N5bmMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBjYWNoZSwgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IGlzTm9kZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL21pc2NcIjtcbmltcG9ydCBzaGEyNjUgZnJvbSBcImpzLXNoYTI1NlwiO1xuaW1wb3J0IGNyeXB0byBmcm9tIFwiY3J5cHRvXCI7XG5pbXBvcnQgeyB0cnVzdENlcnRpZmljYXRlIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvY2VydFN0b3JlXCI7XG5pbXBvcnQgeyBtZWFzdXJlQmxvY2ssIG1lYXN1cmVGbmMsIG1lYXN1cmVXcmFwIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvcHJvZmlsaW5nL21lYXN1cmVcIjtcbmltcG9ydCB7IGdldE5vZGVJZERvbWFpbiwgZ2V0Tm9kZUlkRG9tYWluTWF5YmVVbmRlZmluZWQsIGdldE5vZGVJZExvY2F0aW9uIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbm9kZUNhY2hlXCI7XG5pbXBvcnQgeyBNYXliZVByb21pc2UgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy90eXBlc1wiO1xuaW1wb3J0IHsgU29ja2V0RnVuY3Rpb24gfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL1NvY2tldEZ1bmN0aW9uXCI7XG5pbXBvcnQgeyByZXNldEFsbE5vZGVDYWxsRmFjdG9yaWVzIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbm9kZUNhY2hlXCI7XG5pbXBvcnQgeyBnZXRLZXlTdG9yZSB9IGZyb20gXCIuL3BlcnNpc3RlbnRMb2NhbFN0b3JhZ2VcIjtcblxuc2V0RmxhZyhyZXF1aXJlLCBcIm5vZGUtZm9yZ2VcIiwgXCJhbGxvd2NsaWVudFwiLCB0cnVlKTtcbnNldEZsYWcocmVxdWlyZSwgXCJqcy1zaGEyNTZcIiwgXCJhbGxvd2NsaWVudFwiLCB0cnVlKTtcblxuY29uc3QgdGltZUluRGF5ID0gMTAwMCAqIDYwICogNjAgKiAyNDtcblxuZXhwb3J0IGNvbnN0IENBX05PVF9GT1VORF9FUlJPUiA9IFwiMThhYTczMTgtZjg4Zi00ZDJkLWI0MWYtM2RhZjRhNDMzODI3XCI7XG5cbmV4cG9ydCBjb25zdCBpZGVudGl0eVN0b3JhZ2VLZXkgPSBcIm1hY2hpbmVDQV8xMFwiO1xuZXhwb3J0IHR5cGUgSWRlbnRpdHlTdG9yYWdlVHlwZSA9IHsgZG9tYWluOiBzdHJpbmc7IGNlcnRCNjQ6IHN0cmluZzsga2V5QjY0OiBzdHJpbmcgfTtcblxuZnVuY3Rpb24gZ2V0SWRlbnRpdHlTdG9yZShkb21haW46IHN0cmluZykge1xuICAgIHJldHVybiBnZXRLZXlTdG9yZTxJZGVudGl0eVN0b3JhZ2VUeXBlPihkb21haW4sIGlkZW50aXR5U3RvcmFnZUtleSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgWDUwOUtleVBhaXIgeyBkb21haW46IHN0cmluZzsgY2VydDogQnVmZmVyOyBrZXk6IEJ1ZmZlcjsgfVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29tbW9uTmFtZShjZXJ0OiBCdWZmZXIgfCBzdHJpbmcpIHtcbiAgICBsZXQgc3ViamVjdCA9IG5ldyBjcnlwdG8uWDUwOUNlcnRpZmljYXRlKGNlcnQpLnN1YmplY3Q7XG4gICAgbGV0IHN1YmplY3RLVlBzID0gbmV3IE1hcChzdWJqZWN0LnNwbGl0KFwiLFwiKS5tYXAoeCA9PiB4LnRyaW0oKS5zcGxpdChcIj1cIikpLm1hcCh4ID0+IFt4WzBdLCB4LnNsaWNlKDEpLmpvaW4oXCI9XCIpXSkpO1xuICAgIGxldCBjb21tb25OYW1lID0gc3ViamVjdEtWUHMuZ2V0KFwiQ05cIik7XG4gICAgaWYgKCFjb21tb25OYW1lKSB0aHJvdyBuZXcgRXJyb3IoYE5vIGNvbW1vbiBuYW1lIGluIHN1YmplY3Q6ICR7c3ViamVjdH1gKTtcbiAgICByZXR1cm4gY29tbW9uTmFtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVg1MDkoXG4gICAgY29uZmlnOiB7XG4gICAgICAgIGRvbWFpbjogc3RyaW5nO1xuICAgICAgICBpc3N1ZXI6IFg1MDlLZXlQYWlyIHwgXCJzZWxmXCI7XG4gICAgICAgIGxpZmVTcGFuOiBudW1iZXI7XG4gICAgICAgIGtleVBhaXI6IHtcbiAgICAgICAgICAgIHB1YmxpY0tleTogZm9yZ2UuRWQyNTUxOVB1YmxpY0tleTtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IGZvcmdlLkVkMjU1MTlQcml2YXRlS2V5O1xuICAgICAgICB9IHwgZm9yZ2UucGtpLktleVBhaXI7XG4gICAgfVxuKTogWDUwOUtleVBhaXIge1xuICAgIHJldHVybiBtZWFzdXJlQmxvY2soZnVuY3Rpb24gY3JlYXRlWDUwOSgpIHtcbiAgICAgICAgbGV0IHsgZG9tYWluLCBpc3N1ZXIsIGxpZmVTcGFuLCBrZXlQYWlyIH0gPSBjb25maWc7XG5cbiAgICAgICAgbGV0IGNlcnRPYmogPSBmb3JnZS5wa2kuY3JlYXRlQ2VydGlmaWNhdGUoKTtcbiAgICAgICAgY2VydE9iai5wdWJsaWNLZXkgPSBrZXlQYWlyLnB1YmxpY0tleTtcbiAgICAgICAgY2VydE9iai5zZXJpYWxOdW1iZXIgPSBcIjAxXCI7XG4gICAgICAgIC8vIEdpdmUgaXQgNSBtaW51dGVzIGJlZm9yZSBub3cuIElmIHdlIGdpdmUgaXQgdG9vIG11Y2ggdGltZSwgaXQgY2FuIGxvb2sgbGlrZSB0aGUgY2VydCBpcyByZWFsbHlcbiAgICAgICAgLy8gIG9sZCwgd2hpY2ggd2lsbCB0cmlnZ2VyIHZhcmlvdXMgcHJvY2Vzc2VzIHRvIHRyeSB0byBnZXQgYSBmcmVzaGVyIG9uZSAoYXMgaWYgaXQgbGFzdHMgZm9yXG4gICAgICAgIC8vICAxIGhvdXIsIGJ1dCB3ZSBzZXQgbm90QmVmb3JlIHRvIDEgbW9udGggYWdvLCBpdCBsb29rcyAxIG1vbnRoIG9sZCwgYW5kIHNvIGFsbW9zdCBleHBpcmVkLFxuICAgICAgICAvLyAgd2hlbiBpdCBpc24ndC4uLilcbiAgICAgICAgY2VydE9iai52YWxpZGl0eS5ub3RCZWZvcmUgPSBuZXcgRGF0ZShEYXRlLm5vdygpIC0gMTAwMCAqIDYwICogNSk7XG4gICAgICAgIGNlcnRPYmoudmFsaWRpdHkubm90QWZ0ZXIgPSBuZXcgRGF0ZShEYXRlLm5vdygpICsgbGlmZVNwYW4pO1xuXG4gICAgICAgIGNvbnN0IGNvbW1vbk5hbWVBdHRycyA9IFt7IG5hbWU6IFwiY29tbW9uTmFtZVwiLCB2YWx1ZTogZG9tYWluIH1dO1xuICAgICAgICBjZXJ0T2JqLnNldFN1YmplY3QoY29tbW9uTmFtZUF0dHJzKTtcblxuICAgICAgICBpZiAoaXNzdWVyID09PSBcInNlbGZcIikge1xuICAgICAgICAgICAgY2VydE9iai5zZXRJc3N1ZXIoY29tbW9uTmFtZUF0dHJzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNlcnRPYmouc2V0SXNzdWVyKGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUZyb21QZW0oaXNzdWVyLmNlcnQudG9TdHJpbmcoKSkuc3ViamVjdC5hdHRyaWJ1dGVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBleHRlbnNpb25zID0gW107XG4gICAgICAgIGNvbnN0IGlzQ0EgPSBpc3N1ZXIgPT09IFwic2VsZlwiO1xuICAgICAgICBpZiAoaXNDQSkge1xuICAgICAgICAgICAgZXh0ZW5zaW9ucy5wdXNoKHsgbmFtZTogXCJiYXNpY0NvbnN0cmFpbnRzXCIsIGNBOiB0cnVlIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGxvY2FsSG9zdERvbWFpbiA9IFwiMTI3LTAtMC0xLlwiICsgZG9tYWluLnNwbGl0KFwiLlwiKS5zbGljZSgtMikuam9pbihcIi5cIik7XG5cbiAgICAgICAgZXh0ZW5zaW9ucy5wdXNoKC4uLltcbiAgICAgICAgICAgIHsgbmFtZTogXCJrZXlVc2FnZVwiLCBrZXlDZXJ0U2lnbjogaXNDQSwgZGlnaXRhbFNpZ25hdHVyZTogdHJ1ZSwgbm9uUmVwdWRpYXRpb246IHRydWUsIGtleUVuY2lwaGVybWVudDogdHJ1ZSwgZGF0YUVuY2lwaGVybWVudDogdHJ1ZSB9LFxuICAgICAgICAgICAgeyBuYW1lOiBcInN1YmplY3RLZXlJZGVudGlmaWVyXCIgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBuYW1lOiBcInN1YmplY3RBbHROYW1lXCIsXG4gICAgICAgICAgICAgICAgYWx0TmFtZXM6IFtcbiAgICAgICAgICAgICAgICAgICAgeyB0eXBlOiAyLCB2YWx1ZTogZG9tYWluIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgdHlwZTogMiwgdmFsdWU6IFwiKi5cIiArIGRvbWFpbiB9LFxuICAgICAgICAgICAgICAgICAgICB7IHR5cGU6IDIsIHZhbHVlOiBsb2NhbEhvc3REb21haW4gfSxcbiAgICAgICAgICAgICAgICAgICAgLy8gTk9URTogTm8gbG9uZ2VyIGFsbG93IDEyNy4wLjAuMSwgdG8gbWFrZSB0aGlzIG1vcmUgc2VjdXJlLiBXZSBtaWdodCBlbmFibGUgdGhpc1xuICAgICAgICAgICAgICAgICAgICAvLyAgYmVoYXZpb3IgYmVoaW5kIGEgZmxhZywgZm9yIGRldmVsb3BtZW50LlxuICAgICAgICAgICAgICAgICAgICAvL3sgdHlwZTogNywgaXA6IFwiMTI3LjAuMC4xXCIgfVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAvLyBOT1RFOiBuYW1lQ29uc3RyYWludHMgYXJlIHN1cHBvcnRlZCB3aXRoIG91ciBicmFuY2guIEJ1dC4uLiBjaHJvbWUgZG9lc24ndCBzdXBwb3J0IHRoZW0sIHNvIHRoZXJlJ3Mgbm8gcG9pbnQgaW4gdXNpbmcgdGhlbS5cbiAgICAgICAgICAgIC8vICAgICAgXCJub2RlLWZvcmdlXCI6IFwiaHR0cHM6Ly9naXRodWIuY29tL3NsaWZ0aXN0L2ZvcmdlI2U2MTgxODFiNDY5YjA3YmRjNzBiOTY4YjAzOTFiZWI4ZWY1ZmVjZDZcIixcbiAgICAgICAgICAgIC8vIHtcbiAgICAgICAgICAgIC8vICAgICBuYW1lOiBcIm5hbWVDb25zdHJhaW50c1wiLFxuICAgICAgICAgICAgLy8gICAgIHBlcm1pdHRlZFN1YnRyZWVzOiBbXG4gICAgICAgICAgICAvLyAgICAgICAgIC8vIENocm9tZSBkb2Vzbid0IHJlc3BlY3QgbmFtZUNvbnN0cmFpbnRzIHBlciBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0xMDcyMDgzLFxuICAgICAgICAgICAgLy8gICAgICAgICAvLyAgYXMgdGhlIHNwZWMgZGVjaWRlZCB0aGF0IFwiZnJlZSB0byBwcm9jZXNzIG9yIGlnbm9yZSBzdWNoIGluZm9ybWF0aW9uXCIgKHdoZW4gcHJlc2VudCBpbiBzZWxmXG4gICAgICAgICAgICAvLyAgICAgICAgIC8vICBzaWduZWQgY2VydGlmaWNhdGVzKSwgYW5kIHRoZXJlZm9yZSB0aGUgY2hyb21lIGltcGxlbWVudGF0aW9uIGRlY2lkZWQgXCJUaGUgZmlyc3Qgb3JkZXIgaXMgdG8gYmVoYXZlIHByZWRpY3RhYmx5XCIsXG4gICAgICAgICAgICAvLyAgICAgICAgIC8vICBzby4uLiB0aGV5J3JlIG5vdCBnb2luZyB0byBzdXBwb3J0IGl0LCBiZWNhdXNlIHdoeSBoYXZlIGEgZmVhdHVyZSBpbiBvbmUgcGxhY2UsIGlmIGl0IGlzbid0XG4gICAgICAgICAgICAvLyAgICAgICAgIC8vICBvbiBhbmRyb2lkIGFzIHdlbGwuLi4gdWdoLi4uXG4gICAgICAgICAgICAvLyAgICAgICAgIC8vIFdvcmtzIGZpbmUgb24gRWRnZSB0aG91Z2hcbiAgICAgICAgICAgIC8vICAgICAgICAgeyB0eXBlOiAyLCB2YWx1ZTogZm9yZ2UudXRpbC5lbmNvZGVVdGY4KGRvbWFpbikgfSxcbiAgICAgICAgICAgIC8vICAgICAgICAgeyB0eXBlOiAyLCB2YWx1ZTogZm9yZ2UudXRpbC5lbmNvZGVVdGY4KGxvY2FsSG9zdERvbWFpbikgfSxcbiAgICAgICAgICAgIC8vICAgICBdXG4gICAgICAgICAgICAvLyB9LFxuICAgICAgICBdKTtcbiAgICAgICAgY2VydE9iai5zZXRFeHRlbnNpb25zKGV4dGVuc2lvbnMpO1xuXG5cbiAgICAgICAgbWVhc3VyZUJsb2NrKGZ1bmN0aW9uIHNpZ24oKSB7XG4gICAgICAgICAgICBpZiAoaXNzdWVyID09PSBcInNlbGZcIikge1xuICAgICAgICAgICAgICAgIGNlcnRPYmouc2lnbihrZXlQYWlyLnByaXZhdGVLZXkgYXMgYW55LCBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjZXJ0T2JqLnNpZ24ocHJpdmF0ZUtleUZyb21QZW0oaXNzdWVyLmtleS50b1N0cmluZygpKSBhcyBhbnksIGZvcmdlLm1kLnNoYTI1Ni5jcmVhdGUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBtZWFzdXJlQmxvY2soZnVuY3Rpb24gdG9QZW1zKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkb21haW4sXG4gICAgICAgICAgICAgICAgY2VydDogQnVmZmVyLmZyb20oZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9QZW0oY2VydE9iaikpLFxuICAgICAgICAgICAgICAgIGtleTogQnVmZmVyLmZyb20ocHJpdmF0ZUtleVRvUGVtKGtleVBhaXIucHJpdmF0ZUtleSkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gcHJpdmF0ZUtleVRvUGVtKGJ1ZmZlcjogZm9yZ2UucGtpLlByaXZhdGVLZXkgfCBmb3JnZS5FZDI1NTE5UHJpdmF0ZUtleSkge1xuICAgIGlmIChcInByaXZhdGVLZXlCeXRlc1wiIGluIGJ1ZmZlcikge1xuICAgICAgICByZXR1cm4gZm9yZ2UuZWQyNTUxOS5wcml2YXRlS2V5VG9QZW0oYnVmZmVyKTtcbiAgICB9XG4gICAgcmV0dXJuIGZvcmdlLnBraS5wcml2YXRlS2V5VG9QZW0oYnVmZmVyKTtcbn1cbmZ1bmN0aW9uIHByaXZhdGVLZXlGcm9tUGVtKHBlbTogc3RyaW5nKSB7XG4gICAgLy8gV2Ugd2FudCB0byBndWVzcyB0aGUgdHlwZSBjb3JyZWN0bHksIGFzIGNhdWdodCBleGNlcHRpb25zIG1ha2UgZGVidWdnaW5nIGFubm95aW5nXG4gICAgaWYgKHBlbS5sZW5ndGggPCAyMDApIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBmb3JnZS5lZDI1NTE5LnByaXZhdGVLZXlGcm9tUGVtKHBlbSk7XG4gICAgICAgIH0gY2F0Y2ggeyB9XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBmb3JnZS5wa2kucHJpdmF0ZUtleUZyb21QZW0ocGVtKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGZvcmdlLmVkMjU1MTkucHJpdmF0ZUtleUZyb21QZW0ocGVtKTtcbiAgICB9XG59XG5mdW5jdGlvbiBwdWJsaWNLZXlGcm9tQ2VydChjZXJ0OiBzdHJpbmcpIHtcbiAgICByZXR1cm4gcGFyc2VDZXJ0KGNlcnQpLnB1YmxpY0tleTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNlcnQoUEVNb3JERVI6IHN0cmluZyB8IEJ1ZmZlcikge1xuICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tUGVtKG5vcm1hbGl6ZUNlcnRUb1BFTShQRU1vckRFUikpO1xufVxuXG4vLyBHZXRzIGEgdW5pcXVlIHZhbHVlIHRvIHJlcHJlc2VudCB0aGUgcHVibGljIGtleVxuZXhwb3J0IGZ1bmN0aW9uIGdldFB1YmxpY0lkZW50aWZpZXIoUEVNb3JERVI6IHN0cmluZyB8IEJ1ZmZlcik6IEJ1ZmZlciB7XG4gICAgbGV0IG9iaiA9IHBhcnNlQ2VydChQRU1vckRFUik7XG4gICAgbGV0IHB1YmxpY0tleSA9IG9iai5wdWJsaWNLZXk7XG4gICAgaWYgKFwicHVibGljS2V5Qnl0ZXNcIiBpbiBwdWJsaWNLZXkpIHtcbiAgICAgICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHB1YmxpY0tleS5wdWJsaWNLZXlCeXRlcyBhcyBhbnkpO1xuICAgIH1cbiAgICByZXR1cm4gQnVmZmVyLmZyb20obmV3IFVpbnQzMkFycmF5KChwdWJsaWNLZXkgYXMgYW55KS5uLmRhdGEpLmJ1ZmZlcik7XG59XG5cbmZ1bmN0aW9uIGlzRUQyNTUxOShrZXk6IHN0cmluZyB8IEJ1ZmZlcikge1xuICAgIHJldHVybiBrZXkubGVuZ3RoIDwgMjU2O1xufVxuXG4vLyBFUVVJVkFMRU5UIFRPOiBgY3J5cHRvLmNyZWF0ZVNpZ24oXCJTSEEyNTZcIikudXBkYXRlKEpTT04uc3RyaW5naWZ5KHBheWxvYWQpKS5zaWduKGtleUNlcnQua2V5LCBcImJpbmFyeVwiKWBcbmV4cG9ydCBjb25zdCBzaWduID0gbWVhc3VyZVdyYXAoZnVuY3Rpb24gc2lnbihrZXlQYWlyOiB7IGtleTogc3RyaW5nIHwgQnVmZmVyIH0sIGRhdGE6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGxldCBkYXRhU3RyID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgaWYgKGlzRUQyNTUxOShrZXlQYWlyLmtleSkpIHtcbiAgICAgICAgbGV0IHByaXZhdGVLZXkgPSAoZm9yZ2UucGtpLmVkMjU1MTkgYXMgYW55KS5wcml2YXRlS2V5RnJvbVBlbShrZXlQYWlyLmtleS50b1N0cmluZygpKTtcbiAgICAgICAgcmV0dXJuIHByaXZhdGVLZXkuc2lnbihkYXRhU3RyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgcHJpdmF0ZUtleSA9IGZvcmdlLnBraS5wcml2YXRlS2V5RnJvbVBlbShrZXlQYWlyLmtleS50b1N0cmluZygpKTtcbiAgICAgICAgY29uc3QgbWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7XG4gICAgICAgIG1kLnVwZGF0ZShkYXRhU3RyKTtcbiAgICAgICAgcmV0dXJuIHByaXZhdGVLZXkuc2lnbihtZCk7XG4gICAgfVxufSk7XG5cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnkoY2VydDogc3RyaW5nLCBzaWduYXR1cmU6IHN0cmluZywgZGF0YTogdW5rbm93bikge1xuICAgIGxldCBjZXJ0T2JqID0gcGFyc2VDZXJ0KGNlcnQpO1xuICAgIHJldHVybiAoY2VydE9iai5wdWJsaWNLZXkgYXMgZm9yZ2UucGtpLnJzYS5QdWJsaWNLZXkpLnZlcmlmeShKU09OLnN0cmluZ2lmeShkYXRhKSwgc2lnbmF0dXJlKTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplQ2VydFRvUEVNKFBFTW9yREVSOiBzdHJpbmcgfCBCdWZmZXIpOiBzdHJpbmcge1xuICAgIGlmIChQRU1vckRFUi50b1N0cmluZygpLnN0YXJ0c1dpdGgoXCItLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS1cIikpIHtcbiAgICAgICAgcmV0dXJuIFBFTW9yREVSLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIFBFTW9yREVSID0gUEVNb3JERVIudG9TdHJpbmcoXCJiYXNlNjRcIik7XG4gICAgcmV0dXJuIFwiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXFxuXCIgKyBQRU1vckRFUiArIFwiXFxuLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLVwiO1xufVxuXG5mdW5jdGlvbiBnZXREb21haW5QYXJ0RnJvbVB1YmxpY0tleShwdWJsaWNLZXk6IHsgcHVibGljS2V5Qnl0ZXM6IEJ1ZmZlciB9IHwgZm9yZ2UucGtpLktleVBhaXJbXCJwdWJsaWNLZXlcIl0gfCBCdWZmZXIpIHtcbiAgICBsZXQgYnl0ZXM6IEJ1ZmZlcjtcbiAgICBpZiAoXCJwdWJsaWNLZXlCeXRlc1wiIGluIHB1YmxpY0tleSkge1xuICAgICAgICBieXRlcyA9IHB1YmxpY0tleS5wdWJsaWNLZXlCeXRlcztcbiAgICB9IGVsc2UgaWYgKHB1YmxpY0tleSBpbnN0YW5jZW9mIEJ1ZmZlcikge1xuICAgICAgICBieXRlcyA9IHB1YmxpY0tleTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBieXRlcyA9IEJ1ZmZlci5mcm9tKG5ldyBVaW50MzJBcnJheSgocHVibGljS2V5IGFzIGFueSkubi5kYXRhKS5idWZmZXIpO1xuICAgIH1cbiAgICByZXR1cm4gXCJiXCIgKyBzaGEyNjUuc2hhMjU2KEJ1ZmZlci5mcm9tKGJ5dGVzKSkuc2xpY2UoMCwgMTYpLnJlcGxhY2VBbGwoXCIrXCIsIFwiLVwiKS5yZXBsYWNlQWxsKFwiL1wiLCBcIl9cIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUNBQ2VydChkb21haW46IHN0cmluZywgY2VydDogc3RyaW5nIHwgQnVmZmVyKSB7XG4gICAgbGV0IGNlcnRQYXJzZWQgPSBwYXJzZUNlcnQoY2VydCk7XG5cbiAgICBsZXQgc3ViamVjdCA9IGNlcnRQYXJzZWQuc3ViamVjdC5nZXRGaWVsZChcIkNOXCIpLnZhbHVlIGFzIHN0cmluZztcbiAgICBsZXQgbG9jYWxob3N0RG9tYWluID0gXCIxMjctMC0wLTEuXCIgKyBzdWJqZWN0LnNwbGl0KFwiLlwiKS5zbGljZSgtMikuam9pbihcIi5cIik7XG5cbiAgICBsZXQgZG9tYWluUGFydHMgPSBzdWJqZWN0LnNwbGl0KFwiLlwiKS5yZXZlcnNlKCk7XG5cbiAgICBsZXQgcm9vdERvbWFpblBhcnNlZCA9IFtkb21haW5QYXJ0cy5zaGlmdCgpLCBkb21haW5QYXJ0cy5zaGlmdCgpXS5yZXZlcnNlKCkuam9pbihcIi5cIik7XG4gICAgaWYgKHJvb3REb21haW5QYXJzZWQgIT09IGRvbWFpbikge1xuICAgICAgICAvLyBUaGlzIGlzIGltcG9ydGFudCwgYXMgb3VyIHRydXN0IHN0b3JlIGNvbnRhaW5zIG1vcmUgdGhlbiBqdXN0IE9VUiBjZXJ0aWZpY2F0ZXMsXG4gICAgICAgIC8vICBzbyBpZiB3ZSBhbGxvdyBhbnkgZG9tYWlucyB0aGVuIHJlYWwgZG9tYWlucyBjYW4gaW1wZXJzb25hdGUgYW55b25lISBJdCBoYXMgdG9cbiAgICAgICAgLy8gIGJlIG9uZSBPVVIgZG9tYWluIHRvIGJlIHRydXN0ZWQhXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgcm9vdCBkb21haW4gc2hvdWxkIGJlICR7ZG9tYWlufSwgYnV0IGlzICR7cm9vdERvbWFpblBhcnNlZH1gKTtcbiAgICB9XG4gICAgLy8gVE9ETzogTWF5YmUganVzdCBza2lwIGlmIGl0IGlzbid0IGEgaGFzaCBzdHJpbmc/XG4gICAgaWYgKGRvbWFpblBhcnRzWzBdID09PSBcIm5vcHJveHlcIikge1xuICAgICAgICBkb21haW5QYXJ0cy5zaGlmdCgpO1xuICAgIH1cblxuICAgIGxldCBjZXJ0RXhwZWN0ZWRQdWJsaWNLZXlQYXJ0ID0gKGRvbWFpblBhcnRzLnNoaWZ0KCkgfHwgXCJcIikuc3BsaXQoXCItXCIpLnNsaWNlKC0xKVswXTtcbiAgICBsZXQgY2VydEFjdHVhbFB1YmxpY0tleVBhcnQgPSBnZXREb21haW5QYXJ0RnJvbVB1YmxpY0tleShjZXJ0UGFyc2VkLnB1YmxpY0tleSk7XG4gICAgaWYgKGNlcnRFeHBlY3RlZFB1YmxpY0tleVBhcnQgIT09IGNlcnRBY3R1YWxQdWJsaWNLZXlQYXJ0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgcHVibGljIGtleSBpbiB0aGUgdXJsIGlzICR7Y2VydEV4cGVjdGVkUHVibGljS2V5UGFydH0sIGJ1dCBpbiB0aGUgY2VydCBpcyAke2NlcnRBY3R1YWxQdWJsaWNLZXlQYXJ0fWApO1xuICAgIH1cblxuICAgIC8vIEFMU08sIHJlcXVpcmUgbmFtZSBjb25zdHJhaW50cyB0byBiZSBwcmVzZW50LCBhbmQgdG8gcmVzdHJpY3QgdG8gdGhlIFwiQ05cIlxuICAgIGxldCBuYW1lQ29uc3RyYWludHMgPSBjZXJ0UGFyc2VkLmdldEV4dGVuc2lvbihcIm5hbWVDb25zdHJhaW50c1wiKSBhcyBhbnk7XG4gICAgaWYgKCFuYW1lQ29uc3RyYWludHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDZXJ0aWZpY2F0ZSBtdXN0IGhhdmUgbmFtZUNvbnN0cmFpbnRzYCk7XG4gICAgfVxuICAgIGxldCBzdWJ0cmVlcyA9IG5hbWVDb25zdHJhaW50cy5wZXJtaXR0ZWRTdWJ0cmVlcztcbiAgICBpZiAoIXN1YnRyZWVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgbXVzdCBoYXZlIG5hbWVDb25zdHJhaW50cy5wZXJtaXR0ZWRTdWJ0cmVlc2ApO1xuICAgIH1cbiAgICBsZXQgc3VidHJlZVZhbHVlcyA9IHN1YnRyZWVzLm1hcCgoeDogYW55KSA9PiB4LnZhbHVlKTtcbiAgICAvLyBJZ25vcmUgbG9jYWxob3N0RG9tYWluLCBhcyBpdCBjYW4gYWx3YXlzIHNhZmVseSBiZSBhbGxvd2VkICh0aGUgc2FtZSBtYWNoaW5lXG4gICAgLy8gICAgICBpcyBhbHdheXMgYWxsb3dlZCkuXG4gICAgc3VidHJlZVZhbHVlcyA9IHN1YnRyZWVWYWx1ZXMuZmlsdGVyKCh4OiBzdHJpbmcpID0+IHggIT09IGxvY2FsaG9zdERvbWFpbik7XG4gICAgaWYgKHN1YnRyZWVWYWx1ZXMubGVuZ3RoICE9PSAxIHx8IHN1YnRyZWVWYWx1ZXNbMF0gIT09IHN1YmplY3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDZXJ0aWZpY2F0ZSBtdXN0IGhhdmUgYSBzaW5nbGUgY29uc3RyYWluZWQgZG9tYWluIChoYWQgJHtKU09OLnN0cmluZ2lmeShzdWJ0cmVlVmFsdWVzKX0pYCk7XG4gICAgfVxuXG4gICAgdmFsaWRhdGVBbHROYW1lcyhjZXJ0UGFyc2VkLCBzdWJqZWN0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ2VydGlmaWNhdGUoZG9tYWluOiBzdHJpbmcsIGNlcnQ6IEJ1ZmZlciB8IHN0cmluZywgaXNzdWVyQ2VydDogQnVmZmVyIHwgc3RyaW5nKSB7XG4gICAgdmFsaWRhdGVDQUNlcnQoZG9tYWluLCBpc3N1ZXJDZXJ0KTtcblxuICAgIGxldCBjZXJ0UGFyc2VkID0gcGFyc2VDZXJ0KGNlcnQpO1xuICAgIGxldCBzdWJqZWN0ID0gY2VydFBhcnNlZC5zdWJqZWN0LmdldEZpZWxkKFwiQ05cIikudmFsdWUgYXMgc3RyaW5nO1xuICAgIGxldCBsb2NhbGhvc3REb21haW4gPSBcIjEyNy0wLTAtMS5cIiArIHN1YmplY3Quc3BsaXQoXCIuXCIpLnNsaWNlKC0yKS5qb2luKFwiLlwiKTtcblxuICAgIGxldCBkb21haW5QYXJ0cyA9IHN1YmplY3Quc3BsaXQoXCIuXCIpLnJldmVyc2UoKTtcblxuICAgIGxldCByb290RG9tYWluUGFyc2VkID0gW2RvbWFpblBhcnRzLnNoaWZ0KCksIGRvbWFpblBhcnRzLnNoaWZ0KCldLnJldmVyc2UoKS5qb2luKFwiLlwiKTtcbiAgICBpZiAocm9vdERvbWFpblBhcnNlZCAhPT0gZG9tYWluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgcm9vdCBkb21haW4gc2hvdWxkIGJlICR7ZG9tYWlufSwgYnV0IGlzICR7cm9vdERvbWFpblBhcnNlZH1gKTtcbiAgICB9XG4gICAgLy8gVE9ETzogTWF5YmUganVzdCBza2lwIGlmIGl0IGlzbid0IGEgaGFzaCBzdHJpbmc/XG4gICAgaWYgKGRvbWFpblBhcnRzWzBdID09PSBcIm5vcHJveHlcIikge1xuICAgICAgICBkb21haW5QYXJ0cy5zaGlmdCgpO1xuICAgIH1cblxuICAgIGxldCBpc3N1ZXJDZXJ0UGFyc2VkID0gcGFyc2VDZXJ0KGlzc3VlckNlcnQpO1xuXG4gICAgbGV0IGlzc3VlckV4cGVjdGVkUHVibGljS2V5UGFydCA9IGRvbWFpblBhcnRzLnNoaWZ0KCkgfHwgXCJcIjtcbiAgICBsZXQgaXNzdWVyQWN0dWFsUHVibGljS2V5UGFydCA9IGdldERvbWFpblBhcnRGcm9tUHVibGljS2V5KGlzc3VlckNlcnRQYXJzZWQucHVibGljS2V5KTtcbiAgICBpZiAoaXNzdWVyRXhwZWN0ZWRQdWJsaWNLZXlQYXJ0ICE9PSBpc3N1ZXJBY3R1YWxQdWJsaWNLZXlQYXJ0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSXNzdWVyIHB1YmxpYyBrZXkgaW4gdGhlIHVybCBpcyAke2lzc3VlckV4cGVjdGVkUHVibGljS2V5UGFydH0sIGJ1dCBpbiB0aGUgY2VydCBpcyAke2lzc3VlckFjdHVhbFB1YmxpY0tleVBhcnR9YCk7XG4gICAgfVxuXG4gICAgLy8gVGFrZSB0aGUgbGFzdCBwYXJ0XG4gICAgbGV0IGNlcnRFeHBlY3RlZFB1YmxpY0tleVBhcnQgPSBkb21haW5QYXJ0cy5zaGlmdCgpIHx8IFwiXCI7XG4gICAgbGV0IGNlcnRBY3R1YWxQdWJsaWNLZXlQYXJ0ID0gZ2V0RG9tYWluUGFydEZyb21QdWJsaWNLZXkoY2VydFBhcnNlZC5wdWJsaWNLZXkpO1xuICAgIGlmIChjZXJ0RXhwZWN0ZWRQdWJsaWNLZXlQYXJ0ICE9PSBjZXJ0QWN0dWFsUHVibGljS2V5UGFydCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENlcnRpZmljYXRlIHB1YmxpYyBrZXkgaW4gdGhlIHVybCBpcyAke2NlcnRFeHBlY3RlZFB1YmxpY0tleVBhcnR9LCBidXQgaW4gdGhlIGNlcnQgaXMgJHtjZXJ0QWN0dWFsUHVibGljS2V5UGFydH1gKTtcbiAgICB9XG5cblxuICAgIGxldCBuYW1lQ29uc3RyYWludHMgPSBpc3N1ZXJDZXJ0UGFyc2VkLmdldEV4dGVuc2lvbihcIm5hbWVDb25zdHJhaW50c1wiKSBhcyBhbnk7XG4gICAgaWYgKCFuYW1lQ29uc3RyYWludHMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDQSBtdXN0IGhhdmUgbmFtZUNvbnN0cmFpbnRzYCk7XG4gICAgfVxuICAgIGxldCBzdWJ0cmVlcyA9IG5hbWVDb25zdHJhaW50cy5wZXJtaXR0ZWRTdWJ0cmVlcztcbiAgICBpZiAoIXN1YnRyZWVzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ0EgbXVzdCBoYXZlIG5hbWVDb25zdHJhaW50cy5wZXJtaXR0ZWRTdWJ0cmVlc2ApO1xuICAgIH1cbiAgICBsZXQgc3VidHJlZVZhbHVlcyA9IHN1YnRyZWVzLm1hcCgoeDogYW55KSA9PiB4LnZhbHVlKTtcbiAgICAvLyBJZ25vcmUgbG9jYWxob3N0RG9tYWluLCBhcyBpdCBjYW4gYWx3YXlzIHNhZmVseSBiZSBhbGxvd2VkICh0aGUgc2FtZSBtYWNoaW5lXG4gICAgLy8gICAgICBpcyBhbHdheXMgYWxsb3dlZCkuXG4gICAgc3VidHJlZVZhbHVlcyA9IHN1YnRyZWVWYWx1ZXMuZmlsdGVyKCh4OiBzdHJpbmcpID0+IHggIT09IGxvY2FsaG9zdERvbWFpbik7XG4gICAgaWYgKHN1YnRyZWVWYWx1ZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ0EgbXVzdCBoYXZlIGEgc2luZ2xlIGNvbnN0cmFpbmVkIGRvbWFpbiAoaGFkICR7SlNPTi5zdHJpbmdpZnkoc3VidHJlZVZhbHVlcyl9KWApO1xuICAgIH1cblxuICAgIGxldCBzdWJ0cmVlID0gc3VidHJlZVZhbHVlc1swXTtcbiAgICBpZiAoc3VidHJlZSAhPT0gc3ViamVjdCAmJiAhc3ViamVjdC5lbmRzV2l0aChcIi5cIiArIHN1YnRyZWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgbXVzdCBiZSBhIHN1YnRyZWUgb2YgdGhlIENBIChDQTogJHtzdWJ0cmVlfSwgY2VydDogJHtzdWJqZWN0fSlgKTtcbiAgICB9XG5cbiAgICB2YWxpZGF0ZUFsdE5hbWVzKGNlcnRQYXJzZWQsIHN1YmplY3QpO1xuXG4gICAgLy8gVmVyaWZ5IGlzc3VlciBBQ1RVQUxMWSBzaWduZWQgY2VydFBhcnNlZFxuICAgIGlmICghaXNzdWVyQ2VydFBhcnNlZC52ZXJpZnkoY2VydFBhcnNlZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJc3N1ZXIgZGlkIG5vdCBzaWduIGNlcnRpZmljYXRlYCk7XG4gICAgfVxufVxuXG4vLyBSZXF1aXJlIGFsdCBuYW1lcyB0byBiZSBlaXRoZXIgZXF1YWwgdG8gXCJDTlwiLCBvciBhIHN1YnRyZWUgb2YgXCJDTlwiXG5mdW5jdGlvbiB2YWxpZGF0ZUFsdE5hbWVzKGNlcnRQYXJzZWQ6IGZvcmdlLnBraS5DZXJ0aWZpY2F0ZSwgc3ViamVjdDogc3RyaW5nKSB7XG4gICAgbGV0IGxvY2FsaG9zdERvbWFpbiA9IFwiMTI3LTAtMC0xLlwiICsgc3ViamVjdC5zcGxpdChcIi5cIikuc2xpY2UoLTIpLmpvaW4oXCIuXCIpO1xuXG4gICAgbGV0IGFsdE5hbWVzT2JqID0gY2VydFBhcnNlZC5nZXRFeHRlbnNpb24oXCJzdWJqZWN0QWx0TmFtZVwiKSBhcyBhbnk7XG4gICAgbGV0IGFsdE5hbWVzID0gYWx0TmFtZXNPYmo/LmFsdE5hbWVzLm1hcCgoeDogYW55KSA9PiB4LnZhbHVlKTtcbiAgICAvLyBBbGxvdyBsb2NhbGhvc3REb21haW4sIGFzIGl0IGNhbiBhbHdheXMgc2FmZWx5IGJlIGFsbG93ZWRcbiAgICBhbHROYW1lcyA9IGFsdE5hbWVzLmZpbHRlcigoeDogc3RyaW5nKSA9PiB4ICE9PSBsb2NhbGhvc3REb21haW4pO1xuICAgIGlmIChcbiAgICAgICAgYWx0TmFtZXMuc29tZSgoeDogc3RyaW5nKSA9PlxuICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgICB4ID09PSBzdWJqZWN0XG4gICAgICAgICAgICAgICAgfHwgeC5lbmRzV2l0aChcIi5cIiArIHN1YmplY3QpXG4gICAgICAgICAgICAgICAgLy8gQ29tbWVudGVkIG91dCwgYmVjYXVzZS4uLiBpdCBpcyBzbyBlYXN5IHRvIHB1Ymxpc2ggYSAxMjcuMC4wLjEgQSByZWNvcmQsXG4gICAgICAgICAgICAgICAgLy8gIGFuZCBldmVuIHRvIGdlbmVyYXRlIGEgcmVhbCBjZXJ0LCBzbywgd2Ugc2hvdWxkIGpzdXQgZG8gdGhhdCwgYW5kIGtlZXAgaXQgc2VjdXJlLlxuICAgICAgICAgICAgICAgIC8vICBJZiB3ZSBuZWVkIHRoaXMgZm9yIGRldmVsb3BtZW50IHdlIGNhbiBwdXQgaXQgYmVoaW5kIGEgZmxhZywgc28gbm9uLWRldmVsb3BtZW50XG4gICAgICAgICAgICAgICAgLy8gIGluc3RhbmNlcyBhcmUgc3RpbGwgc2VjdXJlLlxuICAgICAgICAgICAgICAgIC8vIC8vIEFsc28gYWxsb3cgMTI3LjAuMC4xLCBmb3IgbG9jYWwgdGVzdGluZywgZm9yIG5vdz9cbiAgICAgICAgICAgICAgICAvLyAvLyAgLSBUaGlzIG1pZ2h0IGJlIGluc2VjdXJlIGlmIHRoZXNlIGFyZSB0cnVzdGVkIGJ5IHRoZSBicm93c2VyLFxuICAgICAgICAgICAgICAgIC8vIC8vICAgICAgYXMgdGhlbiBhbnlvbmUgdGhhdCBzdG9yZXMgYW55IGNvb2tpZXMgaW4gdGhpcyBpcCBjYW4gaGF2ZVxuICAgICAgICAgICAgICAgIC8vIC8vICAgICAgdGhlIGNvb2tpZXMgc3RvbGVuLiBCdXQuLi4gaWYgdGhpcyBpcyBqdXN0IGNyb3NzLXNlcnZlci4uLlxuICAgICAgICAgICAgICAgIC8vIC8vICAgICAgSSBkb24ndCBzZWUgaG93IHRoaXMgY291bGQgY2F1c2UgYSBzZWN1cml0eSB2dWxuZXJhYmlsaXR5LlxuICAgICAgICAgICAgICAgIC8vIHx8IHggPT09IEJ1ZmZlci5mcm9tKFsxMjcsIDAsIDAsIDFdKS50b1N0cmluZygpXG4gICAgICAgICAgICApXG4gICAgICAgIClcbiAgICApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGFsdCBuYW1lcy4gTXVzdCBiZSBzdWJ0cmVlcyBvZiB0aGUgc3ViamVjdCAoQ04pICR7SlNPTi5zdHJpbmdpZnkoc3ViamVjdCl9LCB3YXMgJHtKU09OLnN0cmluZ2lmeShhbHROYW1lcyl9YCk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUtleVBhaXIoKSB7XG4gICAgcmV0dXJuIG1lYXN1cmVCbG9jayhmdW5jdGlvbiBnZW5lcmF0ZUtleVBhaXIoKSB7XG4gICAgICAgIC8vIE5PVEU6IFdlIHVzZSBFRDI1NTE5IGJlY2F1c2UgaXQgY2FuIGdlbmVyYXRlZCBrZXlzIGFib3V0IDEwWCBmYXN0ZXIsIFdISUNILCBpcyBzdGlsbCBzbG93XG4gICAgICAgIC8vICAofjZtcyBvbiBteSBtYWNoaW5lKS4gU28gd2UgREVGSU5JVEVMWSBkb24ndCB3YW50IGl0IHRvIGJlIDEwWCBzbG93ZXIhXG4gICAgICAgIC8vIE5PVEU6IEVEMjU1MTkgZG9lbnMndCBoYXZlIGdyZWF0IHN1cHBvcnQgaW4gYnJvd3NlcnMsIGJ1dCB3ZSBzaG91bGRuJ3QgbmVlZCBzZWxmIHNpZ25lZCBjZXJ0aWZpY2F0ZXNcbiAgICAgICAgLy8gIGluIHRoZSBicm93c2VyIGFueXdheS5cbiAgICAgICAgLy8gIC0gaHR0cHM6Ly9zZWN1cml0eS5zdGFja2V4Y2hhbmdlLmNvbS9hLzIzNjk0My8yODIzNjdcbiAgICAgICAgLy9sZXQga2V5UGFpciA9IGZvcmdlLmVkMjU1MTkuZ2VuZXJhdGVLZXlQYWlyKCk7XG4gICAgICAgIGxldCBrZXlQYWlyID0gZm9yZ2UucGtpLnJzYS5nZW5lcmF0ZUtleVBhaXIoKTtcbiAgICAgICAgcmV0dXJuIGtleVBhaXI7XG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVSU0FLZXlQYWlyKCkge1xuICAgIHJldHVybiBtZWFzdXJlQmxvY2soZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlyKCkge1xuICAgICAgICByZXR1cm4gZm9yZ2UucGtpLnJzYS5nZW5lcmF0ZUtleVBhaXIoKTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlVGVzdENBKGRvbWFpbjogc3RyaW5nKSB7XG4gICAgY29uc3Qga2V5UGFpciA9IGdlbmVyYXRlS2V5UGFpcigpO1xuICAgIGxldCBjYVB1YmxpY0tleVBhcnQgPSBnZXREb21haW5QYXJ0RnJvbVB1YmxpY0tleShrZXlQYWlyLnB1YmxpY0tleSk7XG4gICAgbGV0IGZ1bGxEb21haW4gPSBgJHtjYVB1YmxpY0tleVBhcnR9LiR7ZG9tYWlufWA7XG4gICAgaWYgKCFpc05vZGUoKSkge1xuICAgICAgICBmdWxsRG9tYWluID0gYCR7Y2FQdWJsaWNLZXlQYXJ0fS4ke2RvbWFpbn1gO1xuICAgIH1cblxuICAgIHJldHVybiBjcmVhdGVYNTA5KHsgZG9tYWluOiBmdWxsRG9tYWluLCBpc3N1ZXI6IFwic2VsZlwiLCBrZXlQYWlyLCBsaWZlU3BhbjogdGltZUluRGF5ICogMzY1ICogMjAgfSk7XG59XG5cbmxldCBpZGVudGl0eUNBID0gY2FjaGUoKGRvbWFpbjogc3RyaW5nKSA9PiB7XG4gICAgbGV0IGlkZW50aXR5Q0EgPSBsYXp5KChhc3luYyAoKTogUHJvbWlzZTxYNTA5S2V5UGFpcj4gPT4ge1xuICAgICAgICBsZXQgaWRlbnRpdHlDQUNhY2hlZCA9IGdldElkZW50aXR5U3RvcmUoZG9tYWluKTtcbiAgICAgICAgbGV0IGNhQ2FjaGVkID0gYXdhaXQgaWRlbnRpdHlDQUNhY2hlZC5nZXQoKTtcbiAgICAgICAgaWYgKCFjYUNhY2hlZCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYEdlbmVyYXRpbmcgbmV3IGlkZW50aXR5IENBYCk7XG4gICAgICAgICAgICBjb25zdCBrZXlQYWlyID0gZ2VuZXJhdGVLZXlQYWlyKCk7XG4gICAgICAgICAgICBsZXQgY2FQdWJsaWNLZXlQYXJ0ID0gZ2V0RG9tYWluUGFydEZyb21QdWJsaWNLZXkoa2V5UGFpci5wdWJsaWNLZXkpO1xuICAgICAgICAgICAgbGV0IGZ1bGxEb21haW4gPSBgJHtjYVB1YmxpY0tleVBhcnR9LiR7ZG9tYWlufWA7XG4gICAgICAgICAgICBpZiAoIWlzTm9kZSgpKSB7XG4gICAgICAgICAgICAgICAgZnVsbERvbWFpbiA9IGAke2NhUHVibGljS2V5UGFydH0uJHtkb21haW59YDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHZhbHVlID0gY3JlYXRlWDUwOSh7IGRvbWFpbjogZnVsbERvbWFpbiwgaXNzdWVyOiBcInNlbGZcIiwga2V5UGFpciwgbGlmZVNwYW46IHRpbWVJbkRheSAqIDM2NSAqIDIwIH0pO1xuXG4gICAgICAgICAgICBjYUNhY2hlZCA9IHtcbiAgICAgICAgICAgICAgICBkb21haW46IHZhbHVlLmRvbWFpbixcbiAgICAgICAgICAgICAgICBjZXJ0QjY0OiB2YWx1ZS5jZXJ0LnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICAgICAgICAgICAgIGtleUI2NDogdmFsdWUua2V5LnRvU3RyaW5nKFwiYmFzZTY0XCIpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGF3YWl0IGlkZW50aXR5Q0FDYWNoZWQuc2V0KGNhQ2FjaGVkKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmVzdWx0ID0ge1xuICAgICAgICAgICAgZG9tYWluOiBjYUNhY2hlZC5kb21haW4sXG4gICAgICAgICAgICBjZXJ0OiBCdWZmZXIuZnJvbShjYUNhY2hlZC5jZXJ0QjY0LCBcImJhc2U2NFwiKSxcbiAgICAgICAgICAgIGtleTogQnVmZmVyLmZyb20oY2FDYWNoZWQua2V5QjY0LCBcImJhc2U2NFwiKSxcbiAgICAgICAgfTtcbiAgICAgICAgdHJ1c3RDZXJ0aWZpY2F0ZShyZXN1bHQuY2VydC50b1N0cmluZygpKTtcbiAgICAgICAgaWRlbnRpdHlDQS5zZXQocmVzdWx0KTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KSBhcyAoKCkgPT4gTWF5YmVQcm9taXNlPFg1MDlLZXlQYWlyPikpO1xuICAgIHJldHVybiBpZGVudGl0eUNBO1xufSk7XG5cbi8vIElNUE9SVEFOVCEgV2UgZG8gbm90IGVtYmVkIGFueSBkZWJ1ZyBpbmZvIGluIHRoaXMgZG9tYWluLiBJZiB3ZSBkaWQsIGl0IHdvdWxkIGJlIHVzZWZ1bCxcbi8vICBidXQuLi4gcG90ZW50YWxseSBhIHNlY3VyaXR5IHZ1bG5lcmFiaWxpdHksIGFzIGlmIHRoZSBkZWJ1ZyBpbmZvIChzdWNoIGFzIGEgcHJlZml4KVxuLy8gIGlzIHVzZWQgdG8gaWRlbnRpZnkgd2hhdCBhIGNlcnRpZmljYXRlIGlzIGZvciwgaXQgd291bGQgYmUgZWFzeSBmb3IgYW4gYXR0YWNrIHRvXG4vLyAgZm9yZ2UgdGhpcyAoYXMgdGhlIGRlYnVnIGluZm8gd29uJ3QgYmUgc2VjdXJlZCkuIFNvIGl0IGlzIG11Y2ggYmV0dGVyIHRvIGtlZXBcbi8vICB0aGUgY2VydGlmaWNhdGUgb3BhcXVlLCBhbmQgdGhlbiByZXF1aXJlIGFueSBtZXRhZGF0YSB0byBiZSBhY3R1YWxseSB2ZXR0ZWRcbi8vICAoYW5kIGhvcGVmdWxseSBzdG9yZWQgaW4gYSBVSSwgc2hvd2luZyBJUCwgdGltZSwgZXRjKS5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDZXJ0RnJvbUNBKGNvbmZpZzoge1xuICAgIENBS2V5UGFpcjogWDUwOUtleVBhaXI7XG59KTogWDUwOUtleVBhaXIge1xuICAgIHJldHVybiBtZWFzdXJlQmxvY2soZnVuY3Rpb24gY3JlYXRlQ2VydEZyb21DQSgpIHtcbiAgICAgICAgbGV0IHsgQ0FLZXlQYWlyIH0gPSBjb25maWc7XG4gICAgICAgIGNvbnN0IGtleVBhaXIgPSBnZW5lcmF0ZUtleVBhaXIoKTtcbiAgICAgICAgbGV0IGRvbWFpbktleVBhcnQgPSBnZXREb21haW5QYXJ0RnJvbVB1YmxpY0tleShrZXlQYWlyLnB1YmxpY0tleSk7XG4gICAgICAgIGxldCBmdWxsRG9tYWluID0gYCR7ZG9tYWluS2V5UGFydH0uJHtjb25maWcuQ0FLZXlQYWlyLmRvbWFpbn1gO1xuICAgICAgICByZXR1cm4gY3JlYXRlWDUwOSh7XG4gICAgICAgICAgICBkb21haW46IGZ1bGxEb21haW4sXG4gICAgICAgICAgICBpc3N1ZXI6IENBS2V5UGFpcixcbiAgICAgICAgICAgIGtleVBhaXIsXG4gICAgICAgICAgICBsaWZlU3BhbjogdGltZUluRGF5ICogMzY1ICogMTAsXG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWFjaGluZUlkKGRvbWFpbk5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiBkb21haW5OYW1lLnNwbGl0KFwiLlwiKS5zbGljZSgtMykuam9pbihcIi5cIik7XG59XG5cbmV4cG9ydCB0eXBlIE5vZGVJZFBhcnRzID0ge1xuICAgIHRocmVhZElkOiBzdHJpbmc7XG4gICAgbWFjaGluZUlkOiBzdHJpbmc7XG4gICAgZG9tYWluOiBzdHJpbmc7XG4gICAgcG9ydDogbnVtYmVyO1xufTtcbmV4cG9ydCBmdW5jdGlvbiBkZWNvZGVOb2RlSWQobm9kZUlkOiBzdHJpbmcpOiBOb2RlSWRQYXJ0cyB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IGxvY2F0aW9uT2JqID0gZ2V0Tm9kZUlkTG9jYXRpb24obm9kZUlkKTtcbiAgICBpZiAoIWxvY2F0aW9uT2JqKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGxldCBwYXJ0cyA9IGxvY2F0aW9uT2JqLmFkZHJlc3Muc3BsaXQoXCIuXCIpO1xuICAgIGlmIChub2RlSWQuc3RhcnRzV2l0aChcIjEyNy0wLTAtMS5cIikgJiYgcGFydHMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB0aHJlYWRJZDogXCJcIixcbiAgICAgICAgICAgIG1hY2hpbmVJZDogcGFydHMuYXQoLTMpIHx8IFwiXCIsXG4gICAgICAgICAgICBkb21haW46IHBhcnRzLnNsaWNlKC0yKS5qb2luKFwiLlwiKSxcbiAgICAgICAgICAgIHBvcnQ6IGxvY2F0aW9uT2JqLnBvcnQsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGlmIChwYXJ0cy5sZW5ndGggPCA0KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHRocmVhZElkOiBwYXJ0cy5hdCgtNCkgfHwgXCJcIixcbiAgICAgICAgbWFjaGluZUlkOiBwYXJ0cy5hdCgtMykgfHwgXCJcIixcbiAgICAgICAgZG9tYWluOiBwYXJ0cy5zbGljZSgtMikuam9pbihcIi5cIikgfHwgXCJcIixcbiAgICAgICAgcG9ydDogbG9jYXRpb25PYmoucG9ydCxcbiAgICB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZU5vZGVJZEFzc2VydChub2RlSWQ6IHN0cmluZyk6IE5vZGVJZFBhcnRzIHtcbiAgICBsZXQgcmVzdWx0ID0gZGVjb2RlTm9kZUlkKG5vZGVJZCk7XG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG5vZGVJZDogJHtub2RlSWR9YCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlTm9kZUlkKHBhcnRzOiBOb2RlSWRQYXJ0cykge1xuICAgIHJldHVybiBgJHtwYXJ0cy50aHJlYWRJZH0uJHtwYXJ0cy5tYWNoaW5lSWR9LiR7cGFydHMuZG9tYWlufToke3BhcnRzLnBvcnR9YDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldElkZW50aXR5Q0FSYXcoZG9tYWluOiBzdHJpbmcsIGpzb246IHN0cmluZykge1xuICAgIGxldCBpZGVudGl0eUNBQ2FjaGVkID0gZ2V0SWRlbnRpdHlTdG9yZShkb21haW4pO1xuICAgIGxldCBvYmogPSBKU09OLnBhcnNlKGpzb24pIGFzIHtcbiAgICAgICAgZG9tYWluOiBzdHJpbmc7XG4gICAgICAgIGNlcnRCNjQ6IHN0cmluZztcbiAgICAgICAga2V5QjY0OiBzdHJpbmc7XG4gICAgfTtcbiAgICBsZXQgY2EgPSB7XG4gICAgICAgIGRvbWFpbjogb2JqLmRvbWFpbixcbiAgICAgICAgY2VydDogQnVmZmVyLmZyb20ob2JqLmNlcnRCNjQsIFwiYmFzZTY0XCIpLFxuICAgICAgICBrZXk6IEJ1ZmZlci5mcm9tKG9iai5rZXlCNjQsIFwiYmFzZTY0XCIpLFxuICAgIH07XG4gICAgdHJ1c3RDZXJ0aWZpY2F0ZShjYS5jZXJ0LnRvU3RyaW5nKCkpO1xuICAgIGlkZW50aXR5Q0EoZG9tYWluKS5zZXQoY2EpO1xuICAgIGdldFRocmVhZEtleUNlcnRCYXNlKGRvbWFpbikucmVzZXQoKTtcbiAgICBhd2FpdCBpZGVudGl0eUNBQ2FjaGVkLnNldChvYmopO1xuICAgIHJlc2V0QWxsTm9kZUNhbGxGYWN0b3JpZXMoKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRJZGVudGl0eUNBKGRvbWFpbjogc3RyaW5nKSB7XG4gICAgYXdhaXQgaWRlbnRpdHlDQShkb21haW4pKCk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0SWRlbnRpdHlDQShkb21haW46IHN0cmluZyk6IFg1MDlLZXlQYWlyIHtcbiAgICBsZXQgdmFsdWUgPSBpZGVudGl0eUNBKGRvbWFpbikoKTtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIklkZW50aXR5IENBIGlzIG5vdCB5ZXQgbG9hZGVkLiBDYWxsIGFuZCB3YWl0IGZvciBsb2FkSWRlbnRpdHlDQSgpIGluIHlvdXIgc3RhcnR1cCBiZWZvcmUgYWNjZXNzaW5nIHRoZSBpZGVudGl0eSAob3IgY2FsbCBnZXRJZGVudGl0eUNBUHJvbWlzZSgpKVwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuXG4vLyBUT0RPOiBSZXBsYWNlIHRoaXMgd2l0aCBhIGRhdGFiYXNlLCBzbyBpdCBpcyBlYXN5IGZvciB1cyB0byB0cnVzdCBDQXNcbi8vICBjcm9zcyBtYWNoaW5lLCBhbmQgZXZlbiBoYXZlIG11bHRpcGxlIHVzZXJzLCBldGMsIGV0Yy5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJZGVudGl0eUNBUHJvbWlzZShkb21haW46IHN0cmluZyk6IE1heWJlUHJvbWlzZTxYNTA5S2V5UGFpcj4ge1xuICAgIHJldHVybiBpZGVudGl0eUNBKGRvbWFpbikoKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3duTWFjaGluZUlkKGRvbWFpbjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGdldE1hY2hpbmVJZChnZXRJZGVudGl0eUNBKGRvbWFpbikuZG9tYWluKTtcbn1cblxuLyoqIFBhcnQgb2YgdGhlIG1hY2hpbmVJZCBjb21lcyBmcm9tIHRoZSBwdWJsaWNLZXksIHNvIHdlIGNhbiB1c2UgaXQgdG8gdmVyaWZ5ICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5TWFjaGluZUlkRm9yUHVibGljS2V5KGNvbmZpZzoge1xuICAgIG1hY2hpbmVJZDogc3RyaW5nO1xuICAgIHB1YmxpY0tleTogQnVmZmVyO1xufSk6IGJvb2xlYW4ge1xuICAgIGxldCB7IG1hY2hpbmVJZCwgcHVibGljS2V5IH0gPSBjb25maWc7XG4gICAgbGV0IGRvbWFpblBhcnQgPSBnZXREb21haW5QYXJ0RnJvbVB1YmxpY0tleShwdWJsaWNLZXkpO1xuICAgIHJldHVybiBtYWNoaW5lSWQuc3BsaXQoXCIuXCIpLmF0KC0zKSA9PT0gZG9tYWluUGFydDtcbn1cblxuLy8gTk9URTogV2UgZG9uJ3QgaGF2ZSBhIGNhY2hlIHBlciBDQSwgYXMuLi4gdGhlIENBIHNob3VsZCBiZSBzZXQgZmlyc3Rcbi8vICBUT0RPOiBNYXliZSB0aHJvdyBpZiB0aGV5IHRyeSB0byBjaGFuZ2UgdGhlIENBIGFmdGVyIHRoZXkgZ2VuZXJhdGUgYW55IGNlcnRpZmljYXRlcz9cbi8vIFRPRE86IFJlZ2VuZXJhdGUgY2VydGlmaWNhdGVzIGFmdGVyIGVub3VnaCB0aW1lIChhcyB0aHJlYWQgY2VydHMgc2hvdWxkIGJlIHJlbGF0aXZlbHkgc2hvcnQgbGl2ZWQsXG4vLyAgc28gaXQgaXMgcGxhdXNpYmxlIGZvciB0aGVtIHRvIGV4cGlyZSlcbi8vICAtIFdlIHdpbGwgYWxzbyBuZWVkIHRvIHByb3ZpZGUgYSBjYWxsYmFjayBzbyB0aGF0IHVzZXJzIG9mIHRoZSBjZXJ0IGNhbiB1cGRhdGUgdGhlIGNlcnQgdGhleVxuLy8gICAgICBhcmUgdXNpbmcgYXMgd2VsbC5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUaHJlYWRLZXlDZXJ0KGRvbWFpbjogc3RyaW5nKSB7XG4gICAgcmV0dXJuIGdldFRocmVhZEtleUNlcnRCYXNlKGRvbWFpbikoKTtcbn1cbmNvbnN0IGdldFRocmVhZEtleUNlcnRCYXNlID0gY2FjaGUoKGRvbWFpbjogc3RyaW5nKSA9PiBsYXp5KCgpID0+IHtcbiAgICBsZXQgY2EgPSBnZXRJZGVudGl0eUNBKGRvbWFpbik7XG4gICAgcmV0dXJuIGNyZWF0ZUNlcnRGcm9tQ0EoeyBDQUtleVBhaXI6IGNhIH0pO1xufSkpO1xuXG5leHBvcnQgY29uc3QgY3JlYXRlVGVzdEJyb3dzZXJLZXlDZXJ0ID0gbGF6eShhc3luYyAoKSA9PiB7XG4gICAgbGV0IGtleVBhaXIgPSBnZW5lcmF0ZVJTQUtleVBhaXIoKTtcbiAgICByZXR1cm4gYXdhaXQgY3JlYXRlWDUwOSh7IGRvbWFpbjogXCJ0ZXN0XCIsIGlzc3VlcjogXCJzZWxmXCIsIGtleVBhaXIsIGxpZmVTcGFuOiB0aW1lSW5EYXkgKiAzNjUgKiAyMCB9KTtcbn0pO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3duTm9kZUlkKCk6IHN0cmluZyB7XG4gICAgbGV0IG5vZGVJZCA9IFNvY2tldEZ1bmN0aW9uLm1vdW50ZWROb2RlSWQ7XG4gICAgaWYgKCFub2RlSWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOb2RlIG11c3QgYmUgbW91bnRlZCBiZWZvcmUgbm9kZUlkIGlzIGFjY2Vzc2VkYCk7XG4gICAgfVxuICAgIHJldHVybiBub2RlSWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRPd25Ob2RlSWRBbGxvd1VuZGVmaW5lZCgpIHtcbiAgICByZXR1cm4gU29ja2V0RnVuY3Rpb24ubW91bnRlZE5vZGVJZDtcbn0iXX0=
530
- /* _JS_SOURCE_HASH = "be134c2204a9b9ba8ae9e00631d6a5b87b56d49723154c00ab8e24807b63c905"; */
465
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjZXJ0cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsa0RBQWtEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVsRCxNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUUxQiwrbkJBQStuQjtBQUMvbkIsc0lBQXNJO0FBRXRJLGlEQUFpRDtBQUVqRCx1RUFBK0Q7QUFDL0Qsa0RBQW9DO0FBR3BDLHlEQUEwRDtBQUUxRCwwREFBK0I7QUFDL0Isb0RBQTRCO0FBQzVCLDZEQUFpRTtBQUNqRSxtRUFBOEY7QUFDOUYsNkRBQWtIO0FBQ2xILG1FQUFnRTtBQUNoRSw2REFBMEU7QUFDMUUscUVBQXVEO0FBQ3ZELHdDQUF1QztBQUV2QyxJQUFBLHNCQUFPLEVBQUMsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDcEQsSUFBQSxzQkFBTyxFQUFDLE9BQU8sRUFBRSxXQUFXLEVBQUUsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBRW5ELE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUV6QixRQUFBLGtCQUFrQixHQUFHLHNDQUFzQyxDQUFDO0FBRTVELFFBQUEsa0JBQWtCLEdBQUcsY0FBYyxDQUFDO0FBR2pELFNBQVMsZ0JBQWdCLENBQUMsTUFBYztJQUNwQyxPQUFPLElBQUEsb0NBQVcsRUFBc0IsTUFBTSxFQUFFLDBCQUFrQixDQUFDLENBQUM7QUFDeEUsQ0FBQztBQUlELFNBQWdCLGFBQWEsQ0FBQyxJQUFxQjtJQUMvQyxJQUFJLE9BQU8sR0FBRyxJQUFJLGdCQUFNLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sQ0FBQztJQUN2RCxJQUFJLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcs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RUFBRSxFQUFFLENBQUMsSUFBQSxjQUFJLEVBQUMsR0FBRyxFQUFFO0lBQzdELElBQUksRUFBRSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvQixPQUFPLGdCQUFnQixDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDL0MsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUVKLFNBQWdCLFlBQVk7SUFDeEIsSUFBSSxNQUFNLEdBQUcsK0JBQWMsQ0FBQyxhQUFhLENBQUM7SUFDMUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO0lBQ3RFLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNsQixDQUFDO0FBTkQsb0NBTUM7QUFFRCxTQUFnQiwwQkFBMEI7SUFDdEMsT0FBTywrQkFBYyxDQUFDLGFBQWEsQ0FBQztBQUN4QyxDQUFDO0FBRkQsZ0VBRUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSBwYXRoPVwiLi9ub2RlLWZvcmdlLWVkMjU1MTkuZC50c1wiIC8+XG5cbm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbi8vIE5PVEU6IFdlIGNhbid0IHVzZSBjcnlwdG8uc3VidGxlIChub24tZXh0cmFjdGFibGUgQ3J5cHRvS2V5cykgZm9yIG91ciBrZXlzLCBiZWNhdXNlIHN1YnRsZSBpcyBhc3luY2hyb25vdXMsIGFuZCBldmVyeXRoaW5nIGhlcmUgKGtleSBnZW5lcmF0aW9uLCBjZXJ0IGNyZWF0aW9uLCBzaWduaW5nKSBtdXN0IGJlIGF2YWlsYWJsZSBzeW5jaHJvbm91c2x5LiBUaGUgb25seSByZWFsIGJlbmVmaXQgb2Ygc3VidGxlIGlzIHRoYXQgYSBjcm9zcy1zaXRlIHNjcmlwdGluZyBhdHRhY2sgY2FuJ3QgZXhmaWx0cmF0ZSB0aGUga2V5LiBXaGljaCwgd2hpbGUgbmljZSwgaXMgb2YgbWlub3IgYmVuZWZpdCwgYXMgdGhlIGNyb3NzLXNpdGUgc2NyaXB0IGNhbiBhbHJlYWR5IGRvIHF1aXRlIGEgYml0IG9mIGRhbWFnZSBhbnl3YXkgd2l0aCBhY2Nlc3MuIEFuZCBpZiB0aGF0IGhhcHBlbnMsIHRoZSBmaXJzdCB0aGluZyB0aGUgdXNlciBpcyBwcm9iYWJseSBnb2luZyB0byBkbyBpcyByZXNldCBhbGwgdGhlaXIgY3JlZGVudGlhbHMsIHdoaWNoIHNvbHZlcyB0aGUgY2FzZSBvZiB0aGUga2V5IGJlaW5nIGV4ZmlsdHJhdGVkIGFueXdheSAoYnkgdGVsbGluZyB0aGUgc2VydmVyIHRvIHN0b3AgdHJ1c3RpbmcgYWxsIGlkZW50aXRpZXMpLlxuLy8gTk9URTogV2UgYXJlIGp1c3Qgbm90IGdvaW5nIHRvIHN1cHBvcnQgSFRUUFMgYnJvd3NlciBjZXJ0cy4gT3VyIGNvZGUgaXMgcHVyZWx5IGZvciBpZGVudGlmaWNhdGlvbiwgYW5kIHNvIGl0IG9ubHkgc3VwcG9ydHMgRUQyNTUxOS5cblxuLy8gaHR0cHM6Ly93d3cucmZjLWVkaXRvci5vcmcvcmZjL3JmYzUyODAjcGFnZS00MlxuXG5pbXBvcnQgeyBzZXRGbGFnIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9yZXF1aXJlL2NvbXBpbGVGbGFnc1wiO1xuaW1wb3J0ICogYXMgZm9yZ2UgZnJvbSBcIm5vZGUtZm9yZ2VcIjtcbmltcG9ydCBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCBmc1N5bmMgZnJvbSBcImZzXCI7XG5pbXBvcnQgeyBjYWNoZSwgbGF6eSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL2NhY2hpbmdcIjtcbmltcG9ydCB7IGlzTm9kZSB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vc3JjL21pc2NcIjtcbmltcG9ydCBzaGEyNjUgZnJvbSBcImpzLXNoYTI1NlwiO1xuaW1wb3J0IGNyeXB0byBmcm9tIFwiY3J5cHRvXCI7XG5pbXBvcnQgeyB0cnVzdENlcnRpZmljYXRlIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvY2VydFN0b3JlXCI7XG5pbXBvcnQgeyBtZWFzdXJlQmxvY2ssIG1lYXN1cmVGbmMsIG1lYXN1cmVXcmFwIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvcHJvZmlsaW5nL21lYXN1cmVcIjtcbmltcG9ydCB7IGdldE5vZGVJZERvbWFpbiwgZ2V0Tm9kZUlkRG9tYWluTWF5YmVVbmRlZmluZWQsIGdldE5vZGVJZExvY2F0aW9uIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbm9kZUNhY2hlXCI7XG5pbXBvcnQgeyBTb2NrZXRGdW5jdGlvbiB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vU29ja2V0RnVuY3Rpb25cIjtcbmltcG9ydCB7IHJlc2V0QWxsTm9kZUNhbGxGYWN0b3JpZXMgfSBmcm9tIFwic29ja2V0LWZ1bmN0aW9uL3NyYy9ub2RlQ2FjaGVcIjtcbmltcG9ydCB7IGdldEtleVN0b3JlIH0gZnJvbSBcIi4vcGVyc2lzdGVudExvY2FsU3RvcmFnZVwiO1xuaW1wb3J0IHsgZWxsaXBzaXplIH0gZnJvbSBcIi4uL3N0cmluZ3NcIjtcblxuc2V0RmxhZyhyZXF1aXJlLCBcIm5vZGUtZm9yZ2VcIiwgXCJhbGxvd2NsaWVudFwiLCB0cnVlKTtcbnNldEZsYWcocmVxdWlyZSwgXCJqcy1zaGEyNTZcIiwgXCJhbGxvd2NsaWVudFwiLCB0cnVlKTtcblxuY29uc3QgdGltZUluRGF5ID0gMTAwMCAqIDYwICogNjAgKiAyNDtcblxuZXhwb3J0IGNvbnN0IENBX05PVF9GT1VORF9FUlJPUiA9IFwiMThhYTczMTgtZjg4Zi00ZDJkLWI0MWYtM2RhZjRhNDMzODI3XCI7XG5cbmV4cG9ydCBjb25zdCBpZGVudGl0eVN0b3JhZ2VLZXkgPSBcIm1hY2hpbmVDQV8xNFwiO1xuZXhwb3J0IHR5cGUgSWRlbnRpdHlTdG9yYWdlVHlwZSA9IHsgZG9tYWluOiBzdHJpbmc7IGNlcnRCNjQ6IHN0cmluZzsga2V5QjY0OiBzdHJpbmcgfTtcblxuZnVuY3Rpb24gZ2V0SWRlbnRpdHlTdG9yZShkb21haW46IHN0cmluZykge1xuICAgIHJldHVybiBnZXRLZXlTdG9yZTxJZGVudGl0eVN0b3JhZ2VUeXBlPihkb21haW4sIGlkZW50aXR5U3RvcmFnZUtleSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgWDUwOUtleVBhaXIgeyBkb21haW46IHN0cmluZzsgY2VydDogQnVmZmVyOyBrZXk6IEJ1ZmZlcjsgfVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29tbW9uTmFtZShjZXJ0OiBCdWZmZXIgfCBzdHJpbmcpIHtcbiAgICBsZXQgc3ViamVjdCA9IG5ldyBjcnlwdG8uWDUwOUNlcnRpZmljYXRlKGNlcnQpLnN1YmplY3Q7XG4gICAgbGV0IHN1YmplY3RLVlBzID0gbmV3IE1hcChzdWJqZWN0LnNwbGl0KFwiLFwiKS5tYXAoeCA9PiB4LnRyaW0oKS5zcGxpdChcIj1cIikpLm1hcCh4ID0+IFt4WzBdLCB4LnNsaWNlKDEpLmpvaW4oXCI9XCIpXSkpO1xuICAgIGxldCBjb21tb25OYW1lID0gc3ViamVjdEtWUHMuZ2V0KFwiQ05cIik7XG4gICAgaWYgKCFjb21tb25OYW1lKSB0aHJvdyBuZXcgRXJyb3IoYE5vIGNvbW1vbiBuYW1lIGluIHN1YmplY3Q6ICR7c3ViamVjdH1gKTtcbiAgICByZXR1cm4gY29tbW9uTmFtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVg1MDkoXG4gICAgY29uZmlnOiB7XG4gICAgICAgIGRvbWFpbjogc3RyaW5nO1xuICAgICAgICBpc3N1ZXI6IFg1MDlLZXlQYWlyIHwgXCJzZWxmXCI7XG4gICAgICAgIGxpZmVTcGFuOiBudW1iZXI7XG4gICAgICAgIGtleVBhaXI6IHtcbiAgICAgICAgICAgIHB1YmxpY0tleTogZm9yZ2UuRWQyNTUxOVB1YmxpY0tleTtcbiAgICAgICAgICAgIHByaXZhdGVLZXk6IGZvcmdlLkVkMjU1MTlQcml2YXRlS2V5O1xuICAgICAgICB9O1xuICAgIH1cbik6IFg1MDlLZXlQYWlyIHtcbiAgICByZXR1cm4gbWVhc3VyZUJsb2NrKGZ1bmN0aW9uIGNyZWF0ZVg1MDkoKSB7XG4gICAgICAgIGxldCB7IGRvbWFpbiwgaXNzdWVyLCBsaWZlU3Bhbiwga2V5UGFpciB9ID0gY29uZmlnO1xuXG4gICAgICAgIGxldCBjZXJ0T2JqID0gZm9yZ2UucGtpLmNyZWF0ZUNlcnRpZmljYXRlKCk7XG4gICAgICAgIGNlcnRPYmoucHVibGljS2V5ID0ga2V5UGFpci5wdWJsaWNLZXkgYXMgdW5rbm93biBhcyBmb3JnZS5wa2kuUHVibGljS2V5O1xuICAgICAgICBjZXJ0T2JqLnNlcmlhbE51bWJlciA9IFwiMDFcIjtcbiAgICAgICAgLy8gR2l2ZSBpdCA1IG1pbnV0ZXMgYmVmb3JlIG5vdy4gSWYgd2UgZ2l2ZSBpdCB0b28gbXVjaCB0aW1lLCBpdCBjYW4gbG9vayBsaWtlIHRoZSBjZXJ0IGlzIHJlYWxseSBvbGQsIHdoaWNoIHdpbGwgdHJpZ2dlciB2YXJpb3VzIHByb2Nlc3NlcyB0byB0cnkgdG8gZ2V0IGEgZnJlc2hlciBvbmUgKGFzIGlmIGl0IGxhc3RzIGZvciAxIGhvdXIsIGJ1dCB3ZSBzZXQgbm90QmVmb3JlIHRvIDEgbW9udGggYWdvLCBpdCBsb29rcyAxIG1vbnRoIG9sZCwgYW5kIHNvIGFsbW9zdCBleHBpcmVkLCB3aGVuIGl0IGlzbid0Li4uKVxuICAgICAgICBjZXJ0T2JqLnZhbGlkaXR5Lm5vdEJlZm9yZSA9IG5ldyBEYXRlKERhdGUubm93KCkgLSAxMDAwICogNjAgKiA1KTtcbiAgICAgICAgY2VydE9iai52YWxpZGl0eS5ub3RBZnRlciA9IG5ldyBEYXRlKERhdGUubm93KCkgKyBsaWZlU3Bhbik7XG5cbiAgICAgICAgY29uc3QgY29tbW9uTmFtZUF0dHJzID0gW3sgbmFtZTogXCJjb21tb25OYW1lXCIsIHZhbHVlOiBkb21haW4gfV07XG4gICAgICAgIGNlcnRPYmouc2V0U3ViamVjdChjb21tb25OYW1lQXR0cnMpO1xuXG4gICAgICAgIGlmIChpc3N1ZXIgPT09IFwic2VsZlwiKSB7XG4gICAgICAgICAgICBjZXJ0T2JqLnNldElzc3Vlcihjb21tb25OYW1lQXR0cnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2VydE9iai5zZXRJc3N1ZXIoZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbVBlbShpc3N1ZXIuY2VydC50b1N0cmluZygpKS5zdWJqZWN0LmF0dHJpYnV0ZXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGV4dGVuc2lvbnMgPSBbXTtcbiAgICAgICAgY29uc3QgaXNDQSA9IGlzc3VlciA9PT0gXCJzZWxmXCI7XG4gICAgICAgIGlmIChpc0NBKSB7XG4gICAgICAgICAgICBleHRlbnNpb25zLnB1c2goeyBuYW1lOiBcImJhc2ljQ29uc3RyYWludHNcIiwgY0E6IHRydWUgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbG9jYWxIb3N0RG9tYWluID0gXCIxMjctMC0wLTEuXCIgKyBkb21haW4uc3BsaXQoXCIuXCIpLnNsaWNlKC0yKS5qb2luKFwiLlwiKTtcblxuICAgICAgICBleHRlbnNpb25zLnB1c2goLi4uW1xuICAgICAgICAgICAgeyBuYW1lOiBcImtleVVzYWdlXCIsIGtleUNlcnRTaWduOiBpc0NBLCBkaWdpdGFsU2lnbmF0dXJlOiB0cnVlLCBub25SZXB1ZGlhdGlvbjogdHJ1ZSwga2V5RW5jaXBoZXJtZW50OiB0cnVlLCBkYXRhRW5jaXBoZXJtZW50OiB0cnVlIH0sXG4gICAgICAgICAgICB7IG5hbWU6IFwic3ViamVjdEtleUlkZW50aWZpZXJcIiB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG5hbWU6IFwic3ViamVjdEFsdE5hbWVcIixcbiAgICAgICAgICAgICAgICBhbHROYW1lczogW1xuICAgICAgICAgICAgICAgICAgICB7IHR5cGU6IDIsIHZhbHVlOiBkb21haW4gfSxcbiAgICAgICAgICAgICAgICAgICAgeyB0eXBlOiAyLCB2YWx1ZTogXCIqLlwiICsgZG9tYWluIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgdHlwZTogMiwgdmFsdWU6IGxvY2FsSG9zdERvbWFpbiB9LFxuICAgICAgICAgICAgICAgICAgICAvLyBOT1RFOiBObyBsb25nZXIgYWxsb3cgMTI3LjAuMC4xICh7IHR5cGU6IDcsIGlwOiBcIjEyNy4wLjAuMVwiIH0pLCB0byBtYWtlIHRoaXMgbW9yZSBzZWN1cmUuIFdlIG1pZ2h0IGVuYWJsZSB0aGlzIGJlaGF2aW9yIGJlaGluZCBhIGZsYWcsIGZvciBkZXZlbG9wbWVudC5cbiAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgLy8gTk9URTogbmFtZUNvbnN0cmFpbnRzIHJlcXVpcmUgb3VyIGZvcmtlZCBub2RlLWZvcmdlIChcIm5vZGUtZm9yZ2VcIjogXCJodHRwczovL2dpdGh1Yi5jb20vc2xpZnRpc3QvZm9yZ2UjZTYxODE4MWI0NjliMDdiZGM3MGI5NjhiMDM5MWJlYjhlZjVmZWNkNlwiKS4gQ2hyb21lIGlnbm9yZXMgdGhlbSAoaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9MTA3MjA4MyksIGJ1dCBvdXIgb3duIHZhbGlkYXRpb24gKHZhbGlkYXRlQ0FDZXJ0L3ZhbGlkYXRlQ2VydGlmaWNhdGUpIGVuZm9yY2VzIHRoZW0uXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbmFtZTogXCJuYW1lQ29uc3RyYWludHNcIixcbiAgICAgICAgICAgICAgICBwZXJtaXR0ZWRTdWJ0cmVlczogW1xuICAgICAgICAgICAgICAgICAgICB7IHR5cGU6IDIsIHZhbHVlOiBmb3JnZS51dGlsLmVuY29kZVV0ZjgoZG9tYWluKSB9LFxuICAgICAgICAgICAgICAgICAgICB7IHR5cGU6IDIsIHZhbHVlOiBmb3JnZS51dGlsLmVuY29kZVV0ZjgobG9jYWxIb3N0RG9tYWluKSB9LFxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgICBjZXJ0T2JqLnNldEV4dGVuc2lvbnMoZXh0ZW5zaW9ucyk7XG5cblxuICAgICAgICBtZWFzdXJlQmxvY2soZnVuY3Rpb24gc2lnbigpIHtcbiAgICAgICAgICAgIGlmIChpc3N1ZXIgPT09IFwic2VsZlwiKSB7XG4gICAgICAgICAgICAgICAgY2VydE9iai5zaWduKGtleVBhaXIucHJpdmF0ZUtleSBhcyBhbnkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjZXJ0T2JqLnNpZ24oZm9yZ2UuZWQyNTUxOS5wcml2YXRlS2V5RnJvbVBlbShpc3N1ZXIua2V5LnRvU3RyaW5nKCkpIGFzIGFueSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBtZWFzdXJlQmxvY2soZnVuY3Rpb24gdG9QZW1zKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkb21haW4sXG4gICAgICAgICAgICAgICAgY2VydDogQnVmZmVyLmZyb20oZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9QZW0oY2VydE9iaikpLFxuICAgICAgICAgICAgICAgIGtleTogQnVmZmVyLmZyb20ocHJpdmF0ZUtleVRvUGVtKGtleVBhaXIucHJpdmF0ZUtleSkpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG59XG5leHBvcnQgZnVuY3Rpb24gcHJpdmF0ZUtleVRvUGVtKGtleTogZm9yZ2UuRWQyNTUxOVByaXZhdGVLZXkpIHtcbiAgICByZXR1cm4gZm9yZ2UuZWQyNTUxOS5wcml2YXRlS2V5VG9QZW0oa2V5KTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUNlcnQoUEVNb3JERVI6IHN0cmluZyB8IEJ1ZmZlcikge1xuICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tUGVtKG5vcm1hbGl6ZUNlcnRUb1BFTShQRU1vckRFUikpO1xufVxuXG5mdW5jdGlvbiBnZXRFRDI1NTE5UHVibGljS2V5KGNlcnRQYXJzZWQ6IGZvcmdlLnBraS5DZXJ0aWZpY2F0ZSk6IGZvcmdlLkVkMjU1MTlQdWJsaWNLZXkge1xuICAgIGxldCBwdWJsaWNLZXkgPSBjZXJ0UGFyc2VkLnB1YmxpY0tleTtcbiAgICBpZiAoIShcInB1YmxpY0tleUJ5dGVzXCIgaW4gcHVibGljS2V5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE9ubHkgRUQyNTUxOSBjZXJ0aWZpY2F0ZXMgYXJlIHN1cHBvcnRlZCwgdGhlIGNlcnRpZmljYXRlIHB1YmxpYyBrZXkgaXMgbm90IEVEMjU1MTkgKHN1YmplY3Q6ICR7Y2VydFBhcnNlZC5zdWJqZWN0LmdldEZpZWxkKFwiQ05cIik/LnZhbHVlfSlgKTtcbiAgICB9XG4gICAgcmV0dXJuIHB1YmxpY0tleSBhcyB1bmtub3duIGFzIGZvcmdlLkVkMjU1MTlQdWJsaWNLZXk7XG59XG5cbi8vIEdldHMgYSB1bmlxdWUgdmFsdWUgdG8gcmVwcmVzZW50IHRoZSBwdWJsaWMga2V5XG5leHBvcnQgZnVuY3Rpb24gZ2V0UHVibGljSWRlbnRpZmllcihQRU1vckRFUjogc3RyaW5nIHwgQnVmZmVyKTogQnVmZmVyIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oZ2V0RUQyNTUxOVB1YmxpY0tleShwYXJzZUNlcnQoUEVNb3JERVIpKS5wdWJsaWNLZXlCeXRlcyk7XG59XG5cbmV4cG9ydCBjb25zdCBzaWduID0gbWVhc3VyZVdyYXAoZnVuY3Rpb24gc2lnbihrZXlQYWlyOiB7IGtleTogc3RyaW5nIHwgQnVmZmVyIH0sIGRhdGE6IHVua25vd24pOiBzdHJpbmcge1xuICAgIGxldCBkYXRhU3RyID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG4gICAgbGV0IHByaXZhdGVLZXkgPSBmb3JnZS5lZDI1NTE5LnByaXZhdGVLZXlGcm9tUGVtKGtleVBhaXIua2V5LnRvU3RyaW5nKCkpO1xuICAgIHJldHVybiBwcml2YXRlS2V5LnNpZ24oZGF0YVN0cik7XG59KTtcblxuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeShjZXJ0OiBzdHJpbmcsIHNpZ25hdHVyZTogc3RyaW5nLCBkYXRhOiB1bmtub3duKSB7XG4gICAgbGV0IGNlcnRPYmogPSBwYXJzZUNlcnQoY2VydCk7XG4gICAgbGV0IHB1YmxpY0tleSA9IGdldEVEMjU1MTlQdWJsaWNLZXkoY2VydE9iaik7XG4gICAgbGV0IGRhdGFTdHIgPSBKU09OLnN0cmluZ2lmeShkYXRhKTtcbiAgICBpZiAoIXB1YmxpY0tleS52ZXJpZnkoZGF0YVN0ciwgc2lnbmF0dXJlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFNpZ25hdHVyZSB2ZXJpZmljYXRpb24gZmFpbGVkLiBTaWduYXR1cmU6ICR7SlNPTi5zdHJpbmdpZnkoc2lnbmF0dXJlKX0gfCBEYXRhOiAke2VsbGlwc2l6ZShkYXRhU3RyLCAxMDI0KX1gKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZUNlcnRUb1BFTShQRU1vckRFUjogc3RyaW5nIHwgQnVmZmVyKTogc3RyaW5nIHtcbiAgICBpZiAoUEVNb3JERVIudG9TdHJpbmcoKS5zdGFydHNXaXRoKFwiLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tXCIpKSB7XG4gICAgICAgIHJldHVybiBQRU1vckRFUi50b1N0cmluZygpO1xuICAgIH1cbiAgICBQRU1vckRFUiA9IFBFTW9yREVSLnRvU3RyaW5nKFwiYmFzZTY0XCIpO1xuICAgIHJldHVybiBcIi0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLVxcblwiICsgUEVNb3JERVIgKyBcIlxcbi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS1cIjtcbn1cblxuLy8gQmFzZTMyIChSRkMgNDY0OCwgbG93ZXJjYXNlLCB1bnBhZGRlZCksIGFzIGRvbWFpbiBuYW1lcyBhcmUgY2FzZS1pbnNlbnNpdGl2ZSwgd2hpY2ggcnVsZXMgb3V0IGJhc2U2NC9oZXgtd2l0aC1jYXNlXG5jb25zdCBiYXNlMzJBbHBoYWJldCA9IFwiYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoyMzQ1NjdcIjtcbmZ1bmN0aW9uIGVuY29kZUJhc2UzMihieXRlczogQnVmZmVyKTogc3RyaW5nIHtcbiAgICBsZXQgcmVzdWx0ID0gXCJcIjtcbiAgICBsZXQgYml0Q291bnQgPSAwO1xuICAgIGxldCB2YWx1ZSA9IDA7XG4gICAgZm9yIChsZXQgYnl0ZSBvZiBieXRlcykge1xuICAgICAgICB2YWx1ZSA9ICh2YWx1ZSA8PCA4KSB8IGJ5dGU7XG4gICAgICAgIGJpdENvdW50ICs9IDg7XG4gICAgICAgIHdoaWxlIChiaXRDb3VudCA+PSA1KSB7XG4gICAgICAgICAgICByZXN1bHQgKz0gYmFzZTMyQWxwaGFiZXRbKHZhbHVlID4+PiAoYml0Q291bnQgLSA1KSkgJiAzMV07XG4gICAgICAgICAgICBiaXRDb3VudCAtPSA1O1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChiaXRDb3VudCA+IDApIHtcbiAgICAgICAgcmVzdWx0ICs9IGJhc2UzMkFscGhhYmV0Wyh2YWx1ZSA8PCAoNSAtIGJpdENvdW50KSkgJiAzMV07XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIGdldERvbWFpblBhcnRGcm9tUHVibGljS2V5KHB1YmxpY0tleTogeyBwdWJsaWNLZXlCeXRlczogQnVmZmVyIH0gfCBCdWZmZXIpIHtcbiAgICBsZXQgYnl0ZXM6IEJ1ZmZlcjtcbiAgICBpZiAoXCJwdWJsaWNLZXlCeXRlc1wiIGluIHB1YmxpY0tleSkge1xuICAgICAgICBieXRlcyA9IHB1YmxpY0tleS5wdWJsaWNLZXlCeXRlcztcbiAgICB9IGVsc2Uge1xuICAgICAgICBieXRlcyA9IHB1YmxpY0tleTtcbiAgICB9XG4gICAgcmV0dXJuIFwiYlwiICsgZW5jb2RlQmFzZTMyKEJ1ZmZlci5mcm9tKHNoYTI2NS5zaGEyNTYuYXJyYXkoQnVmZmVyLmZyb20oYnl0ZXMpKSkpLnNsaWNlKDAsIDIwKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ0FDZXJ0KGRvbWFpbjogc3RyaW5nLCBjZXJ0OiBzdHJpbmcgfCBCdWZmZXIpIHtcbiAgICBsZXQgY2VydFBhcnNlZCA9IHBhcnNlQ2VydChjZXJ0KTtcblxuICAgIGxldCBzdWJqZWN0ID0gY2VydFBhcnNlZC5zdWJqZWN0LmdldEZpZWxkKFwiQ05cIikudmFsdWUgYXMgc3RyaW5nO1xuICAgIGxldCBsb2NhbGhvc3REb21haW4gPSBcIjEyNy0wLTAtMS5cIiArIHN1YmplY3Quc3BsaXQoXCIuXCIpLnNsaWNlKC0yKS5qb2luKFwiLlwiKTtcblxuICAgIGxldCBkb21haW5QYXJ0cyA9IHN1YmplY3Quc3BsaXQoXCIuXCIpLnJldmVyc2UoKTtcblxuICAgIGxldCByb290RG9tYWluUGFyc2VkID0gW2RvbWFpblBhcnRzLnNoaWZ0KCksIGRvbWFpblBhcnRzLnNoaWZ0KCldLnJldmVyc2UoKS5qb2luKFwiLlwiKTtcbiAgICBpZiAocm9vdERvbWFpblBhcnNlZCAhPT0gZG9tYWluKSB7XG4gICAgICAgIC8vIFRoaXMgaXMgaW1wb3J0YW50LCBhcyBvdXIgdHJ1c3Qgc3RvcmUgY29udGFpbnMgbW9yZSB0aGVuIGp1c3QgT1VSIGNlcnRpZmljYXRlcywgc28gaWYgd2UgYWxsb3cgYW55IGRvbWFpbnMgdGhlbiByZWFsIGRvbWFpbnMgY2FuIGltcGVyc29uYXRlIGFueW9uZSEgSXQgaGFzIHRvIGJlIE9VUiBkb21haW4gdG8gYmUgdHJ1c3RlZCFcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDZXJ0aWZpY2F0ZSByb290IGRvbWFpbiBzaG91bGQgYmUgJHtkb21haW59LCBidXQgaXMgJHtyb290RG9tYWluUGFyc2VkfWApO1xuICAgIH1cbiAgICAvLyBUT0RPOiBNYXliZSBqdXN0IHNraXAgaWYgaXQgaXNuJ3QgYSBoYXNoIHN0cmluZz9cbiAgICBpZiAoZG9tYWluUGFydHNbMF0gPT09IFwibm9wcm94eVwiKSB7XG4gICAgICAgIGRvbWFpblBhcnRzLnNoaWZ0KCk7XG4gICAgfVxuXG4gICAgbGV0IGNlcnRFeHBlY3RlZFB1YmxpY0tleVBhcnQgPSAoZG9tYWluUGFydHMuc2hpZnQoKSB8fCBcIlwiKS5zcGxpdChcIi1cIikuc2xpY2UoLTEpWzBdO1xuICAgIGxldCBjZXJ0QWN0dWFsUHVibGljS2V5UGFydCA9IGdldERvbWFpblBhcnRGcm9tUHVibGljS2V5KGdldEVEMjU1MTlQdWJsaWNLZXkoY2VydFBhcnNlZCkpO1xuICAgIGlmIChjZXJ0RXhwZWN0ZWRQdWJsaWNLZXlQYXJ0ICE9PSBjZXJ0QWN0dWFsUHVibGljS2V5UGFydCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENlcnRpZmljYXRlIHB1YmxpYyBrZXkgaW4gdGhlIHVybCBpcyAke2NlcnRFeHBlY3RlZFB1YmxpY0tleVBhcnR9LCBidXQgaW4gdGhlIGNlcnQgaXMgJHtjZXJ0QWN0dWFsUHVibGljS2V5UGFydH1gKTtcbiAgICB9XG5cbiAgICAvLyBBTFNPLCByZXF1aXJlIG5hbWUgY29uc3RyYWludHMgdG8gYmUgcHJlc2VudCwgYW5kIHRvIHJlc3RyaWN0IHRvIHRoZSBcIkNOXCJcbiAgICBsZXQgbmFtZUNvbnN0cmFpbnRzID0gY2VydFBhcnNlZC5nZXRFeHRlbnNpb24oXCJuYW1lQ29uc3RyYWludHNcIikgYXMgYW55O1xuICAgIGlmICghbmFtZUNvbnN0cmFpbnRzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgbXVzdCBoYXZlIG5hbWVDb25zdHJhaW50c2ApO1xuICAgIH1cbiAgICBsZXQgc3VidHJlZXMgPSBuYW1lQ29uc3RyYWludHMucGVybWl0dGVkU3VidHJlZXM7XG4gICAgaWYgKCFzdWJ0cmVlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENlcnRpZmljYXRlIG11c3QgaGF2ZSBuYW1lQ29uc3RyYWludHMucGVybWl0dGVkU3VidHJlZXNgKTtcbiAgICB9XG4gICAgbGV0IHN1YnRyZWVWYWx1ZXMgPSBzdWJ0cmVlcy5tYXAoKHg6IGFueSkgPT4geC52YWx1ZSk7XG4gICAgLy8gSWdub3JlIGxvY2FsaG9zdERvbWFpbiwgYXMgaXQgY2FuIGFsd2F5cyBzYWZlbHkgYmUgYWxsb3dlZCAodGhlIHNhbWUgbWFjaGluZSBpcyBhbHdheXMgYWxsb3dlZCkuXG4gICAgc3VidHJlZVZhbHVlcyA9IHN1YnRyZWVWYWx1ZXMuZmlsdGVyKCh4OiBzdHJpbmcpID0+IHggIT09IGxvY2FsaG9zdERvbWFpbik7XG4gICAgaWYgKHN1YnRyZWVWYWx1ZXMubGVuZ3RoICE9PSAxIHx8IHN1YnRyZWVWYWx1ZXNbMF0gIT09IHN1YmplY3QpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDZXJ0aWZpY2F0ZSBtdXN0IGhhdmUgYSBzaW5nbGUgY29uc3RyYWluZWQgZG9tYWluIChoYWQgJHtKU09OLnN0cmluZ2lmeShzdWJ0cmVlVmFsdWVzKX0pYCk7XG4gICAgfVxuXG4gICAgdmFsaWRhdGVBbHROYW1lcyhjZXJ0UGFyc2VkLCBzdWJqZWN0KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ2VydGlmaWNhdGUoZG9tYWluOiBzdHJpbmcsIGNlcnQ6IEJ1ZmZlciB8IHN0cmluZywgaXNzdWVyQ2VydDogQnVmZmVyIHwgc3RyaW5nKSB7XG4gICAgdmFsaWRhdGVDQUNlcnQoZG9tYWluLCBpc3N1ZXJDZXJ0KTtcblxuICAgIGxldCBjZXJ0UGFyc2VkID0gcGFyc2VDZXJ0KGNlcnQpO1xuICAgIGxldCBzdWJqZWN0ID0gY2VydFBhcnNlZC5zdWJqZWN0LmdldEZpZWxkKFwiQ05cIikudmFsdWUgYXMgc3RyaW5nO1xuICAgIGxldCBsb2NhbGhvc3REb21haW4gPSBcIjEyNy0wLTAtMS5cIiArIHN1YmplY3Quc3BsaXQoXCIuXCIpLnNsaWNlKC0yKS5qb2luKFwiLlwiKTtcblxuICAgIGxldCBkb21haW5QYXJ0cyA9IHN1YmplY3Quc3BsaXQoXCIuXCIpLnJldmVyc2UoKTtcblxuICAgIGxldCByb290RG9tYWluUGFyc2VkID0gW2RvbWFpblBhcnRzLnNoaWZ0KCksIGRvbWFpblBhcnRzLnNoaWZ0KCldLnJldmVyc2UoKS5qb2luKFwiLlwiKTtcbiAgICBpZiAocm9vdERvbWFpblBhcnNlZCAhPT0gZG9tYWluKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgcm9vdCBkb21haW4gc2hvdWxkIGJlICR7ZG9tYWlufSwgYnV0IGlzICR7cm9vdERvbWFpblBhcnNlZH1gKTtcbiAgICB9XG4gICAgLy8gVE9ETzogTWF5YmUganVzdCBza2lwIGlmIGl0IGlzbid0IGEgaGFzaCBzdHJpbmc/XG4gICAgaWYgKGRvbWFpblBhcnRzWzBdID09PSBcIm5vcHJveHlcIikge1xuICAgICAgICBkb21haW5QYXJ0cy5zaGlmdCgpO1xuICAgIH1cblxuICAgIGxldCBpc3N1ZXJDZXJ0UGFyc2VkID0gcGFyc2VDZXJ0KGlzc3VlckNlcnQpO1xuXG4gICAgbGV0IGlzc3VlckV4cGVjdGVkUHVibGljS2V5UGFydCA9IGRvbWFpblBhcnRzLnNoaWZ0KCkgfHwgXCJcIjtcbiAgICBsZXQgaXNzdWVyQWN0dWFsUHVibGljS2V5UGFydCA9IGdldERvbWFpblBhcnRGcm9tUHVibGljS2V5KGdldEVEMjU1MTlQdWJsaWNLZXkoaXNzdWVyQ2VydFBhcnNlZCkpO1xuICAgIGlmIChpc3N1ZXJFeHBlY3RlZFB1YmxpY0tleVBhcnQgIT09IGlzc3VlckFjdHVhbFB1YmxpY0tleVBhcnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJc3N1ZXIgcHVibGljIGtleSBpbiB0aGUgdXJsIGlzICR7aXNzdWVyRXhwZWN0ZWRQdWJsaWNLZXlQYXJ0fSwgYnV0IGluIHRoZSBjZXJ0IGlzICR7aXNzdWVyQWN0dWFsUHVibGljS2V5UGFydH1gKTtcbiAgICB9XG5cbiAgICAvLyBUYWtlIHRoZSBsYXN0IHBhcnRcbiAgICBsZXQgY2VydEV4cGVjdGVkUHVibGljS2V5UGFydCA9IGRvbWFpblBhcnRzLnNoaWZ0KCkgfHwgXCJcIjtcbiAgICBsZXQgY2VydEFjdHVhbFB1YmxpY0tleVBhcnQgPSBnZXREb21haW5QYXJ0RnJvbVB1YmxpY0tleShnZXRFRDI1NTE5UHVibGljS2V5KGNlcnRQYXJzZWQpKTtcbiAgICBpZiAoY2VydEV4cGVjdGVkUHVibGljS2V5UGFydCAhPT0gY2VydEFjdHVhbFB1YmxpY0tleVBhcnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDZXJ0aWZpY2F0ZSBwdWJsaWMga2V5IGluIHRoZSB1cmwgaXMgJHtjZXJ0RXhwZWN0ZWRQdWJsaWNLZXlQYXJ0fSwgYnV0IGluIHRoZSBjZXJ0IGlzICR7Y2VydEFjdHVhbFB1YmxpY0tleVBhcnR9YCk7XG4gICAgfVxuXG5cbiAgICBsZXQgbmFtZUNvbnN0cmFpbnRzID0gaXNzdWVyQ2VydFBhcnNlZC5nZXRFeHRlbnNpb24oXCJuYW1lQ29uc3RyYWludHNcIikgYXMgYW55O1xuICAgIGlmICghbmFtZUNvbnN0cmFpbnRzKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ0EgbXVzdCBoYXZlIG5hbWVDb25zdHJhaW50c2ApO1xuICAgIH1cbiAgICBsZXQgc3VidHJlZXMgPSBuYW1lQ29uc3RyYWludHMucGVybWl0dGVkU3VidHJlZXM7XG4gICAgaWYgKCFzdWJ0cmVlcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENBIG11c3QgaGF2ZSBuYW1lQ29uc3RyYWludHMucGVybWl0dGVkU3VidHJlZXNgKTtcbiAgICB9XG4gICAgbGV0IHN1YnRyZWVWYWx1ZXMgPSBzdWJ0cmVlcy5tYXAoKHg6IGFueSkgPT4geC52YWx1ZSk7XG4gICAgLy8gSWdub3JlIGxvY2FsaG9zdERvbWFpbiwgYXMgaXQgY2FuIGFsd2F5cyBzYWZlbHkgYmUgYWxsb3dlZCAodGhlIHNhbWUgbWFjaGluZSBpcyBhbHdheXMgYWxsb3dlZCkuXG4gICAgc3VidHJlZVZhbHVlcyA9IHN1YnRyZWVWYWx1ZXMuZmlsdGVyKCh4OiBzdHJpbmcpID0+IHggIT09IGxvY2FsaG9zdERvbWFpbik7XG4gICAgaWYgKHN1YnRyZWVWYWx1ZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ0EgbXVzdCBoYXZlIGEgc2luZ2xlIGNvbnN0cmFpbmVkIGRvbWFpbiAoaGFkICR7SlNPTi5zdHJpbmdpZnkoc3VidHJlZVZhbHVlcyl9KWApO1xuICAgIH1cblxuICAgIGxldCBzdWJ0cmVlID0gc3VidHJlZVZhbHVlc1swXTtcbiAgICBpZiAoc3VidHJlZSAhPT0gc3ViamVjdCAmJiAhc3ViamVjdC5lbmRzV2l0aChcIi5cIiArIHN1YnRyZWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2VydGlmaWNhdGUgbXVzdCBiZSBhIHN1YnRyZWUgb2YgdGhlIENBIChDQTogJHtzdWJ0cmVlfSwgY2VydDogJHtzdWJqZWN0fSlgKTtcbiAgICB9XG5cbiAgICB2YWxpZGF0ZUFsdE5hbWVzKGNlcnRQYXJzZWQsIHN1YmplY3QpO1xuXG4gICAgLy8gVmVyaWZ5IGlzc3VlciBBQ1RVQUxMWSBzaWduZWQgY2VydFBhcnNlZFxuICAgIGlmICghaXNzdWVyQ2VydFBhcnNlZC52ZXJpZnkoY2VydFBhcnNlZCkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJc3N1ZXIgZGlkIG5vdCBzaWduIGNlcnRpZmljYXRlYCk7XG4gICAgfVxufVxuXG4vLyBSZXF1aXJlIGFsdCBuYW1lcyB0byBiZSBlaXRoZXIgZXF1YWwgdG8gXCJDTlwiLCBvciBhIHN1YnRyZWUgb2YgXCJDTlwiXG5mdW5jdGlvbiB2YWxpZGF0ZUFsdE5hbWVzKGNlcnRQYXJzZWQ6IGZvcmdlLnBraS5DZXJ0aWZpY2F0ZSwgc3ViamVjdDogc3RyaW5nKSB7XG4gICAgbGV0IGxvY2FsaG9zdERvbWFpbiA9IFwiMTI3LTAtMC0xLlwiICsgc3ViamVjdC5zcGxpdChcIi5cIikuc2xpY2UoLTIpLmpvaW4oXCIuXCIpO1xuXG4gICAgbGV0IGFsdE5hbWVzT2JqID0gY2VydFBhcnNlZC5nZXRFeHRlbnNpb24oXCJzdWJqZWN0QWx0TmFtZVwiKSBhcyBhbnk7XG4gICAgbGV0IGFsdE5hbWVzID0gYWx0TmFtZXNPYmo/LmFsdE5hbWVzLm1hcCgoeDogYW55KSA9PiB4LnZhbHVlKTtcbiAgICAvLyBBbGxvdyBsb2NhbGhvc3REb21haW4sIGFzIGl0IGNhbiBhbHdheXMgc2FmZWx5IGJlIGFsbG93ZWRcbiAgICBhbHROYW1lcyA9IGFsdE5hbWVzLmZpbHRlcigoeDogc3RyaW5nKSA9PiB4ICE9PSBsb2NhbGhvc3REb21haW4pO1xuICAgIGlmIChcbiAgICAgICAgYWx0TmFtZXMuc29tZSgoeDogc3RyaW5nKSA9PlxuICAgICAgICAgICAgIShcbiAgICAgICAgICAgICAgICB4ID09PSBzdWJqZWN0XG4gICAgICAgICAgICAgICAgfHwgeC5lbmRzV2l0aChcIi5cIiArIHN1YmplY3QpXG4gICAgICAgICAgICAgICAgLy8gTk9URTogV2UgZG9uJ3QgYWxsb3cgMTI3LjAuMC4xICh8fCB4ID09PSBCdWZmZXIuZnJvbShbMTI3LCAwLCAwLCAxXSkudG9TdHJpbmcoKSksIGJlY2F1c2UgaXQgaXMgc28gZWFzeSB0byBwdWJsaXNoIGEgMTI3LjAuMC4xIEEgcmVjb3JkLCBhbmQgZXZlbiB0byBnZW5lcmF0ZSBhIHJlYWwgY2VydCwgc28gd2Ugc2hvdWxkIGp1c3QgZG8gdGhhdCwgYW5kIGtlZXAgaXQgc2VjdXJlLiBJZiB3ZSBuZWVkIHRoaXMgZm9yIGRldmVsb3BtZW50IHdlIGNhbiBwdXQgaXQgYmVoaW5kIGEgZmxhZywgc28gbm9uLWRldmVsb3BtZW50IGluc3RhbmNlcyBhcmUgc3RpbGwgc2VjdXJlLlxuICAgICAgICAgICAgKVxuICAgICAgICApXG4gICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhbHQgbmFtZXMuIE11c3QgYmUgc3VidHJlZXMgb2YgdGhlIHN1YmplY3QgKENOKSAke0pTT04uc3RyaW5naWZ5KHN1YmplY3QpfSwgd2FzICR7SlNPTi5zdHJpbmdpZnkoYWx0TmFtZXMpfWApO1xuICAgIH1cbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlyKCkge1xuICAgIHJldHVybiBtZWFzdXJlQmxvY2soZnVuY3Rpb24gZ2VuZXJhdGVLZXlQYWlyKCkge1xuICAgICAgICAvLyBOT1RFOiBXZSB1c2UgRUQyNTUxOSBiZWNhdXNlIGl0IGNhbiBnZW5lcmF0ZSBrZXlzIGFib3V0IDEwWCBmYXN0ZXIgdGhhbiBSU0EgKHdoaWNoIGlzIHN0aWxsIHNsb3csIH42bXMgb24gbXkgbWFjaGluZSwgc28gd2UgREVGSU5JVEVMWSBkb24ndCB3YW50IGl0IHRvIGJlIDEwWCBzbG93ZXIhKSAtIGh0dHBzOi8vc2VjdXJpdHkuc3RhY2tleGNoYW5nZS5jb20vYS8yMzY5NDMvMjgyMzY3XG4gICAgICAgIHJldHVybiBmb3JnZS5lZDI1NTE5LmdlbmVyYXRlS2V5UGFpcigpO1xuICAgIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVUZXN0Q0EoZG9tYWluOiBzdHJpbmcpIHtcbiAgICBjb25zdCBrZXlQYWlyID0gZ2VuZXJhdGVLZXlQYWlyKCk7XG4gICAgbGV0IGNhUHVibGljS2V5UGFydCA9IGdldERvbWFpblBhcnRGcm9tUHVibGljS2V5KGtleVBhaXIucHVibGljS2V5KTtcbiAgICBsZXQgZnVsbERvbWFpbiA9IGAke2NhUHVibGljS2V5UGFydH0uJHtkb21haW59YDtcbiAgICByZXR1cm4gY3JlYXRlWDUwOSh7IGRvbWFpbjogZnVsbERvbWFpbiwgaXNzdWVyOiBcInNlbGZcIiwga2V5UGFpciwgbGlmZVNwYW46IHRpbWVJbkRheSAqIDM2NSAqIDIwIH0pO1xufVxuXG5sZXQgaWRlbnRpdHlDQSA9IGNhY2hlKChkb21haW46IHN0cmluZykgPT4gbGF6eSgoKTogWDUwOUtleVBhaXIgPT4ge1xuICAgIGxldCBpZGVudGl0eUNBQ2FjaGVkID0gZ2V0SWRlbnRpdHlTdG9yZShkb21haW4pO1xuICAgIGxldCBjYUNhY2hlZCA9IGlkZW50aXR5Q0FDYWNoZWQuZ2V0KCk7XG4gICAgaWYgKCFjYUNhY2hlZCkge1xuICAgICAgICBjb25zb2xlLmxvZyhgR2VuZXJhdGluZyBuZXcgaWRlbnRpdHkgQ0FgKTtcbiAgICAgICAgY29uc3Qga2V5UGFpciA9IGdlbmVyYXRlS2V5UGFpcigpO1xuICAgICAgICBsZXQgY2FQdWJsaWNLZXlQYXJ0ID0gZ2V0RG9tYWluUGFydEZyb21QdWJsaWNLZXkoa2V5UGFpci5wdWJsaWNLZXkpO1xuICAgICAgICBsZXQgZnVsbERvbWFpbiA9IGAke2NhUHVibGljS2V5UGFydH0uJHtkb21haW59YDtcblxuICAgICAgICBsZXQgdmFsdWUgPSBjcmVhdGVYNTA5KHsgZG9tYWluOiBmdWxsRG9tYWluLCBpc3N1ZXI6IFwic2VsZlwiLCBrZXlQYWlyLCBsaWZlU3BhbjogdGltZUluRGF5ICogMzY1ICogMjAgfSk7XG5cbiAgICAgICAgY2FDYWNoZWQgPSB7XG4gICAgICAgICAgICBkb21haW46IHZhbHVlLmRvbWFpbixcbiAgICAgICAgICAgIGNlcnRCNjQ6IHZhbHVlLmNlcnQudG9TdHJpbmcoXCJiYXNlNjRcIiksXG4gICAgICAgICAgICBrZXlCNjQ6IHZhbHVlLmtleS50b1N0cmluZyhcImJhc2U2NFwiKSxcbiAgICAgICAgfTtcbiAgICAgICAgaWRlbnRpdHlDQUNhY2hlZC5zZXQoY2FDYWNoZWQpO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0ID0ge1xuICAgICAgICBkb21haW46IGNhQ2FjaGVkLmRvbWFpbixcbiAgICAgICAgY2VydDogQnVmZmVyLmZyb20oY2FDYWNoZWQuY2VydEI2NCwgXCJiYXNlNjRcIiksXG4gICAgICAgIGtleTogQnVmZmVyLmZyb20oY2FDYWNoZWQua2V5QjY0LCBcImJhc2U2NFwiKSxcbiAgICB9O1xuICAgIHRydXN0Q2VydGlmaWNhdGUocmVzdWx0LmNlcnQudG9TdHJpbmcoKSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbn0pKTtcblxuLy8gSU1QT1JUQU5UISBXZSBkbyBub3QgZW1iZWQgYW55IGRlYnVnIGluZm8gaW4gdGhpcyBkb21haW4uIElmIHdlIGRpZCwgaXQgd291bGQgYmUgdXNlZnVsLCBidXQuLi4gcG90ZW50YWxseSBhIHNlY3VyaXR5IHZ1bG5lcmFiaWxpdHksIGFzIGlmIHRoZSBkZWJ1ZyBpbmZvIChzdWNoIGFzIGEgcHJlZml4KSBpcyB1c2VkIHRvIGlkZW50aWZ5IHdoYXQgYSBjZXJ0aWZpY2F0ZSBpcyBmb3IsIGl0IHdvdWxkIGJlIGVhc3kgZm9yIGFuIGF0dGFjayB0byBmb3JnZSB0aGlzIChhcyB0aGUgZGVidWcgaW5mbyB3b24ndCBiZSBzZWN1cmVkKS4gU28gaXQgaXMgbXVjaCBiZXR0ZXIgdG8ga2VlcCB0aGUgY2VydGlmaWNhdGUgb3BhcXVlLCBhbmQgdGhlbiByZXF1aXJlIGFueSBtZXRhZGF0YSB0byBiZSBhY3R1YWxseSB2ZXR0ZWQgKGFuZCBob3BlZnVsbHkgc3RvcmVkIGluIGEgVUksIHNob3dpbmcgSVAsIHRpbWUsIGV0YykuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQ2VydEZyb21DQShjb25maWc6IHtcbiAgICBDQUtleVBhaXI6IFg1MDlLZXlQYWlyO1xufSk6IFg1MDlLZXlQYWlyIHtcbiAgICByZXR1cm4gbWVhc3VyZUJsb2NrKGZ1bmN0aW9uIGNyZWF0ZUNlcnRGcm9tQ0EoKSB7XG4gICAgICAgIGxldCB7IENBS2V5UGFpciB9ID0gY29uZmlnO1xuICAgICAgICBjb25zdCBrZXlQYWlyID0gZ2VuZXJhdGVLZXlQYWlyKCk7XG4gICAgICAgIGxldCBkb21haW5LZXlQYXJ0ID0gZ2V0RG9tYWluUGFydEZyb21QdWJsaWNLZXkoa2V5UGFpci5wdWJsaWNLZXkpO1xuICAgICAgICBsZXQgZnVsbERvbWFpbiA9IGAke2RvbWFpbktleVBhcnR9LiR7Y29uZmlnLkNBS2V5UGFpci5kb21haW59YDtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZVg1MDkoe1xuICAgICAgICAgICAgZG9tYWluOiBmdWxsRG9tYWluLFxuICAgICAgICAgICAgaXNzdWVyOiBDQUtleVBhaXIsXG4gICAgICAgICAgICBrZXlQYWlyLFxuICAgICAgICAgICAgbGlmZVNwYW46IHRpbWVJbkRheSAqIDM2NSAqIDEwLFxuICAgICAgICB9KTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1hY2hpbmVJZChkb21haW5OYW1lT3JOb2RlSWQ6IHN0cmluZywgZG9tYWluOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gZGVjb2RlTm9kZUlkQXNzZXJ0KGRvbWFpbk5hbWVPck5vZGVJZCwgZG9tYWluLCBcImFsbG93TWlzc2luZ1RocmVhZElkXCIpLm1hY2hpbmVJZDtcbn1cblxuZXhwb3J0IHR5cGUgTm9kZUlkUGFydHMgPSB7XG4gICAgdGhyZWFkSWQ6IHN0cmluZztcbiAgICBtYWNoaW5lSWQ6IHN0cmluZztcbiAgICBkb21haW46IHN0cmluZztcbiAgICBwb3J0OiBudW1iZXI7XG59O1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZU5vZGVJZChub2RlSWQ6IHN0cmluZywgZG9tYWluOiBzdHJpbmcsIGFsbG93TWlzc2luZ1RocmVhZElkPzogXCJhbGxvd01pc3NpbmdUaHJlYWRJZFwiKTogTm9kZUlkUGFydHMgfCB1bmRlZmluZWQge1xuICAgIGxldCBsb2NhdGlvbk9iaiA9IGdldE5vZGVJZExvY2F0aW9uKG5vZGVJZCk7XG4gICAgaWYgKCFsb2NhdGlvbk9iaikge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBsZXQgcGFydHMgPSBsb2NhdGlvbk9iai5hZGRyZXNzLnNwbGl0KFwiLlwiKTtcbiAgICAvLyBOT1RFOiBXZSBoYXZlIHRvIG9ubHkgYWxsb3cgbG9jYWxob3N0IGRvbWFpbnMgb24gb3VyIG93biBkb21haW4sIGFzIHRoZSB1bmRlcmx5aW5nIGRvbWFpbiBnZXRzIHN0cmlwcGVkIHdoZW4gd2UncmUgbG9va2luZyBhdCB0aGUgbWFjaGluZUlkLiBTbyBpZiB3ZSBhbGxvd2VkIGxvY2FsaG9zdCBkb21haW5zIG9uIG90aGVyIGRvbWFpbnMsIGEgc2VydmVyIGNvdWxkIHRyaWNrIHVzIGludG8gY29ubmVjdGluZyB0byBpdCwgYW5kIHRoZW4gb25jZSB0aGUgY29ubmVjdGlvbiBpcyBlc3RhYmxpc2hlZCwgaXQgY291bGQgdGFsayBiYWNrIGFuZCB3ZSB3b3VsZCB0aGluayBpdCBoYXMgYSBsb2NhbGhvc3QgbWFjaGluZUlkLCB3aGljaCBpcyBpbXBsaWNpdGx5IHRydXN0ZWQsIHdoaWNoIHdvdWxkIHRoZW4gZ2l2ZSBpdCBhY2Nlc3MgdG8gZXZlcnl0aGluZy5cbiAgICBpZiAobG9jYXRpb25PYmouYWRkcmVzcyA9PT0gYDEyNy0wLTAtMS4ke2RvbWFpbn1gICYmIG5vZGVJZC5pbmNsdWRlcyhcIjpcIikpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRocmVhZElkOiBcIlwiLFxuICAgICAgICAgICAgbWFjaGluZUlkOiBwYXJ0cy5hdCgtMykgfHwgXCJcIixcbiAgICAgICAgICAgIGRvbWFpbjogcGFydHMuc2xpY2UoLTIpLmpvaW4oXCIuXCIpLFxuICAgICAgICAgICAgcG9ydDogbG9jYXRpb25PYmoucG9ydCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgbGV0IGlzVmFsaWQgPSBwYXJ0cy5sZW5ndGggPj0gNCB8fCBhbGxvd01pc3NpbmdUaHJlYWRJZCAmJiBwYXJ0cy5sZW5ndGggPT09IDM7XG4gICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHRocmVhZElkOiBwYXJ0cy5hdCgtNCkgfHwgXCJcIixcbiAgICAgICAgbWFjaGluZUlkOiBwYXJ0cy5hdCgtMykgfHwgXCJcIixcbiAgICAgICAgZG9tYWluOiBwYXJ0cy5zbGljZSgtMikuam9pbihcIi5cIikgfHwgXCJcIixcbiAgICAgICAgcG9ydDogbG9jYXRpb25PYmoucG9ydCxcbiAgICB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZU5vZGVJZEFzc2VydChub2RlSWQ6IHN0cmluZywgZG9tYWluOiBzdHJpbmcsIGFsbG93TWlzc2luZ1RocmVhZElkPzogXCJhbGxvd01pc3NpbmdUaHJlYWRJZFwiKTogTm9kZUlkUGFydHMge1xuICAgIGxldCByZXN1bHQgPSBkZWNvZGVOb2RlSWQobm9kZUlkLCBkb21haW4sIGFsbG93TWlzc2luZ1RocmVhZElkKTtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbm9kZUlkOiAke0pTT04uc3RyaW5naWZ5KG5vZGVJZCl9YCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlTm9kZUlkKHBhcnRzOiBOb2RlSWRQYXJ0cykge1xuICAgIHJldHVybiBgJHtwYXJ0cy50aHJlYWRJZH0uJHtwYXJ0cy5tYWNoaW5lSWR9LiR7cGFydHMuZG9tYWlufToke3BhcnRzLnBvcnR9YDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldElkZW50aXR5Q0FSYXcoZG9tYWluOiBzdHJpbmcsIGpzb246IHN0cmluZykge1xuICAgIGxldCBpZGVudGl0eUNBQ2FjaGVkID0gZ2V0SWRlbnRpdHlTdG9yZShkb21haW4pO1xuICAgIGxldCBvYmogPSBKU09OLnBhcnNlKGpzb24pIGFzIHtcbiAgICAgICAgZG9tYWluOiBzdHJpbmc7XG4gICAgICAgIGNlcnRCNjQ6IHN0cmluZztcbiAgICAgICAga2V5QjY0OiBzdHJpbmc7XG4gICAgfTtcbiAgICBsZXQgY2EgPSB7XG4gICAgICAgIGRvbWFpbjogb2JqLmRvbWFpbixcbiAgICAgICAgY2VydDogQnVmZmVyLmZyb20ob2JqLmNlcnRCNjQsIFwiYmFzZTY0XCIpLFxuICAgICAgICBrZXk6IEJ1ZmZlci5mcm9tKG9iai5rZXlCNjQsIFwiYmFzZTY0XCIpLFxuICAgIH07XG4gICAgdHJ1c3RDZXJ0aWZpY2F0ZShjYS5jZXJ0LnRvU3RyaW5nKCkpO1xuICAgIGlkZW50aXR5Q0EoZG9tYWluKS5zZXQoY2EpO1xuICAgIGdldFRocmVhZEtleUNlcnRCYXNlKGRvbWFpbikucmVzZXQoKTtcbiAgICBpZGVudGl0eUNBQ2FjaGVkLnNldChvYmopO1xuICAgIHJlc2V0QWxsTm9kZUNhbGxGYWN0b3JpZXMoKTtcbn1cblxuLy8gTk9URTogVGhlIGlkZW50aXR5IENBIGlzIGF2YWlsYWJsZSBzeW5jaHJvbm91c2x5IChzdG9yYWdlIGlzIGZzL2xvY2FsU3RvcmFnZSwgYm90aCBzeW5jaHJvbm91cyksIHNvIHRoaXMgb25seSBleGlzdHMgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdpdGggc3RhcnR1cCBjb2RlIHRoYXQgYXdhaXRzIGl0LlxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRJZGVudGl0eUNBKGRvbWFpbjogc3RyaW5nKSB7XG4gICAgaWRlbnRpdHlDQShkb21haW4pKCk7XG59XG5leHBvcnQgZnVuY3Rpb24gZ2V0SWRlbnRpdHlDQShkb21haW46IHN0cmluZyk6IFg1MDlLZXlQYWlyIHtcbiAgICByZXR1cm4gaWRlbnRpdHlDQShkb21haW4pKCk7XG59XG5cbi8vIFRPRE86IFJlcGxhY2UgdGhpcyB3aXRoIGEgZGF0YWJhc2UsIHNvIGl0IGlzIGVhc3kgZm9yIHVzIHRvIHRydXN0IENBcyBjcm9zcyBtYWNoaW5lLCBhbmQgZXZlbiBoYXZlIG11bHRpcGxlIHVzZXJzLCBldGMsIGV0Yy5cbmV4cG9ydCBmdW5jdGlvbiBnZXRJZGVudGl0eUNBUHJvbWlzZShkb21haW46IHN0cmluZyk6IFg1MDlLZXlQYWlyIHtcbiAgICByZXR1cm4gaWRlbnRpdHlDQShkb21haW4pKCk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE93bk1hY2hpbmVJZChkb21haW46IHN0cmluZykge1xuICAgIHJldHVybiBnZXRNYWNoaW5lSWQoZ2V0SWRlbnRpdHlDQShkb21haW4pLmRvbWFpbiwgZG9tYWluKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRPd25UaHJlYWRJZChkb21haW46IHN0cmluZykge1xuICAgIHJldHVybiBkZWNvZGVOb2RlSWRBc3NlcnQoZ2V0VGhyZWFkS2V5Q2VydChkb21haW4pLmRvbWFpbiwgZG9tYWluKS50aHJlYWRJZDtcbn1cblxuLyoqIFBhcnQgb2YgdGhlIG1hY2hpbmVJZCBjb21lcyBmcm9tIHRoZSBwdWJsaWNLZXksIHNvIHdlIGNhbiB1c2UgaXQgdG8gdmVyaWZ5ICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5TWFjaGluZUlkRm9yUHVibGljS2V5KGNvbmZpZzoge1xuICAgIG1hY2hpbmVJZDogc3RyaW5nO1xuICAgIHB1YmxpY0tleTogQnVmZmVyO1xufSk6IGJvb2xlYW4ge1xuICAgIGxldCB7IG1hY2hpbmVJZCwgcHVibGljS2V5IH0gPSBjb25maWc7XG4gICAgbGV0IGRvbWFpblBhcnQgPSBnZXREb21haW5QYXJ0RnJvbVB1YmxpY0tleShwdWJsaWNLZXkpO1xuICAgIC8vIG1hY2hpbmVJZCBpcyB0aGUgYmFyZSBrZXktaGFzaCBsYWJlbCwgYnV0IGFsc28gYWNjZXB0IGxlZ2FjeSBcImhhc2guZG9tYWluLnRsZFwiIGZvcm1zXG4gICAgcmV0dXJuIG1hY2hpbmVJZC5zcGxpdChcIi5cIilbMF0gPT09IGRvbWFpblBhcnQ7XG59XG5cbi8vIE5PVEU6IFdlIGRvbid0IGhhdmUgYSBjYWNoZSBwZXIgQ0EsIGFzLi4uIHRoZSBDQSBzaG91bGQgYmUgc2V0IGZpcnN0XG4vLyBUT0RPOiBNYXliZSB0aHJvdyBpZiB0aGV5IHRyeSB0byBjaGFuZ2UgdGhlIENBIGFmdGVyIHRoZXkgZ2VuZXJhdGUgYW55IGNlcnRpZmljYXRlcz9cbi8vIFRPRE86IFJlZ2VuZXJhdGUgY2VydGlmaWNhdGVzIGFmdGVyIGVub3VnaCB0aW1lIChhcyB0aHJlYWQgY2VydHMgc2hvdWxkIGJlIHJlbGF0aXZlbHkgc2hvcnQgbGl2ZWQsIHNvIGl0IGlzIHBsYXVzaWJsZSBmb3IgdGhlbSB0byBleHBpcmUpLiBXZSB3aWxsIGFsc28gbmVlZCB0byBwcm92aWRlIGEgY2FsbGJhY2sgc28gdGhhdCB1c2VycyBvZiB0aGUgY2VydCBjYW4gdXBkYXRlIHRoZSBjZXJ0IHRoZXkgYXJlIHVzaW5nIGFzIHdlbGwuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGhyZWFkS2V5Q2VydChkb21haW46IHN0cmluZykge1xuICAgIHJldHVybiBnZXRUaHJlYWRLZXlDZXJ0QmFzZShkb21haW4pKCk7XG59XG5jb25zdCBnZXRUaHJlYWRLZXlDZXJ0QmFzZSA9IGNhY2hlKChkb21haW46IHN0cmluZykgPT4gbGF6eSgoKSA9PiB7XG4gICAgbGV0IGNhID0gZ2V0SWRlbnRpdHlDQShkb21haW4pO1xuICAgIHJldHVybiBjcmVhdGVDZXJ0RnJvbUNBKHsgQ0FLZXlQYWlyOiBjYSB9KTtcbn0pKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE93bk5vZGVJZCgpOiBzdHJpbmcge1xuICAgIGxldCBub2RlSWQgPSBTb2NrZXRGdW5jdGlvbi5tb3VudGVkTm9kZUlkO1xuICAgIGlmICghbm9kZUlkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm9kZSBtdXN0IGJlIG1vdW50ZWQgYmVmb3JlIG5vZGVJZCBpcyBhY2Nlc3NlZGApO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZUlkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3duTm9kZUlkQWxsb3dVbmRlZmluZWQoKSB7XG4gICAgcmV0dXJuIFNvY2tldEZ1bmN0aW9uLm1vdW50ZWROb2RlSWQ7XG59Il19
466
+ /* _JS_SOURCE_HASH = "f2009b20f0a3249a21e08f4352d1914e34bdadc2ead4b2316e6320dd28538de0"; */