sliftutils 1.7.147 → 1.7.148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -9,6 +9,7 @@ from `.cursor/rules/*.mdc` so Claude reads them automatically.
9
9
  - Don't run shell commands when you need to create or move small code files. Use tool calls. Use tool calls to make files within folders — you don't need to make the folder, just make the file, the folder will be created automatically.
10
10
  - If you need to add a dependency, don't just edit `package.json`. Use `yarn add` so you get the latest version, unless the user specifies a version.
11
11
  - Use tool calls to read and write files and directories, as opposed to shell commands running `ls`, `dir`, etc.
12
+ - Almost never run shell commands. Prefer a `yarn` command — if one doesn't exist for what you need, write it: a reusable script (an entry point in `bin/`, wired up in `package.json`) that anyone can run again, rather than a one-off shell invocation that only existed in your terminal.
12
13
 
13
14
 
14
15
  ## Coding styles
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.7.147",
3
+ "version": "1.7.148",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -42,11 +42,12 @@ import { checkOtherUserKeys, seedUserKeys } from "./userKeys";
42
42
  // 4. A source's history was rewritten.
43
43
  // 5. A source started being signed by a different key, so its new keys are being held.
44
44
  // 6. A source is now signed when it was not before, applied right away.
45
- // 7. A source changed without its signature being updated, so the change is ignored.
46
- // 8. A source has a corrupted signature, so its contents are ignored.
47
- // 9. The webhook file itself changed, reported to the webhook being replaced.
48
- // 10. A trusted machine talked to us from an address it is not allowed from, so it was frozen
45
+ // 7. A source has a corrupted signature, so its contents are ignored.
46
+ // 8. The webhook file itself changed, reported to the webhook being replaced.
47
+ // 9. A trusted machine talked to us from an address it is not allowed from, so it was frozen
49
48
  // everywhere. Sent by whichever machine wrote that revocation, from machines.ts.
49
+ // A file that does not match the manifest is NOT on this list. It is one file we hold no
50
+ // signature for, it is logged where it is skipped, and the rest of the repo is unaffected.
50
51
 
51
52
  type DaemonConfig = {
52
53
  repoSources: string[];
@@ -62,9 +62,9 @@ function noteRevocation(revocationId, identity, ip) {
62
62
  absorbedRevocations.set(revocationId, { identity, ip });
63
63
  }
64
64
  exports.noteRevocation = noteRevocation;
65
- /** A repo that cannot be trusted, with the message ready for whoever asked. Not every caller
66
- treats these the same - a source keeps its last keys, a machine list is just refused - so the
67
- kind is carried rather than acted on here. */
65
+ /** A repo whose signature does not check out, with the message ready for whoever asked. Not every
66
+ caller treats it the same - a source keeps its last keys, a machine list is just refused - so
67
+ the kind is carried rather than acted on here. */
68
68
  class SignedRepoError extends Error {
69
69
  constructor(problem, headline, body) {
70
70
  super(`${headline}. ${body}`);
@@ -77,11 +77,14 @@ exports.SignedRepoError = SignedRepoError;
77
77
  /** Everything a signed checkout vouches for, in one call: who signed it, and the contents of every
78
78
  file the signature actually covers.
79
79
 
80
- UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError when a
81
- signature is present but does not hold up, or when a file it signed for was changed or removed
82
- without re-signing - either way the caller keeps whatever it last accepted rather than believing
83
- a repo that no longer matches what was signed. A file not in the manifest is just unsigned, so
84
- it is left out and warned about rather than treated as tampering. */
80
+ UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError only when the
81
+ signature over the manifest does not hold up, since then nothing in the repo can be believed and
82
+ the caller keeps whatever it last accepted.
83
+
84
+ Individual files are included or left out one at a time, and a file being left out never affects
85
+ the others: a file the manifest does not name, a file whose contents no longer match what was
86
+ signed, and a file the manifest names that is not on disk are all simply files we hold no
87
+ signature for. */
85
88
  async function readSignedRepo(config) {
86
89
  var _a;
87
90
  let { repoPath, sourceURL } = config;
@@ -112,8 +115,6 @@ async function readSignedRepo(config) {
112
115
  catch (e) {
113
116
  throw broken(`${e}`);
114
117
  }
115
- let stale = (detail) => new SignedRepoError("stale", `KEY REPO CHANGED WITHOUT BEING SIGNED`, `${detail}, so the repo is being ignored and this machine keeps using what it last accepted.`
116
- + `\n\nTo make the change take effect, run in that repo:\n\`\`\`\n${SIGN_COMMAND}\n\`\`\``);
117
118
  // Every file on disk, other than git's own directory and the two signature files, which cannot
118
119
  // describe themselves.
119
120
  let listCheckoutFiles = async (prefix) => {
@@ -134,27 +135,30 @@ async function readSignedRepo(config) {
134
135
  };
135
136
  let manifest = JSON.parse(manifestBytes.toString("utf8"));
136
137
  let listed = new Map((manifest.files || []).map((file) => [file.path, file]));
138
+ // A file counts only if the manifest names it AND its contents still match. Anything else is
139
+ // left out, one file at a time: an unsigned file, a file edited after signing, and a file the
140
+ // manifest names that is not here are all just files we have no signature for. None of them
141
+ // says anything about the files that DO match, so none of them takes the rest of the repo down
142
+ // with it - the signature over the manifest is the only thing that can do that.
137
143
  let files = new Map();
138
144
  for (let filePath of await listCheckoutFiles()) {
139
145
  let expected = listed.get(filePath);
140
- // A file the signature never mentioned is not tampering, it is just unsigned - left out
141
- // rather than trusted. An extra file in a working tree is ordinary, so it is only a note.
142
146
  if (!expected) {
143
147
  console.log(`Ignoring ${path_1.default.join(repoPath, filePath)}, it is not in the signed manifest`);
144
148
  continue;
145
149
  }
146
150
  let contents = (0, manifest_1.normalizeContent)(await promises_1.default.readFile(path_1.default.join(repoPath, filePath)));
147
151
  let hash = crypto_1.default.createHash("sha256").update(contents).digest("hex");
148
- // A file the manifest DOES name, but whose content no longer matches, is a signed file
149
- // changed without re-signing - the repo being edited out from under its signature.
150
152
  if (contents.length !== expected.size || hash !== expected.sha256) {
151
- throw stale(`${path_1.default.join(repoPath, filePath)} was changed after it was signed`);
153
+ console.log(`Ignoring ${path_1.default.join(repoPath, filePath)}, it was changed after it was signed.`
154
+ + ` Run ${SIGN_COMMAND} in that repo to sign it as it now is.`);
155
+ continue;
152
156
  }
153
157
  files.set(filePath, contents);
154
158
  }
155
159
  for (let filePath of listed.keys()) {
156
160
  if (!files.has(filePath)) {
157
- throw stale(`${path_1.default.join(repoPath, filePath)} is signed for but missing`);
161
+ console.log(`${path_1.default.join(repoPath, filePath)} is in the signed manifest, but there is nothing here that matches it`);
158
162
  }
159
163
  }
160
164
  // Absorb the revoke repo's files into the sticky map. Once seen a revocation never leaves it,
@@ -233,5 +237,5 @@ async function readSignedRepo(config) {
233
237
  return { signer, manifestHash, signatureHash, files };
234
238
  }
235
239
  exports.readSignedRepo = readSignedRepo;
236
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ1c3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0cnVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkRBQTZCO0FBQzdCLGdEQUF3QjtBQUN4Qix5REFBNkc7QUFDN0cscURBQXdEO0FBQ3hELHNEQUFtRDtBQUNuRCxrREFBaUQ7QUFFakQsaUdBQWlHO0FBQ2pHLG1EQUFtRDtBQUN0QyxRQUFBLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDM0IsNkZBQTZGO0FBQzdGLGtDQUFrQztBQUNsQyxNQUFNLFlBQVksR0FBRyxvQkFBb0IsQ0FBQztBQUMxQyxNQUFNLGVBQWUsR0FBRyxhQUFhLENBQUM7QUFDdEMsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDO0FBRWxDLGtHQUFrRztBQUNsRyxtR0FBbUc7QUFDbkcsZ0dBQWdHO0FBQ2hHLDBGQUEwRjtBQUMxRixJQUFJLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUE0QyxDQUFDO0FBQzlFLGtHQUFrRztBQUNsRyw4RUFBOEU7QUFDOUUsSUFBSSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUN2QyxJQUFJLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0FBRXJDO2tHQUNrRztBQUNsRyxTQUFnQixnQkFBZ0IsQ0FBQyxRQUFnQjtJQUM3QyxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxDQUFDLElBQUksbUJBQW1CLEVBQUUsQ0FBQztRQUN6RCxJQUFJLFVBQVUsQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsU0FBUztRQUNiLENBQUM7UUFDRCxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsSUFBSSxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3ZGLFNBQVM7UUFDYixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7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LFFBQVEsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ2pFLElBQUksU0FBUyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwRSxJQUFJLGdCQUFnQixDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7Z0JBQzlCLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLFNBQVMsU0FBUyxjQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQzFGLEtBQUssQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0IsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBRUQsT0FBTyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQzFELENBQUM7QUF6S0Qsd0NBeUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNyeXB0byBmcm9tIFwiY3J5cHRvXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgTUFOSUZFU1RfTkFNRSwgbm9ybWFsaXplQ29udGVudCwgU0lHTl9OQU1FU1BBQ0UsIFNJR05BVFVSRV9OQU1FIH0gZnJvbSBcIi4uLy4uL3NpZ25lZEZpbGVzL21hbmlmZXN0XCI7XG5pbXBvcnQgeyB2ZXJpZnlTU0hTSUcgfSBmcm9tIFwiLi4vLi4vc2lnbmVkRmlsZXMvc3Noc2lnXCI7XG5pbXBvcnQgeyBrZXlGaW5nZXJwcmludCB9IGZyb20gXCIuLi9hdXRob3JpemVkS2V5c1wiO1xuaW1wb3J0IHsgcmV2b2tlUmVwb1BhdGggfSBmcm9tIFwiLi4vcmV2b2tlU291cmNlXCI7XG5cbi8vIEEgc291cmNlIHRoYXQgaGFzIG5ldmVyIGJlZW4gc2lnbmVkIHJlYWRzIGFzIHRoaXMsIHNvIGxvc2luZyBhIHNpZ25hdHVyZSBjb3VudHMgYXMgYSBjaGFuZ2Ugb2Zcbi8vIHNpZ25lciByYXRoZXIgdGhhbiBhcyBzb21ldGhpbmcgdG8gd2F2ZSB0aHJvdWdoLlxuZXhwb3J0IGNvbnN0IFVOU0lHTkVEID0gXCJcIjtcbi8vIFdoYXQgZml4ZXMgYm90aCBvZiB0aGUgc2lnbmF0dXJlIHByb2JsZW1zIHdlIHJlcG9ydCwgc28gdGhlIG1lc3NhZ2UgY2FuIHNheSBzbyByYXRoZXIgdGhhblxuLy8gbGVhdmluZyBzb21lb25lIHRvIHdvcmsgaXQgb3V0LlxuY29uc3QgU0lHTl9DT01NQU5EID0gXCJ5YXJuIHNpZ25maWxlcyBnaXRcIjtcbmNvbnN0IFJFVk9DQVRJT05TX0RJUiA9IFwicmV2b2NhdGlvbnNcIjtcbmNvbnN0IFVOUkVWT0tFU19ESVIgPSBcInVucmV2b2tlZFwiO1xuXG4vLyBFdmVyeSByZXZvY2F0aW9uIHRoaXMgcHJvY2VzcyBoYXMgZXZlciBzZWVuLCBrZXllZCBieSByZXZvY2F0aW9uIGlkLiBPbmNlIGFic29yYmVkIGEgcmV2b2NhdGlvblxuLy8gbmV2ZXIgbGVhdmVzLCBldmVuIGlmIGl0cyBmaWxlIGRpc2FwcGVhcnMgZnJvbSB0aGUgcmV2b2tlIHJlcG8gLSB0aGUga2V5IHRoYXQgd3JpdGVzIHJldm9jYXRpb25zXG4vLyBpcyBvbiBldmVyeSBzZXJ2ZXIsIHNvIHdob2V2ZXIgc3RvbGUgb25lIGNvdWxkIG90aGVyd2lzZSBlcmFzZSB0aGUgcmVjb3JkIHRoYXQgc2h1dCB0aGVtIG91dC5cbi8vIFJlc3RhcnRpbmcgdGhlIHByb2Nlc3MgaXMgdGhlIHdheSBiYWNrIGZyb20gYSByZXZvY2F0aW9uIHRoYXQgc2hvdWxkIG5vdCBoYXZlIGhhcHBlbmVkLlxubGV0IGFic29yYmVkUmV2b2NhdGlvbnMgPSBuZXcgTWFwPHN0cmluZywgeyBpZGVudGl0eTogc3RyaW5nOyBpcDogc3RyaW5nIH0+KCk7XG4vLyBUaGUgcGFpcnMgdGhlIHNpZ25lZCB1bnJldm9rZXMgYWxsb3csIGFuZCB0aGUgbGVnYWN5IHJldm9jYXRpb24gaWRzIHRoZXkgbmFtZS4gUmVidWlsdCBvbiBldmVyeVxuLy8gcmVhZCwgc2luY2UgdW5yZXZva2VzIGFyZSBzaWduZWQgY29udGVudCBhbmQgcmVtb3Zpbmcgb25lIG11c3QgdGFrZSBlZmZlY3QuXG5sZXQgdW5yZXZva2VkUGFpcnMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbmxldCB1bnJldm9rZWRJZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqIFdoZXRoZXIgYW4gaWRlbnRpdHkgLSBhIGtleSBmaW5nZXJwcmludCBvciBhIG1hY2hpbmUgaWQgLSBoYXMgYSByZXZvY2F0aW9uIG5vdGhpbmcgaGFzIHVuZG9uZS5cbiAgICBUaGUgb25lIG1lYW5pbmcgb2YgXCJmcm96ZW5cIiwgdXNlZCBib3RoIHdoZW4gc3RyaXBwaW5nIHJlcG8gY29udGVudCBhbmQgd2hlbiBleHBsYWluaW5nIHdoeS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0lkZW50aXR5RnJvemVuKGlkZW50aXR5OiBzdHJpbmcpIHtcbiAgICBmb3IgKGxldCBbcmV2b2NhdGlvbklkLCByZXZvY2F0aW9uXSBvZiBhYnNvcmJlZFJldm9jYXRpb25zKSB7XG4gICAgICAgIGlmIChyZXZvY2F0aW9uLmlkZW50aXR5ICE9PSBpZGVudGl0eSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVucmV2b2tlZElkcy5oYXMocmV2b2NhdGlvbklkKSB8fCB1bnJldm9rZWRQYWlycy5oYXMoYCR7aWRlbnRpdHl9ICR7cmV2b2NhdGlvbi5pcH1gKSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGFpclJldm9rZWQoaWRlbnRpdHk6IHN0cmluZywgaXA6IHN0cmluZykge1xuICAgIGZvciAobGV0IFtyZXZvY2F0aW9uSWQsIHJldm9jYXRpb25dIG9mIGFic29yYmVkUmV2b2NhdGlvbnMpIHtcbiAgICAgICAgaWYgKHJldm9jYXRpb24uaWRlbnRpdHkgPT09IGlkZW50aXR5ICYmIHJldm9jYXRpb24uaXAgPT09IGlwICYmICF1bnJldm9rZWRJZHMuaGFzKHJldm9jYXRpb25JZCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUGFpclVucmV2b2tlZChpZGVudGl0eTogc3RyaW5nLCBpcDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHVucmV2b2tlZFBhaXJzLmhhcyhgJHtpZGVudGl0eX0gJHtpcH1gKTtcbn1cblxuLyoqIEZvciB3aG9ldmVyIGp1c3Qgd3JvdGUgYSByZXZvY2F0aW9uLCBzbyBpdCBob2xkcyBoZXJlIGltbWVkaWF0ZWx5IHJhdGhlciB0aGFuIG9uIHRoZSBuZXh0XG4gICAgYWJzb3JiLiBTdGlja3kgbGlrZSB0aGUgcmVzdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3RlUmV2b2NhdGlvbihyZXZvY2F0aW9uSWQ6IHN0cmluZywgaWRlbnRpdHk6IHN0cmluZywgaXA6IHN0cmluZykge1xuICAgIGFic29yYmVkUmV2b2NhdGlvbnMuc2V0KHJldm9jYXRpb25JZCwgeyBpZGVudGl0eSwgaXAgfSk7XG59XG5cbi8qKiBBIHJlcG8gdGhhdCBjYW5ub3QgYmUgdHJ1c3RlZCwgd2l0aCB0aGUgbWVzc2FnZSByZWFkeSBmb3Igd2hvZXZlciBhc2tlZC4gTm90IGV2ZXJ5IGNhbGxlclxuICAgIHRyZWF0cyB0aGVzZSB0aGUgc2FtZSAtIGEgc291cmNlIGtlZXBzIGl0cyBsYXN0IGtleXMsIGEgbWFjaGluZSBsaXN0IGlzIGp1c3QgcmVmdXNlZCAtIHNvIHRoZVxuICAgIGtpbmQgaXMgY2FycmllZCByYXRoZXIgdGhhbiBhY3RlZCBvbiBoZXJlLiAqL1xuZXhwb3J0IGNsYXNzIFNpZ25lZFJlcG9FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgcHJvYmxlbTogc3RyaW5nLCBwdWJsaWMgaGVhZGxpbmU6IHN0cmluZywgcHVibGljIGJvZHk6IHN0cmluZykge1xuICAgICAgICBzdXBlcihgJHtoZWFkbGluZX0uICR7Ym9keX1gKTtcbiAgICB9XG59XG5cbi8qKiBFdmVyeXRoaW5nIGEgc2lnbmVkIGNoZWNrb3V0IHZvdWNoZXMgZm9yLCBpbiBvbmUgY2FsbDogd2hvIHNpZ25lZCBpdCwgYW5kIHRoZSBjb250ZW50cyBvZiBldmVyeVxuICAgIGZpbGUgdGhlIHNpZ25hdHVyZSBhY3R1YWxseSBjb3ZlcnMuXG5cbiAgICBVTlNJR05FRCB3aXRoIG5vIGZpbGVzIHdoZW4gdGhlcmUgaXMgbm8gc2lnbmF0dXJlIGF0IGFsbC4gVGhyb3dzIGEgU2lnbmVkUmVwb0Vycm9yIHdoZW4gYVxuICAgIHNpZ25hdHVyZSBpcyBwcmVzZW50IGJ1dCBkb2VzIG5vdCBob2xkIHVwLCBvciB3aGVuIGEgZmlsZSBpdCBzaWduZWQgZm9yIHdhcyBjaGFuZ2VkIG9yIHJlbW92ZWRcbiAgICB3aXRob3V0IHJlLXNpZ25pbmcgLSBlaXRoZXIgd2F5IHRoZSBjYWxsZXIga2VlcHMgd2hhdGV2ZXIgaXQgbGFzdCBhY2NlcHRlZCByYXRoZXIgdGhhbiBiZWxpZXZpbmdcbiAgICBhIHJlcG8gdGhhdCBubyBsb25nZXIgbWF0Y2hlcyB3aGF0IHdhcyBzaWduZWQuIEEgZmlsZSBub3QgaW4gdGhlIG1hbmlmZXN0IGlzIGp1c3QgdW5zaWduZWQsIHNvXG4gICAgaXQgaXMgbGVmdCBvdXQgYW5kIHdhcm5lZCBhYm91dCByYXRoZXIgdGhhbiB0cmVhdGVkIGFzIHRhbXBlcmluZy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkU2lnbmVkUmVwbyhjb25maWc6IHsgcmVwb1BhdGg6IHN0cmluZzsgc291cmNlVVJMOiBzdHJpbmcgfSk6IFByb21pc2U8e1xuICAgIHNpZ25lcjogc3RyaW5nO1xuICAgIG1hbmlmZXN0SGFzaDogc3RyaW5nO1xuICAgIHNpZ25hdHVyZUhhc2g6IHN0cmluZztcbiAgICBmaWxlczogTWFwPHN0cmluZywgQnVmZmVyPjtcbn0+IHtcbiAgICBsZXQgeyByZXBvUGF0aCwgc291cmNlVVJMIH0gPSBjb25maWc7XG4gICAgbGV0IG1hbmlmZXN0Qnl0ZXMgPSBhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4ocmVwb1BhdGgsIE1BTklGRVNUX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBzaWduYXR1cmVCeXRlcyA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgU0lHTkFUVVJFX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBtYW5pZmVzdEhhc2ggPSBtYW5pZmVzdEJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShtYW5pZmVzdEJ5dGVzKS5kaWdlc3QoXCJoZXhcIikgfHwgXCJcIjtcbiAgICBsZXQgc2lnbmF0dXJlSGFzaCA9IHNpZ25hdHVyZUJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShzaWduYXR1cmVCeXRlcykuZGlnZXN0KFwiaGV4XCIpIHx8IFwiXCI7XG5cbiAgICBpZiAoIW1hbmlmZXN0Qnl0ZXMgJiYgIXNpZ25hdHVyZUJ5dGVzKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke3JlcG9QYXRofSBpcyBub3Qgc2lnbmVkLCBpZ25vcmluZyBhbGwgb2YgaXRzIGZpbGVzYCk7XG4gICAgICAgIHJldHVybiB7IHNpZ25lcjogVU5TSUdORUQsIG1hbmlmZXN0SGFzaCwgc2lnbmF0dXJlSGFzaCwgZmlsZXM6IG5ldyBNYXAoKSB9O1xuICAgIH1cblxuICAgIGxldCBicm9rZW4gPSAoZGV0YWlsOiBzdHJpbmcpID0+IG5ldyBTaWduZWRSZXBvRXJyb3IoXG4gICAgICAgIFwiY29ycnVwdFwiLFxuICAgICAgICBgS0VZIFJFUE8gU0lHTkFUVVJFIElTIEJST0tFTmAsXG4gICAgICAgIGBUaGUgc2lnbmF0dXJlIG9uICR7cmVwb1BhdGh9IGRvZXMgbm90IGNoZWNrIG91dCwgc28gZXZlcnl0aGluZyBpbiBpdCBpcyBiZWluZyBpZ25vcmVkIGFuZGBcbiAgICAgICAgKyBgIHRoaXMgbWFjaGluZSBrZWVwcyB1c2luZyB3aGF0IGl0IGxhc3QgYWNjZXB0ZWQuXFxuXFxuJHtkZXRhaWx9YFxuICAgICAgICArIGBcXG5cXG5UbyByZXBsYWNlIHRoZSBzaWduYXR1cmUsIHJ1biBpbiB0aGF0IHJlcG86XFxuXFxgXFxgXFxgXFxuJHtTSUdOX0NPTU1BTkR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG4gICAgaWYgKCFtYW5pZmVzdEJ5dGVzIHx8ICFzaWduYXR1cmVCeXRlcykge1xuICAgICAgICB0aHJvdyBicm9rZW4oYE9ubHkgb25lIG9mICR7TUFOSUZFU1RfTkFNRX0gYW5kICR7U0lHTkFUVVJFX05BTUV9IGlzIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgbGV0IHNpZ25lcjogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoZSBzaWduYXR1cmUgY292ZXJzIHRoZSBub3JtYWxpc2VkIGJ5dGVzLCBzbyBhIGNoZWNrb3V0IHRoYXQgYXJyaXZlZCB3aXRoIENSTEYgc3RpbGxcbiAgICAgICAgLy8gdmVyaWZpZXMgcmF0aGVyIHRoYW4gbG9va2luZyBsaWtlIHRhbXBlcmluZy5cbiAgICAgICAgc2lnbmVyID0gdmVyaWZ5U1NIU0lHKHtcbiAgICAgICAgICAgIHNpZ25hdHVyZTogc2lnbmF0dXJlQnl0ZXMudG9TdHJpbmcoXCJ1dGY4XCIpLFxuICAgICAgICAgICAgbWVzc2FnZTogbm9ybWFsaXplQ29udGVudChtYW5pZmVzdEJ5dGVzKSxcbiAgICAgICAgICAgIG5hbWVzcGFjZTogU0lHTl9OQU1FU1BBQ0UsXG4gICAgICAgIH0pLnB1YmxpY0tleTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IGJyb2tlbihgJHtlfWApO1xuICAgIH1cblxuICAgIGxldCBzdGFsZSA9IChkZXRhaWw6IHN0cmluZykgPT4gbmV3IFNpZ25lZFJlcG9FcnJvcihcbiAgICAgICAgXCJzdGFsZVwiLFxuICAgICAgICBgS0VZIFJFUE8gQ0hBTkdFRCBXSVRIT1VUIEJFSU5HIFNJR05FRGAsXG4gICAgICAgIGAke2RldGFpbH0sIHNvIHRoZSByZXBvIGlzIGJlaW5nIGlnbm9yZWQgYW5kIHRoaXMgbWFjaGluZSBrZWVwcyB1c2luZyB3aGF0IGl0IGxhc3QgYWNjZXB0ZWQuYFxuICAgICAgICArIGBcXG5cXG5UbyBtYWtlIHRoZSBjaGFuZ2UgdGFrZSBlZmZlY3QsIHJ1biBpbiB0aGF0IHJlcG86XFxuXFxgXFxgXFxgXFxuJHtTSUdOX0NPTU1BTkR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG5cbiAgICAvLyBFdmVyeSBmaWxlIG9uIGRpc2ssIG90aGVyIHRoYW4gZ2l0J3Mgb3duIGRpcmVjdG9yeSBhbmQgdGhlIHR3byBzaWduYXR1cmUgZmlsZXMsIHdoaWNoIGNhbm5vdFxuICAgIC8vIGRlc2NyaWJlIHRoZW1zZWx2ZXMuXG4gICAgbGV0IGxpc3RDaGVja291dEZpbGVzID0gYXN5bmMgKHByZWZpeD86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nW10+ID0+IHtcbiAgICAgICAgbGV0IGZvdW5kOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBlbnRyeSBvZiBhd2FpdCBmcy5yZWFkZGlyKHBhdGguam9pbihyZXBvUGF0aCwgcHJlZml4IHx8IFwiXCIpLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSkpIHtcbiAgICAgICAgICAgIGxldCByZWxhdGl2ZVBhdGggPSBwcmVmaXggJiYgYCR7cHJlZml4fS8ke2VudHJ5Lm5hbWV9YCB8fCBlbnRyeS5uYW1lO1xuICAgICAgICAgICAgaWYgKGVudHJ5Lm5hbWUgPT09IFwiLmdpdFwiKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmICghcHJlZml4ICYmIChlbnRyeS5uYW1lID09PSBNQU5JRkVTVF9OQU1FIHx8IGVudHJ5Lm5hbWUgPT09IFNJR05BVFVSRV9OQU1FKSkgY29udGludWU7XG4gICAgICAgICAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgICAgICAgICAgIGZvdW5kLnB1c2goLi4uYXdhaXQgbGlzdENoZWNrb3V0RmlsZXMocmVsYXRpdmVQYXRoKSk7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3VuZC5wdXNoKHJlbGF0aXZlUGF0aCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvdW5kLnNvcnQoKTtcbiAgICB9O1xuXG4gICAgbGV0IG1hbmlmZXN0ID0gSlNPTi5wYXJzZShtYW5pZmVzdEJ5dGVzLnRvU3RyaW5nKFwidXRmOFwiKSk7XG4gICAgbGV0IGxpc3RlZCA9IG5ldyBNYXA8c3RyaW5nLCB7IHNpemU6IG51bWJlcjsgc2hhMjU2OiBzdHJpbmcgfT4oXG4gICAgICAgIChtYW5pZmVzdC5maWxlcyB8fCBbXSkubWFwKChmaWxlOiB7IHBhdGg6IHN0cmluZzsgc2l6ZTogbnVtYmVyOyBzaGEyNTY6IHN0cmluZyB9KSA9PiBbZmlsZS5wYXRoLCBmaWxlXSlcbiAgICApO1xuXG4gICAgbGV0IGZpbGVzID0gbmV3IE1hcDxzdHJpbmcsIEJ1ZmZlcj4oKTtcbiAgICBmb3IgKGxldCBmaWxlUGF0aCBvZiBhd2FpdCBsaXN0Q2hlY2tvdXRGaWxlcygpKSB7XG4gICAgICAgIGxldCBleHBlY3RlZCA9IGxpc3RlZC5nZXQoZmlsZVBhdGgpO1xuICAgICAgICAvLyBBIGZpbGUgdGhlIHNpZ25hdHVyZSBuZXZlciBtZW50aW9uZWQgaXMgbm90IHRhbXBlcmluZywgaXQgaXMganVzdCB1bnNpZ25lZCAtIGxlZnQgb3V0XG4gICAgICAgIC8vIHJhdGhlciB0aGFuIHRydXN0ZWQuIEFuIGV4dHJhIGZpbGUgaW4gYSB3b3JraW5nIHRyZWUgaXMgb3JkaW5hcnksIHNvIGl0IGlzIG9ubHkgYSBub3RlLlxuICAgICAgICBpZiAoIWV4cGVjdGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0sIGl0IGlzIG5vdCBpbiB0aGUgc2lnbmVkIG1hbmlmZXN0YCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudHMgPSBub3JtYWxpemVDb250ZW50KGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpKSk7XG4gICAgICAgIGxldCBoYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNvbnRlbnRzKS5kaWdlc3QoXCJoZXhcIik7XG4gICAgICAgIC8vIEEgZmlsZSB0aGUgbWFuaWZlc3QgRE9FUyBuYW1lLCBidXQgd2hvc2UgY29udGVudCBubyBsb25nZXIgbWF0Y2hlcywgaXMgYSBzaWduZWQgZmlsZVxuICAgICAgICAvLyBjaGFuZ2VkIHdpdGhvdXQgcmUtc2lnbmluZyAtIHRoZSByZXBvIGJlaW5nIGVkaXRlZCBvdXQgZnJvbSB1bmRlciBpdHMgc2lnbmF0dXJlLlxuICAgICAgICBpZiAoY29udGVudHMubGVuZ3RoICE9PSBleHBlY3RlZC5zaXplIHx8IGhhc2ggIT09IGV4cGVjdGVkLnNoYTI1Nikge1xuICAgICAgICAgICAgdGhyb3cgc3RhbGUoYCR7cGF0aC5qb2luKHJlcG9QYXRoLCBmaWxlUGF0aCl9IHdhcyBjaGFuZ2VkIGFmdGVyIGl0IHdhcyBzaWduZWRgKTtcbiAgICAgICAgfVxuICAgICAgICBmaWxlcy5zZXQoZmlsZVBhdGgsIGNvbnRlbnRzKTtcbiAgICB9XG4gICAgZm9yIChsZXQgZmlsZVBhdGggb2YgbGlzdGVkLmtleXMoKSkge1xuICAgICAgICBpZiAoIWZpbGVzLmhhcyhmaWxlUGF0aCkpIHtcbiAgICAgICAgICAgIHRocm93IHN0YWxlKGAke3BhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpfSBpcyBzaWduZWQgZm9yIGJ1dCBtaXNzaW5nYCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBYnNvcmIgdGhlIHJldm9rZSByZXBvJ3MgZmlsZXMgaW50byB0aGUgc3RpY2t5IG1hcC4gT25jZSBzZWVuIGEgcmV2b2NhdGlvbiBuZXZlciBsZWF2ZXMgaXQsXG4gICAgLy8gZXZlbiBpZiBpdHMgZmlsZSBkaXNhcHBlYXJzIC0gdGhlIGtleSB0aGF0IHdyaXRlcyByZXZvY2F0aW9ucyBpcyBvbiBldmVyeSBzZXJ2ZXIsIHNvIHdob2V2ZXJcbiAgICAvLyBzdG9sZSBvbmUgY291bGQgb3RoZXJ3aXNlIGVyYXNlIHRoZSByZWNvcmQgdGhhdCBzaHV0IHRoZW0gb3V0LlxuICAgIGxldCByZXZvY2F0aW9uc0RpcmVjdG9yeSA9IHBhdGguam9pbihyZXZva2VSZXBvUGF0aChzb3VyY2VVUkwpLCBSRVZPQ0FUSU9OU19ESVIpO1xuICAgIGZvciAobGV0IG5hbWUgb2YgKGF3YWl0IGZzLnJlYWRkaXIocmV2b2NhdGlvbnNEaXJlY3RvcnkpLmNhdGNoKCgpID0+IFtdIGFzIHN0cmluZ1tdKSkuc29ydCgpKSB7XG4gICAgICAgIGlmICghbmFtZS5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHBhcnNlZCA9IEpTT04ucGFyc2UoYXdhaXQgZnMucmVhZEZpbGUocGF0aC5qb2luKHJldm9jYXRpb25zRGlyZWN0b3J5LCBuYW1lKSwgXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGxldCBpZGVudGl0eSA9IHBhcnNlZC5maW5nZXJwcmludCB8fCBwYXJzZWQubWFjaGluZUlkO1xuICAgICAgICAgICAgaWYgKCFpZGVudGl0eSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHJldm9jYXRpb25JZCA9IHBhcnNlZC5yZXZvY2F0aW9uSWQgfHwgbmFtZS5yZXBsYWNlKC9cXC5qc29uJC8sIFwiXCIpO1xuICAgICAgICAgICAgaWYgKCFhYnNvcmJlZFJldm9jYXRpb25zLmhhcyhyZXZvY2F0aW9uSWQpKSB7XG4gICAgICAgICAgICAgICAgYWJzb3JiZWRSZXZvY2F0aW9ucy5zZXQocmV2b2NhdGlvbklkLCB7IGlkZW50aXR5LCBpcDogcGFyc2VkLmlwIHx8IHBhcnNlZC5hdHRlbXB0Py5pcCB8fCBcIlwiIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgdW5yZWFkYWJsZSByZXZvY2F0aW9uICR7cGF0aC5qb2luKHJldm9jYXRpb25zRGlyZWN0b3J5LCBuYW1lKX0uICR7ZX1gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJlYnVpbGQgdGhlIHVucmV2b2tlcyBmcm9tIHRoZSBzaWduZWQgZmlsZXMganVzdCByZWFkLiBVbnJldm9rZXMgYXJlIHNpZ25lZCBjb250ZW50LCBzb1xuICAgIC8vIHJlbW92aW5nIG9uZSBtdXN0IHRha2UgZWZmZWN0LCB1bmxpa2UgdGhlIHN0aWNreSByZXZvY2F0aW9ucy5cbiAgICB1bnJldm9rZWRQYWlycyA9IG5ldyBTZXQoKTtcbiAgICB1bnJldm9rZWRJZHMgPSBuZXcgU2V0KCk7XG4gICAgZm9yIChsZXQgW2ZpbGVQYXRoLCBjb250ZW50c10gb2YgZmlsZXMpIHtcbiAgICAgICAgaWYgKCFmaWxlUGF0aC5zdGFydHNXaXRoKGAke1VOUkVWT0tFU19ESVJ9L2ApIHx8ICFmaWxlUGF0aC5lbmRzV2l0aChcIi5qc29uXCIpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHBhcnNlZCA9IEpTT04ucGFyc2UoY29udGVudHMudG9TdHJpbmcoXCJ1dGY4XCIpKTtcbiAgICAgICAgICAgIGZvciAobGV0IGFsbG93ZWQgb2YgcGFyc2VkLmFsbG93ZWQgfHwgW10pIHtcbiAgICAgICAgICAgICAgICBsZXQgaWRlbnRpdHkgPSBhbGxvd2VkLmZpbmdlcnByaW50IHx8IGFsbG93ZWQubWFjaGluZUlkO1xuICAgICAgICAgICAgICAgIGlmIChpZGVudGl0eSAmJiBhbGxvd2VkLmlwKSB7XG4gICAgICAgICAgICAgICAgICAgIHVucmV2b2tlZFBhaXJzLmFkZChgJHtpZGVudGl0eX0gJHthbGxvd2VkLmlwfWApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAobGV0IHJldm9jYXRpb25JZCBvZiBwYXJzZWQucmV2b2NhdGlvbklkcyB8fCBbXSkge1xuICAgICAgICAgICAgICAgIHVucmV2b2tlZElkcy5hZGQocmV2b2NhdGlvbklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYElnbm9yaW5nIHVucmVhZGFibGUgdW5yZXZva2UgJHtmaWxlUGF0aH0uICR7ZX1gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIERyb3AgZXZlcnl0aGluZyBmcm96ZW46IHJldm9rZWQga2V5cyBvdXQgb2YgYXV0aG9yaXplZF9rZXlzIGFuZCB0b3AgbGV2ZWwgLnB1YiBmaWxlcywgYW5kXG4gICAgLy8gZnJvemVuIG1hY2hpbmVzJyBmaWxlcyBvdXQgb2YgbWFjaGluZXMvLiBXaGF0IGNvbWVzIGJhY2sgaXMgd2hhdCB0aGlzIG1hY2hpbmUgYWN0dWFsbHlcbiAgICAvLyB0cnVzdHMsIHNvIG5vIGNhbGxlciBjYW4gcmVhZCB0aGUgbGlzdCBhbmQgZm9yZ2V0IHRoZSByZXZvY2F0aW9ucy5cbiAgICBmb3IgKGxldCBbZmlsZVBhdGgsIGNvbnRlbnRzXSBvZiBbLi4uZmlsZXNdKSB7XG4gICAgICAgIGlmIChmaWxlUGF0aCA9PT0gXCJhdXRob3JpemVkX2tleXNcIiB8fCAoZmlsZVBhdGguZW5kc1dpdGgoXCIucHViXCIpICYmICFmaWxlUGF0aC5pbmNsdWRlcyhcIi9cIikpKSB7XG4gICAgICAgICAgICBsZXQgbGluZXMgPSBjb250ZW50cy50b1N0cmluZyhcInV0ZjhcIikuc3BsaXQoXCJcXG5cIik7XG4gICAgICAgICAgICBsZXQga2VwdCA9IGxpbmVzLmZpbHRlcihsaW5lID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZmluZ2VycHJpbnQgPSBrZXlGaW5nZXJwcmludChsaW5lKTtcbiAgICAgICAgICAgICAgICBpZiAoZmluZ2VycHJpbnQgJiYgaXNJZGVudGl0eUZyb3plbihmaW5nZXJwcmludCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYERyb3BwaW5nIHJldm9rZWQga2V5ICR7ZmluZ2VycHJpbnR9IGZyb20gJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX1gKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGtlcHQubGVuZ3RoICE9PSBsaW5lcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmaWxlcy5zZXQoZmlsZVBhdGgsIEJ1ZmZlci5mcm9tKGtlcHQuam9pbihcIlxcblwiKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChmaWxlUGF0aC5zdGFydHNXaXRoKFwibWFjaGluZXMvXCIpICYmIGZpbGVQYXRoLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGxldCBtYWNoaW5lSWQgPSBmaWxlUGF0aC5zbGljZShcIm1hY2hpbmVzL1wiLmxlbmd0aCwgLVwiLmpzb25cIi5sZW5ndGgpO1xuICAgICAgICAgICAgaWYgKGlzSWRlbnRpdHlGcm96ZW4obWFjaGluZUlkKSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBEcm9wcGluZyBmcm96ZW4gbWFjaGluZSAke21hY2hpbmVJZH0gZnJvbSAke3BhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpfWApO1xuICAgICAgICAgICAgICAgIGZpbGVzLmRlbGV0ZShmaWxlUGF0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBzaWduZXIsIG1hbmlmZXN0SGFzaCwgc2lnbmF0dXJlSGFzaCwgZmlsZXMgfTtcbn1cbiJdfQ==
237
- /* _JS_SOURCE_HASH = "dca3e0a9ba6326240f357f9f44b892b1cf1bf3622269921530457ceab4e3266a"; */
240
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJ1c3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0cnVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBNEI7QUFDNUIsMkRBQTZCO0FBQzdCLGdEQUF3QjtBQUN4Qix5REFBNkc7QUFDN0cscURBQXdEO0FBQ3hELHNEQUFtRDtBQUNuRCxrREFBaUQ7QUFFakQsaUdBQWlHO0FBQ2pHLG1EQUFtRDtBQUN0QyxRQUFBLFFBQVEsR0FBRyxFQUFFLENBQUM7QUFDM0IsNkZBQTZGO0FBQzdGLGtDQUFrQztBQUNsQyxNQUFNLFlBQVksR0FBRyxvQkFBb0IsQ0FBQztBQUMxQyxNQUFNLGVBQWUsR0FBRyxhQUFhLENBQUM7QUFDdEMsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDO0FBRWxDLGtHQUFrRztBQUNsRyxtR0FBbUc7QUFDbkcsZ0dBQWdHO0FBQ2hHLDBGQUEwRjtBQUMxRixJQUFJLG1CQUFtQixHQUFHLElBQUksR0FBRyxFQUE0QyxDQUFDO0FBQzlFLGtHQUFrRztBQUNsRyw4RUFBOEU7QUFDOUUsSUFBSSxjQUFjLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUN2QyxJQUFJLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0FBRXJDO2tHQUNrRztBQUNsRyxTQUFnQixnQkFBZ0IsQ0FBQyxRQUFnQjtJQUM3QyxLQUFLLElBQUksQ0FBQyxZQUFZLEVBQUUsVUFBVSxDQUFDLElBQUksbUJBQW1CLEVBQUUsQ0FBQztRQUN6RCxJQUFJLFVBQVUsQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsU0FBUztRQUNiLENBQUM7UUFDRCxJQUFJLFlBQVksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsSUFBSSxVQUFVLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ3ZGLFNBQVM7UUFDYixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7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WUFDakUsSUFBSSxTQUFTLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BFLElBQUksZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztnQkFDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsU0FBUyxTQUFTLGNBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDMUYsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMzQixDQUFDO1FBQ0wsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDMUQsQ0FBQztBQXZLRCx3Q0F1S0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY3J5cHRvIGZyb20gXCJjcnlwdG9cIjtcbmltcG9ydCBmcyBmcm9tIFwiZnMvcHJvbWlzZXNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBNQU5JRkVTVF9OQU1FLCBub3JtYWxpemVDb250ZW50LCBTSUdOX05BTUVTUEFDRSwgU0lHTkFUVVJFX05BTUUgfSBmcm9tIFwiLi4vLi4vc2lnbmVkRmlsZXMvbWFuaWZlc3RcIjtcbmltcG9ydCB7IHZlcmlmeVNTSFNJRyB9IGZyb20gXCIuLi8uLi9zaWduZWRGaWxlcy9zc2hzaWdcIjtcbmltcG9ydCB7IGtleUZpbmdlcnByaW50IH0gZnJvbSBcIi4uL2F1dGhvcml6ZWRLZXlzXCI7XG5pbXBvcnQgeyByZXZva2VSZXBvUGF0aCB9IGZyb20gXCIuLi9yZXZva2VTb3VyY2VcIjtcblxuLy8gQSBzb3VyY2UgdGhhdCBoYXMgbmV2ZXIgYmVlbiBzaWduZWQgcmVhZHMgYXMgdGhpcywgc28gbG9zaW5nIGEgc2lnbmF0dXJlIGNvdW50cyBhcyBhIGNoYW5nZSBvZlxuLy8gc2lnbmVyIHJhdGhlciB0aGFuIGFzIHNvbWV0aGluZyB0byB3YXZlIHRocm91Z2guXG5leHBvcnQgY29uc3QgVU5TSUdORUQgPSBcIlwiO1xuLy8gV2hhdCBmaXhlcyBib3RoIG9mIHRoZSBzaWduYXR1cmUgcHJvYmxlbXMgd2UgcmVwb3J0LCBzbyB0aGUgbWVzc2FnZSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4vLyBsZWF2aW5nIHNvbWVvbmUgdG8gd29yayBpdCBvdXQuXG5jb25zdCBTSUdOX0NPTU1BTkQgPSBcInlhcm4gc2lnbmZpbGVzIGdpdFwiO1xuY29uc3QgUkVWT0NBVElPTlNfRElSID0gXCJyZXZvY2F0aW9uc1wiO1xuY29uc3QgVU5SRVZPS0VTX0RJUiA9IFwidW5yZXZva2VkXCI7XG5cbi8vIEV2ZXJ5IHJldm9jYXRpb24gdGhpcyBwcm9jZXNzIGhhcyBldmVyIHNlZW4sIGtleWVkIGJ5IHJldm9jYXRpb24gaWQuIE9uY2UgYWJzb3JiZWQgYSByZXZvY2F0aW9uXG4vLyBuZXZlciBsZWF2ZXMsIGV2ZW4gaWYgaXRzIGZpbGUgZGlzYXBwZWFycyBmcm9tIHRoZSByZXZva2UgcmVwbyAtIHRoZSBrZXkgdGhhdCB3cml0ZXMgcmV2b2NhdGlvbnNcbi8vIGlzIG9uIGV2ZXJ5IHNlcnZlciwgc28gd2hvZXZlciBzdG9sZSBvbmUgY291bGQgb3RoZXJ3aXNlIGVyYXNlIHRoZSByZWNvcmQgdGhhdCBzaHV0IHRoZW0gb3V0LlxuLy8gUmVzdGFydGluZyB0aGUgcHJvY2VzcyBpcyB0aGUgd2F5IGJhY2sgZnJvbSBhIHJldm9jYXRpb24gdGhhdCBzaG91bGQgbm90IGhhdmUgaGFwcGVuZWQuXG5sZXQgYWJzb3JiZWRSZXZvY2F0aW9ucyA9IG5ldyBNYXA8c3RyaW5nLCB7IGlkZW50aXR5OiBzdHJpbmc7IGlwOiBzdHJpbmcgfT4oKTtcbi8vIFRoZSBwYWlycyB0aGUgc2lnbmVkIHVucmV2b2tlcyBhbGxvdywgYW5kIHRoZSBsZWdhY3kgcmV2b2NhdGlvbiBpZHMgdGhleSBuYW1lLiBSZWJ1aWx0IG9uIGV2ZXJ5XG4vLyByZWFkLCBzaW5jZSB1bnJldm9rZXMgYXJlIHNpZ25lZCBjb250ZW50IGFuZCByZW1vdmluZyBvbmUgbXVzdCB0YWtlIGVmZmVjdC5cbmxldCB1bnJldm9rZWRQYWlycyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xubGV0IHVucmV2b2tlZElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4vKiogV2hldGhlciBhbiBpZGVudGl0eSAtIGEga2V5IGZpbmdlcnByaW50IG9yIGEgbWFjaGluZSBpZCAtIGhhcyBhIHJldm9jYXRpb24gbm90aGluZyBoYXMgdW5kb25lLlxuICAgIFRoZSBvbmUgbWVhbmluZyBvZiBcImZyb3plblwiLCB1c2VkIGJvdGggd2hlbiBzdHJpcHBpbmcgcmVwbyBjb250ZW50IGFuZCB3aGVuIGV4cGxhaW5pbmcgd2h5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzSWRlbnRpdHlGcm96ZW4oaWRlbnRpdHk6IHN0cmluZykge1xuICAgIGZvciAobGV0IFtyZXZvY2F0aW9uSWQsIHJldm9jYXRpb25dIG9mIGFic29yYmVkUmV2b2NhdGlvbnMpIHtcbiAgICAgICAgaWYgKHJldm9jYXRpb24uaWRlbnRpdHkgIT09IGlkZW50aXR5KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodW5yZXZva2VkSWRzLmhhcyhyZXZvY2F0aW9uSWQpIHx8IHVucmV2b2tlZFBhaXJzLmhhcyhgJHtpZGVudGl0eX0gJHtyZXZvY2F0aW9uLmlwfWApKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYWlyUmV2b2tlZChpZGVudGl0eTogc3RyaW5nLCBpcDogc3RyaW5nKSB7XG4gICAgZm9yIChsZXQgW3Jldm9jYXRpb25JZCwgcmV2b2NhdGlvbl0gb2YgYWJzb3JiZWRSZXZvY2F0aW9ucykge1xuICAgICAgICBpZiAocmV2b2NhdGlvbi5pZGVudGl0eSA9PT0gaWRlbnRpdHkgJiYgcmV2b2NhdGlvbi5pcCA9PT0gaXAgJiYgIXVucmV2b2tlZElkcy5oYXMocmV2b2NhdGlvbklkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNQYWlyVW5yZXZva2VkKGlkZW50aXR5OiBzdHJpbmcsIGlwOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdW5yZXZva2VkUGFpcnMuaGFzKGAke2lkZW50aXR5fSAke2lwfWApO1xufVxuXG4vKiogRm9yIHdob2V2ZXIganVzdCB3cm90ZSBhIHJldm9jYXRpb24sIHNvIGl0IGhvbGRzIGhlcmUgaW1tZWRpYXRlbHkgcmF0aGVyIHRoYW4gb24gdGhlIG5leHRcbiAgICBhYnNvcmIuIFN0aWNreSBsaWtlIHRoZSByZXN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vdGVSZXZvY2F0aW9uKHJldm9jYXRpb25JZDogc3RyaW5nLCBpZGVudGl0eTogc3RyaW5nLCBpcDogc3RyaW5nKSB7XG4gICAgYWJzb3JiZWRSZXZvY2F0aW9ucy5zZXQocmV2b2NhdGlvbklkLCB7IGlkZW50aXR5LCBpcCB9KTtcbn1cblxuLyoqIEEgcmVwbyB3aG9zZSBzaWduYXR1cmUgZG9lcyBub3QgY2hlY2sgb3V0LCB3aXRoIHRoZSBtZXNzYWdlIHJlYWR5IGZvciB3aG9ldmVyIGFza2VkLiBOb3QgZXZlcnlcbiAgICBjYWxsZXIgdHJlYXRzIGl0IHRoZSBzYW1lIC0gYSBzb3VyY2Uga2VlcHMgaXRzIGxhc3Qga2V5cywgYSBtYWNoaW5lIGxpc3QgaXMganVzdCByZWZ1c2VkIC0gc29cbiAgICB0aGUga2luZCBpcyBjYXJyaWVkIHJhdGhlciB0aGFuIGFjdGVkIG9uIGhlcmUuICovXG5leHBvcnQgY2xhc3MgU2lnbmVkUmVwb0Vycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKHB1YmxpYyBwcm9ibGVtOiBzdHJpbmcsIHB1YmxpYyBoZWFkbGluZTogc3RyaW5nLCBwdWJsaWMgYm9keTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGAke2hlYWRsaW5lfS4gJHtib2R5fWApO1xuICAgIH1cbn1cblxuLyoqIEV2ZXJ5dGhpbmcgYSBzaWduZWQgY2hlY2tvdXQgdm91Y2hlcyBmb3IsIGluIG9uZSBjYWxsOiB3aG8gc2lnbmVkIGl0LCBhbmQgdGhlIGNvbnRlbnRzIG9mIGV2ZXJ5XG4gICAgZmlsZSB0aGUgc2lnbmF0dXJlIGFjdHVhbGx5IGNvdmVycy5cblxuICAgIFVOU0lHTkVEIHdpdGggbm8gZmlsZXMgd2hlbiB0aGVyZSBpcyBubyBzaWduYXR1cmUgYXQgYWxsLiBUaHJvd3MgYSBTaWduZWRSZXBvRXJyb3Igb25seSB3aGVuIHRoZVxuICAgIHNpZ25hdHVyZSBvdmVyIHRoZSBtYW5pZmVzdCBkb2VzIG5vdCBob2xkIHVwLCBzaW5jZSB0aGVuIG5vdGhpbmcgaW4gdGhlIHJlcG8gY2FuIGJlIGJlbGlldmVkIGFuZFxuICAgIHRoZSBjYWxsZXIga2VlcHMgd2hhdGV2ZXIgaXQgbGFzdCBhY2NlcHRlZC5cblxuICAgIEluZGl2aWR1YWwgZmlsZXMgYXJlIGluY2x1ZGVkIG9yIGxlZnQgb3V0IG9uZSBhdCBhIHRpbWUsIGFuZCBhIGZpbGUgYmVpbmcgbGVmdCBvdXQgbmV2ZXIgYWZmZWN0c1xuICAgIHRoZSBvdGhlcnM6IGEgZmlsZSB0aGUgbWFuaWZlc3QgZG9lcyBub3QgbmFtZSwgYSBmaWxlIHdob3NlIGNvbnRlbnRzIG5vIGxvbmdlciBtYXRjaCB3aGF0IHdhc1xuICAgIHNpZ25lZCwgYW5kIGEgZmlsZSB0aGUgbWFuaWZlc3QgbmFtZXMgdGhhdCBpcyBub3Qgb24gZGlzayBhcmUgYWxsIHNpbXBseSBmaWxlcyB3ZSBob2xkIG5vXG4gICAgc2lnbmF0dXJlIGZvci4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkU2lnbmVkUmVwbyhjb25maWc6IHsgcmVwb1BhdGg6IHN0cmluZzsgc291cmNlVVJMOiBzdHJpbmcgfSk6IFByb21pc2U8e1xuICAgIHNpZ25lcjogc3RyaW5nO1xuICAgIG1hbmlmZXN0SGFzaDogc3RyaW5nO1xuICAgIHNpZ25hdHVyZUhhc2g6IHN0cmluZztcbiAgICBmaWxlczogTWFwPHN0cmluZywgQnVmZmVyPjtcbn0+IHtcbiAgICBsZXQgeyByZXBvUGF0aCwgc291cmNlVVJMIH0gPSBjb25maWc7XG4gICAgbGV0IG1hbmlmZXN0Qnl0ZXMgPSBhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4ocmVwb1BhdGgsIE1BTklGRVNUX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBzaWduYXR1cmVCeXRlcyA9IGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgU0lHTkFUVVJFX05BTUUpKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIGxldCBtYW5pZmVzdEhhc2ggPSBtYW5pZmVzdEJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShtYW5pZmVzdEJ5dGVzKS5kaWdlc3QoXCJoZXhcIikgfHwgXCJcIjtcbiAgICBsZXQgc2lnbmF0dXJlSGFzaCA9IHNpZ25hdHVyZUJ5dGVzICYmIGNyeXB0by5jcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShzaWduYXR1cmVCeXRlcykuZGlnZXN0KFwiaGV4XCIpIHx8IFwiXCI7XG5cbiAgICBpZiAoIW1hbmlmZXN0Qnl0ZXMgJiYgIXNpZ25hdHVyZUJ5dGVzKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAke3JlcG9QYXRofSBpcyBub3Qgc2lnbmVkLCBpZ25vcmluZyBhbGwgb2YgaXRzIGZpbGVzYCk7XG4gICAgICAgIHJldHVybiB7IHNpZ25lcjogVU5TSUdORUQsIG1hbmlmZXN0SGFzaCwgc2lnbmF0dXJlSGFzaCwgZmlsZXM6IG5ldyBNYXAoKSB9O1xuICAgIH1cblxuICAgIGxldCBicm9rZW4gPSAoZGV0YWlsOiBzdHJpbmcpID0+IG5ldyBTaWduZWRSZXBvRXJyb3IoXG4gICAgICAgIFwiY29ycnVwdFwiLFxuICAgICAgICBgS0VZIFJFUE8gU0lHTkFUVVJFIElTIEJST0tFTmAsXG4gICAgICAgIGBUaGUgc2lnbmF0dXJlIG9uICR7cmVwb1BhdGh9IGRvZXMgbm90IGNoZWNrIG91dCwgc28gZXZlcnl0aGluZyBpbiBpdCBpcyBiZWluZyBpZ25vcmVkIGFuZGBcbiAgICAgICAgKyBgIHRoaXMgbWFjaGluZSBrZWVwcyB1c2luZyB3aGF0IGl0IGxhc3QgYWNjZXB0ZWQuXFxuXFxuJHtkZXRhaWx9YFxuICAgICAgICArIGBcXG5cXG5UbyByZXBsYWNlIHRoZSBzaWduYXR1cmUsIHJ1biBpbiB0aGF0IHJlcG86XFxuXFxgXFxgXFxgXFxuJHtTSUdOX0NPTU1BTkR9XFxuXFxgXFxgXFxgYFxuICAgICk7XG4gICAgaWYgKCFtYW5pZmVzdEJ5dGVzIHx8ICFzaWduYXR1cmVCeXRlcykge1xuICAgICAgICB0aHJvdyBicm9rZW4oYE9ubHkgb25lIG9mICR7TUFOSUZFU1RfTkFNRX0gYW5kICR7U0lHTkFUVVJFX05BTUV9IGlzIHByZXNlbnQuYCk7XG4gICAgfVxuXG4gICAgbGV0IHNpZ25lcjogc3RyaW5nO1xuICAgIHRyeSB7XG4gICAgICAgIC8vIFRoZSBzaWduYXR1cmUgY292ZXJzIHRoZSBub3JtYWxpc2VkIGJ5dGVzLCBzbyBhIGNoZWNrb3V0IHRoYXQgYXJyaXZlZCB3aXRoIENSTEYgc3RpbGxcbiAgICAgICAgLy8gdmVyaWZpZXMgcmF0aGVyIHRoYW4gbG9va2luZyBsaWtlIHRhbXBlcmluZy5cbiAgICAgICAgc2lnbmVyID0gdmVyaWZ5U1NIU0lHKHtcbiAgICAgICAgICAgIHNpZ25hdHVyZTogc2lnbmF0dXJlQnl0ZXMudG9TdHJpbmcoXCJ1dGY4XCIpLFxuICAgICAgICAgICAgbWVzc2FnZTogbm9ybWFsaXplQ29udGVudChtYW5pZmVzdEJ5dGVzKSxcbiAgICAgICAgICAgIG5hbWVzcGFjZTogU0lHTl9OQU1FU1BBQ0UsXG4gICAgICAgIH0pLnB1YmxpY0tleTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHRocm93IGJyb2tlbihgJHtlfWApO1xuICAgIH1cblxuICAgIC8vIEV2ZXJ5IGZpbGUgb24gZGlzaywgb3RoZXIgdGhhbiBnaXQncyBvd24gZGlyZWN0b3J5IGFuZCB0aGUgdHdvIHNpZ25hdHVyZSBmaWxlcywgd2hpY2ggY2Fubm90XG4gICAgLy8gZGVzY3JpYmUgdGhlbXNlbHZlcy5cbiAgICBsZXQgbGlzdENoZWNrb3V0RmlsZXMgPSBhc3luYyAocHJlZml4Pzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmdbXT4gPT4ge1xuICAgICAgICBsZXQgZm91bmQ6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGZvciAobGV0IGVudHJ5IG9mIGF3YWl0IGZzLnJlYWRkaXIocGF0aC5qb2luKHJlcG9QYXRoLCBwcmVmaXggfHwgXCJcIiksIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkge1xuICAgICAgICAgICAgbGV0IHJlbGF0aXZlUGF0aCA9IHByZWZpeCAmJiBgJHtwcmVmaXh9LyR7ZW50cnkubmFtZX1gIHx8IGVudHJ5Lm5hbWU7XG4gICAgICAgICAgICBpZiAoZW50cnkubmFtZSA9PT0gXCIuZ2l0XCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgaWYgKCFwcmVmaXggJiYgKGVudHJ5Lm5hbWUgPT09IE1BTklGRVNUX05BTUUgfHwgZW50cnkubmFtZSA9PT0gU0lHTkFUVVJFX05BTUUpKSBjb250aW51ZTtcbiAgICAgICAgICAgIGlmIChlbnRyeS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgICAgICAgZm91bmQucHVzaCguLi5hd2FpdCBsaXN0Q2hlY2tvdXRGaWxlcyhyZWxhdGl2ZVBhdGgpKTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvdW5kLnB1c2gocmVsYXRpdmVQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm91bmQuc29ydCgpO1xuICAgIH07XG5cbiAgICBsZXQgbWFuaWZlc3QgPSBKU09OLnBhcnNlKG1hbmlmZXN0Qnl0ZXMudG9TdHJpbmcoXCJ1dGY4XCIpKTtcbiAgICBsZXQgbGlzdGVkID0gbmV3IE1hcDxzdHJpbmcsIHsgc2l6ZTogbnVtYmVyOyBzaGEyNTY6IHN0cmluZyB9PihcbiAgICAgICAgKG1hbmlmZXN0LmZpbGVzIHx8IFtdKS5tYXAoKGZpbGU6IHsgcGF0aDogc3RyaW5nOyBzaXplOiBudW1iZXI7IHNoYTI1Njogc3RyaW5nIH0pID0+IFtmaWxlLnBhdGgsIGZpbGVdKVxuICAgICk7XG5cbiAgICAvLyBBIGZpbGUgY291bnRzIG9ubHkgaWYgdGhlIG1hbmlmZXN0IG5hbWVzIGl0IEFORCBpdHMgY29udGVudHMgc3RpbGwgbWF0Y2guIEFueXRoaW5nIGVsc2UgaXNcbiAgICAvLyBsZWZ0IG91dCwgb25lIGZpbGUgYXQgYSB0aW1lOiBhbiB1bnNpZ25lZCBmaWxlLCBhIGZpbGUgZWRpdGVkIGFmdGVyIHNpZ25pbmcsIGFuZCBhIGZpbGUgdGhlXG4gICAgLy8gbWFuaWZlc3QgbmFtZXMgdGhhdCBpcyBub3QgaGVyZSBhcmUgYWxsIGp1c3QgZmlsZXMgd2UgaGF2ZSBubyBzaWduYXR1cmUgZm9yLiBOb25lIG9mIHRoZW1cbiAgICAvLyBzYXlzIGFueXRoaW5nIGFib3V0IHRoZSBmaWxlcyB0aGF0IERPIG1hdGNoLCBzbyBub25lIG9mIHRoZW0gdGFrZXMgdGhlIHJlc3Qgb2YgdGhlIHJlcG8gZG93blxuICAgIC8vIHdpdGggaXQgLSB0aGUgc2lnbmF0dXJlIG92ZXIgdGhlIG1hbmlmZXN0IGlzIHRoZSBvbmx5IHRoaW5nIHRoYXQgY2FuIGRvIHRoYXQuXG4gICAgbGV0IGZpbGVzID0gbmV3IE1hcDxzdHJpbmcsIEJ1ZmZlcj4oKTtcbiAgICBmb3IgKGxldCBmaWxlUGF0aCBvZiBhd2FpdCBsaXN0Q2hlY2tvdXRGaWxlcygpKSB7XG4gICAgICAgIGxldCBleHBlY3RlZCA9IGxpc3RlZC5nZXQoZmlsZVBhdGgpO1xuICAgICAgICBpZiAoIWV4cGVjdGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0sIGl0IGlzIG5vdCBpbiB0aGUgc2lnbmVkIG1hbmlmZXN0YCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY29udGVudHMgPSBub3JtYWxpemVDb250ZW50KGF3YWl0IGZzLnJlYWRGaWxlKHBhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpKSk7XG4gICAgICAgIGxldCBoYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNvbnRlbnRzKS5kaWdlc3QoXCJoZXhcIik7XG4gICAgICAgIGlmIChjb250ZW50cy5sZW5ndGggIT09IGV4cGVjdGVkLnNpemUgfHwgaGFzaCAhPT0gZXhwZWN0ZWQuc2hhMjU2KSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgICBgSWdub3JpbmcgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0sIGl0IHdhcyBjaGFuZ2VkIGFmdGVyIGl0IHdhcyBzaWduZWQuYFxuICAgICAgICAgICAgICAgICsgYCBSdW4gJHtTSUdOX0NPTU1BTkR9IGluIHRoYXQgcmVwbyB0byBzaWduIGl0IGFzIGl0IG5vdyBpcy5gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgZmlsZXMuc2V0KGZpbGVQYXRoLCBjb250ZW50cyk7XG4gICAgfVxuICAgIGZvciAobGV0IGZpbGVQYXRoIG9mIGxpc3RlZC5rZXlzKCkpIHtcbiAgICAgICAgaWYgKCFmaWxlcy5oYXMoZmlsZVBhdGgpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgJHtwYXRoLmpvaW4ocmVwb1BhdGgsIGZpbGVQYXRoKX0gaXMgaW4gdGhlIHNpZ25lZCBtYW5pZmVzdCwgYnV0IHRoZXJlIGlzIG5vdGhpbmcgaGVyZSB0aGF0IG1hdGNoZXMgaXRgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFic29yYiB0aGUgcmV2b2tlIHJlcG8ncyBmaWxlcyBpbnRvIHRoZSBzdGlja3kgbWFwLiBPbmNlIHNlZW4gYSByZXZvY2F0aW9uIG5ldmVyIGxlYXZlcyBpdCxcbiAgICAvLyBldmVuIGlmIGl0cyBmaWxlIGRpc2FwcGVhcnMgLSB0aGUga2V5IHRoYXQgd3JpdGVzIHJldm9jYXRpb25zIGlzIG9uIGV2ZXJ5IHNlcnZlciwgc28gd2hvZXZlclxuICAgIC8vIHN0b2xlIG9uZSBjb3VsZCBvdGhlcndpc2UgZXJhc2UgdGhlIHJlY29yZCB0aGF0IHNodXQgdGhlbSBvdXQuXG4gICAgbGV0IHJldm9jYXRpb25zRGlyZWN0b3J5ID0gcGF0aC5qb2luKHJldm9rZVJlcG9QYXRoKHNvdXJjZVVSTCksIFJFVk9DQVRJT05TX0RJUik7XG4gICAgZm9yIChsZXQgbmFtZSBvZiAoYXdhaXQgZnMucmVhZGRpcihyZXZvY2F0aW9uc0RpcmVjdG9yeSkuY2F0Y2goKCkgPT4gW10gYXMgc3RyaW5nW10pKS5zb3J0KCkpIHtcbiAgICAgICAgaWYgKCFuYW1lLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShhd2FpdCBmcy5yZWFkRmlsZShwYXRoLmpvaW4ocmV2b2NhdGlvbnNEaXJlY3RvcnksIG5hbWUpLCBcInV0ZjhcIikpO1xuICAgICAgICAgICAgbGV0IGlkZW50aXR5ID0gcGFyc2VkLmZpbmdlcnByaW50IHx8IHBhcnNlZC5tYWNoaW5lSWQ7XG4gICAgICAgICAgICBpZiAoIWlkZW50aXR5KSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgcmV2b2NhdGlvbklkID0gcGFyc2VkLnJldm9jYXRpb25JZCB8fCBuYW1lLnJlcGxhY2UoL1xcLmpzb24kLywgXCJcIik7XG4gICAgICAgICAgICBpZiAoIWFic29yYmVkUmV2b2NhdGlvbnMuaGFzKHJldm9jYXRpb25JZCkpIHtcbiAgICAgICAgICAgICAgICBhYnNvcmJlZFJldm9jYXRpb25zLnNldChyZXZvY2F0aW9uSWQsIHsgaWRlbnRpdHksIGlwOiBwYXJzZWQuaXAgfHwgcGFyc2VkLmF0dGVtcHQ/LmlwIHx8IFwiXCIgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBJZ25vcmluZyB1bnJlYWRhYmxlIHJldm9jYXRpb24gJHtwYXRoLmpvaW4ocmV2b2NhdGlvbnNEaXJlY3RvcnksIG5hbWUpfS4gJHtlfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmVidWlsZCB0aGUgdW5yZXZva2VzIGZyb20gdGhlIHNpZ25lZCBmaWxlcyBqdXN0IHJlYWQuIFVucmV2b2tlcyBhcmUgc2lnbmVkIGNvbnRlbnQsIHNvXG4gICAgLy8gcmVtb3Zpbmcgb25lIG11c3QgdGFrZSBlZmZlY3QsIHVubGlrZSB0aGUgc3RpY2t5IHJldm9jYXRpb25zLlxuICAgIHVucmV2b2tlZFBhaXJzID0gbmV3IFNldCgpO1xuICAgIHVucmV2b2tlZElkcyA9IG5ldyBTZXQoKTtcbiAgICBmb3IgKGxldCBbZmlsZVBhdGgsIGNvbnRlbnRzXSBvZiBmaWxlcykge1xuICAgICAgICBpZiAoIWZpbGVQYXRoLnN0YXJ0c1dpdGgoYCR7VU5SRVZPS0VTX0RJUn0vYCkgfHwgIWZpbGVQYXRoLmVuZHNXaXRoKFwiLmpzb25cIikpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gSlNPTi5wYXJzZShjb250ZW50cy50b1N0cmluZyhcInV0ZjhcIikpO1xuICAgICAgICAgICAgZm9yIChsZXQgYWxsb3dlZCBvZiBwYXJzZWQuYWxsb3dlZCB8fCBbXSkge1xuICAgICAgICAgICAgICAgIGxldCBpZGVudGl0eSA9IGFsbG93ZWQuZmluZ2VycHJpbnQgfHwgYWxsb3dlZC5tYWNoaW5lSWQ7XG4gICAgICAgICAgICAgICAgaWYgKGlkZW50aXR5ICYmIGFsbG93ZWQuaXApIHtcbiAgICAgICAgICAgICAgICAgICAgdW5yZXZva2VkUGFpcnMuYWRkKGAke2lkZW50aXR5fSAke2FsbG93ZWQuaXB9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgcmV2b2NhdGlvbklkIG9mIHBhcnNlZC5yZXZvY2F0aW9uSWRzIHx8IFtdKSB7XG4gICAgICAgICAgICAgICAgdW5yZXZva2VkSWRzLmFkZChyZXZvY2F0aW9uSWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgSWdub3JpbmcgdW5yZWFkYWJsZSB1bnJldm9rZSAke2ZpbGVQYXRofS4gJHtlfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gRHJvcCBldmVyeXRoaW5nIGZyb3plbjogcmV2b2tlZCBrZXlzIG91dCBvZiBhdXRob3JpemVkX2tleXMgYW5kIHRvcCBsZXZlbCAucHViIGZpbGVzLCBhbmRcbiAgICAvLyBmcm96ZW4gbWFjaGluZXMnIGZpbGVzIG91dCBvZiBtYWNoaW5lcy8uIFdoYXQgY29tZXMgYmFjayBpcyB3aGF0IHRoaXMgbWFjaGluZSBhY3R1YWxseVxuICAgIC8vIHRydXN0cywgc28gbm8gY2FsbGVyIGNhbiByZWFkIHRoZSBsaXN0IGFuZCBmb3JnZXQgdGhlIHJldm9jYXRpb25zLlxuICAgIGZvciAobGV0IFtmaWxlUGF0aCwgY29udGVudHNdIG9mIFsuLi5maWxlc10pIHtcbiAgICAgICAgaWYgKGZpbGVQYXRoID09PSBcImF1dGhvcml6ZWRfa2V5c1wiIHx8IChmaWxlUGF0aC5lbmRzV2l0aChcIi5wdWJcIikgJiYgIWZpbGVQYXRoLmluY2x1ZGVzKFwiL1wiKSkpIHtcbiAgICAgICAgICAgIGxldCBsaW5lcyA9IGNvbnRlbnRzLnRvU3RyaW5nKFwidXRmOFwiKS5zcGxpdChcIlxcblwiKTtcbiAgICAgICAgICAgIGxldCBrZXB0ID0gbGluZXMuZmlsdGVyKGxpbmUgPT4ge1xuICAgICAgICAgICAgICAgIGxldCBmaW5nZXJwcmludCA9IGtleUZpbmdlcnByaW50KGxpbmUpO1xuICAgICAgICAgICAgICAgIGlmIChmaW5nZXJwcmludCAmJiBpc0lkZW50aXR5RnJvemVuKGZpbmdlcnByaW50KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgRHJvcHBpbmcgcmV2b2tlZCBrZXkgJHtmaW5nZXJwcmludH0gZnJvbSAke3BhdGguam9pbihyZXBvUGF0aCwgZmlsZVBhdGgpfWApO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAoa2VwdC5sZW5ndGggIT09IGxpbmVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGZpbGVzLnNldChmaWxlUGF0aCwgQnVmZmVyLmZyb20oa2VwdC5qb2luKFwiXFxuXCIpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbGVQYXRoLnN0YXJ0c1dpdGgoXCJtYWNoaW5lcy9cIikgJiYgZmlsZVBhdGguZW5kc1dpdGgoXCIuanNvblwiKSkge1xuICAgICAgICAgICAgbGV0IG1hY2hpbmVJZCA9IGZpbGVQYXRoLnNsaWNlKFwibWFjaGluZXMvXCIubGVuZ3RoLCAtXCIuanNvblwiLmxlbmd0aCk7XG4gICAgICAgICAgICBpZiAoaXNJZGVudGl0eUZyb3plbihtYWNoaW5lSWQpKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coYERyb3BwaW5nIGZyb3plbiBtYWNoaW5lICR7bWFjaGluZUlkfSBmcm9tICR7cGF0aC5qb2luKHJlcG9QYXRoLCBmaWxlUGF0aCl9YCk7XG4gICAgICAgICAgICAgICAgZmlsZXMuZGVsZXRlKGZpbGVQYXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IHNpZ25lciwgbWFuaWZlc3RIYXNoLCBzaWduYXR1cmVIYXNoLCBmaWxlcyB9O1xufVxuIl19
241
+ /* _JS_SOURCE_HASH = "d3acdb6db034d40babc0df2c4f949cd4683a1b30159b8c43a628e0bf4c60fa50"; */
@@ -9,9 +9,9 @@ export declare function isPairUnrevoked(identity: string, ip: string): boolean;
9
9
  /** For whoever just wrote a revocation, so it holds here immediately rather than on the next
10
10
  absorb. Sticky like the rest. */
11
11
  export declare function noteRevocation(revocationId: string, identity: string, ip: string): void;
12
- /** A repo that cannot be trusted, with the message ready for whoever asked. Not every caller
13
- treats these the same - a source keeps its last keys, a machine list is just refused - so the
14
- kind is carried rather than acted on here. */
12
+ /** A repo whose signature does not check out, with the message ready for whoever asked. Not every
13
+ caller treats it the same - a source keeps its last keys, a machine list is just refused - so
14
+ the kind is carried rather than acted on here. */
15
15
  export declare class SignedRepoError extends Error {
16
16
  problem: string;
17
17
  headline: string;
@@ -21,11 +21,14 @@ export declare class SignedRepoError extends Error {
21
21
  /** Everything a signed checkout vouches for, in one call: who signed it, and the contents of every
22
22
  file the signature actually covers.
23
23
 
24
- UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError when a
25
- signature is present but does not hold up, or when a file it signed for was changed or removed
26
- without re-signing - either way the caller keeps whatever it last accepted rather than believing
27
- a repo that no longer matches what was signed. A file not in the manifest is just unsigned, so
28
- it is left out and warned about rather than treated as tampering. */
24
+ UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError only when the
25
+ signature over the manifest does not hold up, since then nothing in the repo can be believed and
26
+ the caller keeps whatever it last accepted.
27
+
28
+ Individual files are included or left out one at a time, and a file being left out never affects
29
+ the others: a file the manifest does not name, a file whose contents no longer match what was
30
+ signed, and a file the manifest names that is not on disk are all simply files we hold no
31
+ signature for. */
29
32
  export declare function readSignedRepo(config: {
30
33
  repoPath: string;
31
34
  sourceURL: string;
@@ -59,9 +59,9 @@ export function noteRevocation(revocationId: string, identity: string, ip: strin
59
59
  absorbedRevocations.set(revocationId, { identity, ip });
60
60
  }
61
61
 
62
- /** A repo that cannot be trusted, with the message ready for whoever asked. Not every caller
63
- treats these the same - a source keeps its last keys, a machine list is just refused - so the
64
- kind is carried rather than acted on here. */
62
+ /** A repo whose signature does not check out, with the message ready for whoever asked. Not every
63
+ caller treats it the same - a source keeps its last keys, a machine list is just refused - so
64
+ the kind is carried rather than acted on here. */
65
65
  export class SignedRepoError extends Error {
66
66
  constructor(public problem: string, public headline: string, public body: string) {
67
67
  super(`${headline}. ${body}`);
@@ -71,11 +71,14 @@ export class SignedRepoError extends Error {
71
71
  /** Everything a signed checkout vouches for, in one call: who signed it, and the contents of every
72
72
  file the signature actually covers.
73
73
 
74
- UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError when a
75
- signature is present but does not hold up, or when a file it signed for was changed or removed
76
- without re-signing - either way the caller keeps whatever it last accepted rather than believing
77
- a repo that no longer matches what was signed. A file not in the manifest is just unsigned, so
78
- it is left out and warned about rather than treated as tampering. */
74
+ UNSIGNED with no files when there is no signature at all. Throws a SignedRepoError only when the
75
+ signature over the manifest does not hold up, since then nothing in the repo can be believed and
76
+ the caller keeps whatever it last accepted.
77
+
78
+ Individual files are included or left out one at a time, and a file being left out never affects
79
+ the others: a file the manifest does not name, a file whose contents no longer match what was
80
+ signed, and a file the manifest names that is not on disk are all simply files we hold no
81
+ signature for. */
79
82
  export async function readSignedRepo(config: { repoPath: string; sourceURL: string }): Promise<{
80
83
  signer: string;
81
84
  manifestHash: string;
@@ -117,13 +120,6 @@ export async function readSignedRepo(config: { repoPath: string; sourceURL: stri
117
120
  throw broken(`${e}`);
118
121
  }
119
122
 
120
- let stale = (detail: string) => new SignedRepoError(
121
- "stale",
122
- `KEY REPO CHANGED WITHOUT BEING SIGNED`,
123
- `${detail}, so the repo is being ignored and this machine keeps using what it last accepted.`
124
- + `\n\nTo make the change take effect, run in that repo:\n\`\`\`\n${SIGN_COMMAND}\n\`\`\``
125
- );
126
-
127
123
  // Every file on disk, other than git's own directory and the two signature files, which cannot
128
124
  // describe themselves.
129
125
  let listCheckoutFiles = async (prefix?: string): Promise<string[]> => {
@@ -146,27 +142,32 @@ export async function readSignedRepo(config: { repoPath: string; sourceURL: stri
146
142
  (manifest.files || []).map((file: { path: string; size: number; sha256: string }) => [file.path, file])
147
143
  );
148
144
 
145
+ // A file counts only if the manifest names it AND its contents still match. Anything else is
146
+ // left out, one file at a time: an unsigned file, a file edited after signing, and a file the
147
+ // manifest names that is not here are all just files we have no signature for. None of them
148
+ // says anything about the files that DO match, so none of them takes the rest of the repo down
149
+ // with it - the signature over the manifest is the only thing that can do that.
149
150
  let files = new Map<string, Buffer>();
150
151
  for (let filePath of await listCheckoutFiles()) {
151
152
  let expected = listed.get(filePath);
152
- // A file the signature never mentioned is not tampering, it is just unsigned - left out
153
- // rather than trusted. An extra file in a working tree is ordinary, so it is only a note.
154
153
  if (!expected) {
155
154
  console.log(`Ignoring ${path.join(repoPath, filePath)}, it is not in the signed manifest`);
156
155
  continue;
157
156
  }
158
157
  let contents = normalizeContent(await fs.readFile(path.join(repoPath, filePath)));
159
158
  let hash = crypto.createHash("sha256").update(contents).digest("hex");
160
- // A file the manifest DOES name, but whose content no longer matches, is a signed file
161
- // changed without re-signing - the repo being edited out from under its signature.
162
159
  if (contents.length !== expected.size || hash !== expected.sha256) {
163
- throw stale(`${path.join(repoPath, filePath)} was changed after it was signed`);
160
+ console.log(
161
+ `Ignoring ${path.join(repoPath, filePath)}, it was changed after it was signed.`
162
+ + ` Run ${SIGN_COMMAND} in that repo to sign it as it now is.`
163
+ );
164
+ continue;
164
165
  }
165
166
  files.set(filePath, contents);
166
167
  }
167
168
  for (let filePath of listed.keys()) {
168
169
  if (!files.has(filePath)) {
169
- throw stale(`${path.join(repoPath, filePath)} is signed for but missing`);
170
+ console.log(`${path.join(repoPath, filePath)} is in the signed manifest, but there is nothing here that matches it`);
170
171
  }
171
172
  }
172
173