sliftutils 1.8.2 → 1.8.4

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 (41) hide show
  1. package/dist/treeSummary.ts.cache +2 -2
  2. package/index.d.ts +19 -0
  3. package/misc/dist/getSecret.ts.cache +2 -2
  4. package/package.json +1 -1
  5. package/security/machines/dist/machines.ts.cache +2 -2
  6. package/storage/dist/ArchivesDisk.ts.cache +2 -2
  7. package/storage/dist/IArchives.ts.cache +2 -2
  8. package/storage/dist/StreamingLogs.ts.cache +2 -2
  9. package/storage/dist/TransactionFile.ts.cache +2 -2
  10. package/storage/dist/archiveHelpers.ts.cache +2 -2
  11. package/storage/dist/backblaze.ts.cache +2 -2
  12. package/storage/proxydatabase/dist/ivfEmbeddingDatabase.ts.cache +17 -5
  13. package/storage/proxydatabase/ivfEmbeddingDatabase.ts +16 -3
  14. package/storage/remoteStorage/createArchives.d.ts +19 -0
  15. package/storage/remoteStorage/createArchives.ts +155 -44
  16. package/storage/remoteStorage/dist/ArchivesDelayed.ts.cache +2 -2
  17. package/storage/remoteStorage/dist/ArchivesRemote.ts.cache +2 -2
  18. package/storage/remoteStorage/dist/ArchivesUrl.ts.cache +2 -2
  19. package/storage/remoteStorage/dist/accessStats.ts.cache +2 -2
  20. package/storage/remoteStorage/dist/blobStore.ts.cache +2 -2
  21. package/storage/remoteStorage/dist/bucketDisk.ts.cache +2 -2
  22. package/storage/remoteStorage/dist/certTrustModal.tsx.cache +2 -2
  23. package/storage/remoteStorage/dist/chainStartup.ts.cache +2 -2
  24. package/storage/remoteStorage/dist/cliArgs.ts.cache +2 -2
  25. package/storage/remoteStorage/dist/createArchives.ts.cache +141 -50
  26. package/storage/remoteStorage/dist/deployTakeover.ts.cache +2 -2
  27. package/storage/remoteStorage/dist/intermediateManagement.ts.cache +2 -2
  28. package/storage/remoteStorage/dist/intermediateSources.ts.cache +2 -2
  29. package/storage/remoteStorage/dist/remoteConfig.ts.cache +2 -2
  30. package/storage/remoteStorage/dist/serverConfig.ts.cache +2 -2
  31. package/storage/remoteStorage/dist/sourceWrapper.ts.cache +2 -2
  32. package/storage/remoteStorage/dist/sourcesList.ts.cache +2 -2
  33. package/storage/remoteStorage/dist/storageClientController.ts.cache +2 -2
  34. package/storage/remoteStorage/dist/storageController.ts.cache +2 -2
  35. package/storage/remoteStorage/dist/storageLogs.ts.cache +2 -2
  36. package/storage/remoteStorage/dist/storageServerState.ts.cache +2 -2
  37. package/storage/remoteStorage/dist/storeConfig.ts.cache +2 -2
  38. package/storage/remoteStorage/dist/storePlan.ts.cache +2 -2
  39. package/storage/remoteStorage/dist/storeSources.ts.cache +2 -2
  40. package/storage/remoteStorage/dist/storeSync.ts.cache +2 -2
  41. package/storage/remoteStorage/dist/validation.ts.cache +2 -2
@@ -40,6 +40,18 @@ function rankCellsByCloseness(embedding, centroids) {
40
40
  ranked.sort((left, right) => right.closeness - left.closeness);
41
41
  return ranked.map(entry => entry.cellId);
42
42
  }
43
+ // Synced functions rerun (and are predicted client-side), so the rebalance roll must be identical on every run of the same call — derive it from the inserted items instead of Math.random(). FNV-1a over each ref plus its embedding hash, mapped to [0, 1).
44
+ function seededRandomFromItems(items) {
45
+ let hash = 2166136261;
46
+ for (const item of items) {
47
+ const key = item.ref + (0, embeddingFormats_1.hashEmbedding)(item.embedding);
48
+ for (let index = 0; index < key.length; index++) {
49
+ hash ^= key.charCodeAt(index);
50
+ hash = Math.imul(hash, 16777619);
51
+ }
52
+ }
53
+ return (hash >>> 0) / 2 ** 32;
54
+ }
43
55
  // Per-write chance of a full rebuild. Zero at/under the target size, then rises (cubically) past it so cells stay roughly between target and ~2x target.
44
56
  function rebalanceProbability(fillRatio) {
45
57
  if (fillRatio <= 1) {
@@ -292,10 +304,10 @@ function insertEmbeddings(database, items) {
292
304
  }
293
305
  }
294
306
  const averageFill = newCount / Math.max(1, centroids.size) / config.cellTargetSize;
295
- if (Math.random() < rebalanceProbability(averageFill)) {
296
- rebuildStructure(database);
307
+ if (seededRandomFromItems(items) < rebalanceProbability(averageFill)) {
308
+ return true;
297
309
  }
298
- return true;
310
+ return false;
299
311
  };
300
312
  if (shouldRegenerate(database)) {
301
313
  rebuildStructure(database);
@@ -382,5 +394,5 @@ function removeEmbeddings(database, refs) {
382
394
  }
383
395
  }
384
396
  exports.removeEmbeddings = removeEmbeddings;
385
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXZmRW1iZWRkaW5nRGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpdmZFbWJlZGRpbmdEYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBMkI7QUFDM0IseUNBQXlEO0FBQ3pELHFEQUFzSTtBQUN0SSwwREFBeUo7QUF5QnpKLE1BQU0sYUFBYSxHQUFHLElBQUksZ0JBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUNuRSxTQUFTLGNBQWMsQ0FBQyxTQUEwQjtJQUM5QyxPQUFPLGFBQWEsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFlLENBQUM7QUFDekQsQ0FBQztBQUNELFNBQVMsY0FBYyxDQUFDLEtBQWlCO0lBQ3JDLE9BQU8sYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQW9CLENBQUM7QUFDMUQsQ0FBQztBQUVELGlHQUFpRztBQUNqRyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUM7QUFDeEIseUpBQXlKO0FBQ3pKLE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQztBQUN2QixxSEFBcUg7QUFDckgsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLENBQUM7QUFDakMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFFL0IsU0FBUyxTQUFTLENBQUMsUUFBb0M7SUFDbkQsT0FBTyxJQUFBLDRCQUFpQixFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBQ0QsU0FBUyxhQUFhLENBQUMsUUFBb0M7SUFDdkQsT0FBTyxJQUFBLDRCQUFpQixFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBQ0QsU0FBUyxT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YUFBYSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUNELEtBQUssTUFBTSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFDNUIsUUFBUSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBQ0QsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDckIsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxHQUFHLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3BGLENBQUM7QUFDTCxDQUFDO0FBaEZELDRDQWdGQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjYm9yeCBmcm9tIFwiY2Jvci14XCI7XG5pbXBvcnQgeyBEYXRhYmFzZSwgbmFtZXNwYWNlRGF0YWJhc2UgfSBmcm9tIFwiLi9EYXRhYmFzZVwiO1xuaW1wb3J0IHsgVHJhbnNhY3Rpb25TZXRTdG9yZSwgdHJhbnNhY3Rpb25SZWFkLCB0cmFuc2FjdGlvbk11dGF0ZSwgdHJhbnNhY3Rpb25EZWxldGUsIHJlcGxheVRyYW5zYWN0aW9uU3RvcmUgfSBmcm9tIFwiLi90cmFuc2FjdGlvblNldFwiO1xuaW1wb3J0IHsgU3RvcmVkRW1iZWRkaW5nLCBFbWJlZGRpbmdGb3JtYXQsIGdldENsb3NlbmVzcywgZW1iZWRkaW5nVG9GbG9hdDMyLCByZWxlYXNlRmxvYXQzMiwgZW5jb2RlRW1iZWRkaW5nLCBoYXNoRW1iZWRkaW5nIH0gZnJvbSBcIi4uL2VtYmVkZGluZ0Zvcm1hdHNcIjtcblxuZXhwb3J0IHR5cGUgSXZmQ29uZmlnID0ge1xuICAgIG1vZGVsOiBzdHJpbmc7XG4gICAgZm9ybWF0OiBFbWJlZGRpbmdGb3JtYXQ7XG4gICAgLy8gVGFyZ2V0IG51bWJlciBvZiBlbWJlZGRpbmdzIHBlciBjZWxsLlxuICAgIGNlbGxUYXJnZXRTaXplOiBudW1iZXI7XG59O1xuXG4vLyBUaWVyZWQgc3RvcmFnZS4gQmVsb3cgRkxBVF9MSU1JVCBlbWJlZGRpbmdzIHRoZSB3aG9sZSBzZXQgbGl2ZXMgaW4gb25lIGZsYXQgdHJhbnNhY3Rpb24gc2V0IChubyBJVkYpOyBvbmNlIGl0IGdyb3dzIHBhc3QgdGhhdCB3ZSBidWlsZCB0aGUgSVZGIChjZW50cm9pZHMgKyBwZXItY2VsbCBzZXRzKSBhbmQgc3RheSB0aGVyZSBmb3JldmVyLiBgY291bnRgIGlzIHRoZSBsaXZlIGVtYmVkZGluZyBjb3VudCAocmUtZGVyaXZlZCBleGFjdGx5IG9uIGEgcmVidWlsZCkuIGBzdGVwc2AgcmVjb3JkcyBvbmUtdGltZSB1cGdyYWRlcyB0aGF0IG11c3QgbmV2ZXIgcmUtcnVuIGV2ZW4gaWYgdGhlIHNldCBsYXRlciBzaHJpbmtzIGFuZCByZWdyb3dzLlxuZXhwb3J0IHR5cGUgSXZmRW1iZWRkaW5nUm9vdCA9IHtcbiAgICBjb25maWc6IEl2ZkNvbmZpZztcbiAgICBjb3VudDogbnVtYmVyO1xuICAgIGZsYXQ6IFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPjtcbiAgICAvLyBEaXJlY3QgcmVmIC0+IGVtYmVkZGluZyBpbmRleC4gRWFjaCBlbnRyeSBpcyBvbmUgQ0JPUiBibG9iIGF0IGl0cyBvd24ga2V5LCBzbyBhIGxvb2t1cCBvciBkZWxldGUgaXMgYSBzaW5nbGUga2V5LXZhbHVlIG9wIChubyB0cmFuc2FjdGlvbi1zZXQgcmVwbGF5KSBhbmQgZGVsZXRlRGF0YSBjYW4gZHJvcCBpdCAoaXQncyBhIHByaW1pdGl2ZSBsZWFmKS4gUmVmcyBhbmQgdGhlaXIgZW1iZWRkaW5ncyBuZXZlciBtb3ZlLCBzbyBhIHJlYnVpbGQgbGVhdmVzIHRoaXMgdW50b3VjaGVkLlxuICAgIGJ5UmVmOiB7IFtyZWY6IHN0cmluZ106IFVpbnQ4QXJyYXkgfTtcbiAgICBzdGVwczogeyBbc3RlcDogc3RyaW5nXTogYm9vbGVhbiB9O1xuICAgIGNlbnRyb2lkczogVHJhbnNhY3Rpb25TZXRTdG9yZTxTdG9yZWRFbWJlZGRpbmc+O1xuICAgIGNlbGxzOiB7IFtjZWxsSWQ6IHN0cmluZ106IFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPiB9O1xufTtcblxuZXhwb3J0IHR5cGUgRW1iZWRkaW5nSW5wdXQgPSB7IHJlZjogc3RyaW5nOyBlbWJlZGRpbmc6IFN0b3JlZEVtYmVkZGluZyB9O1xuZXhwb3J0IHR5cGUgU2VhcmNoSGl0ID0geyByZWY6IHN0cmluZzsgY2xvc2VuZXNzOiBudW1iZXIgfTtcbnR5cGUgQ2VsbEVudHJ5ID0geyByZWY6IHN0cmluZzsgZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcgfTtcblxuY29uc3QgZW1iZWRkaW5nQ2JvciA9IG5ldyBjYm9yeC5FbmNvZGVyKHsgc3RydWN0dXJlZENsb25lOiB0cnVlIH0pO1xuZnVuY3Rpb24gZW5jb2RlUmVmVmFsdWUoZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcpOiBVaW50OEFycmF5IHtcbiAgICByZXR1cm4gZW1iZWRkaW5nQ2Jvci5lbmNvZGUoZW1iZWRkaW5nKSBhcyBVaW50OEFycmF5O1xufVxuZnVuY3Rpb24gZGVjb2RlUmVmVmFsdWUodmFsdWU6IFVpbnQ4QXJyYXkpOiBTdG9yZWRFbWJlZGRpbmcge1xuICAgIHJldHVybiBlbWJlZGRpbmdDYm9yLmRlY29kZSh2YWx1ZSkgYXMgU3RvcmVkRW1iZWRkaW5nO1xufVxuXG4vLyBCZWxvdyB0aGlzIG1hbnkgZW1iZWRkaW5ncyB3ZSBza2lwIHRoZSBJVkYgZW50aXJlbHkgKGZsYXQgc3RvcmUpLiAxMDI0ID0gYSBjbGVhbiBwb3dlciBvZiB0d28uXG5jb25zdCBGTEFUX0xJTUlUID0gMTAyNDtcbi8vIEZvcmNlIGEgZnJvbS1zY3JhdGNoIHJlYnVpbGQgb25jZSBhdCBlYWNoIG9mIHRoZXNlIChtdWx0aXBsZXMgb2YgNCBhYm92ZSBGTEFUX0xJTUlULCB1cCB0byB+MTZrKSwgZ2F0ZWQgYnkgYSBzdGVwIGZsYWcgc28gZWFjaCBydW5zIGF0IG1vc3Qgb25jZSBldmVyLlxuY29uc3QgUkVHRU5FUkFURV9BVCA9IFs0MDk2LCAxNjM4NF07XG5jb25zdCBTVEVQX0lWRiA9IFwiaXZmXCI7XG4vLyBPbiBkZWxldGUsIHRoZSBtZW1iZXIncyBleGFjdCBjZWxsIHBsdXMgdGhpcyBtYW55IG5lYXJieSBjZWxscyBhcmUgY2hlY2tlZCwgaW4gY2FzZSBhIHJlYnVpbGQgbGVmdCBpdCBub24tb3B0aW1hbC5cbmNvbnN0IERFTEVURV9GQUxMQkFDS19DRUxMUyA9IDEwO1xuY29uc3QgUkVCQUxBTkNFX0lURVJBVElPTlMgPSA0O1xuXG5mdW5jdGlvbiBmbGF0U3RvcmUoZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+KTogRGF0YWJhc2U8VHJhbnNhY3Rpb25TZXRTdG9yZTxTdG9yZWRFbWJlZGRpbmc+PiB7XG4gICAgcmV0dXJuIG5hbWVzcGFjZURhdGFiYXNlKGRhdGFiYXNlLCByb290ID0+IHJvb3QuZmxhdCk7XG59XG5mdW5jdGlvbiBjZW50cm9pZFN0b3JlKGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290Pik6IERhdGFiYXNlPFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPj4ge1xuICAgIHJldHVybiBuYW1lc3BhY2VEYXRhYmFzZShkYXRhYmFzZSwgcm9vdCA9PiByb290LmNlbnRyb2lkcyk7XG59XG5mdW5jdGlvbiBjZWxsU3RvcmUoZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LCBjZWxsSWQ6IHN0cmluZyk6IERhdGFiYXNlPFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPj4ge1xuICAgIHJldHVybiBuYW1lc3BhY2VEYXRhYmFzZShkYXRhYmFzZSwgcm9vdCA9PiByb290LmNlbGxzW2NlbGxJZF0pO1xufVxuXG5mdW5jdGlvbiByYW5rQ2VsbHNCeUNsb3NlbmVzcyhlbWJlZGRpbmc6IFN0b3JlZEVtYmVkZGluZywgY2VudHJvaWRzOiBNYXA8c3RyaW5nLCBTdG9yZWRFbWJlZGRpbmc+KTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHJhbmtlZDogeyBjZWxsSWQ6IHN0cmluZzsgY2xvc2VuZXNzOiBudW1iZXIgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBjZWxsSWQgb2YgY2VudHJvaWRzLmtleXMoKSkge1xuICAgICAgICByYW5rZWQucHVzaCh7IGNlbGxJZCwgY2xvc2VuZXNzOiBnZXRDbG9zZW5lc3MoZW1iZWRkaW5nLCBjZW50cm9pZHMuZ2V0KGNlbGxJZCkhKSB9KTtcbiAgICB9XG4gICAgcmFua2VkLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiByaWdodC5jbG9zZW5lc3MgLSBsZWZ0LmNsb3NlbmVzcyk7XG4gICAgcmV0dXJuIHJhbmtlZC5tYXAoZW50cnkgPT4gZW50cnkuY2VsbElkKTtcbn1cblxuLy8gUGVyLXdyaXRlIGNoYW5jZSBvZiBhIGZ1bGwgcmVidWlsZC4gWmVybyBhdC91bmRlciB0aGUgdGFyZ2V0IHNpemUsIHRoZW4gcmlzZXMgKGN1YmljYWxseSkgcGFzdCBpdCBzbyBjZWxscyBzdGF5IHJvdWdobHkgYmV0d2VlbiB0YXJnZXQgYW5kIH4yeCB0YXJnZXQuXG5mdW5jdGlvbiByZWJhbGFuY2VQcm9iYWJpbGl0eShmaWxsUmF0aW86IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGZpbGxSYXRpbyA8PSAxKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjb25zdCBvdmVyID0gZmlsbFJhdGlvIC0gMTtcbiAgICByZXR1cm4gTWF0aC5taW4oMSwgb3ZlciAqIG92ZXIgKiBvdmVyICogMC4yNSk7XG59XG5cbi8vIGstbWVhbnMuIERlY29kZXMgZXZlcnkgbWVtYmVyIHRvIGEgcG9vbGVkIGZsb2F0MzIgYnVmZmVyIE9OQ0UsIHRoZW4gYXNzaWducyB3aXRoIGEgcGxhaW4gaW50ZXJuYWwgZmxvYXQgZG90IChubyBnZXRDbG9zZW5lc3MgY2FsbCDigJQgY29tcGFyaW5nIHR3byBmbG9hdCB2ZWN0b3JzIGlzIHRyaXZpYWwpIGFuZCBrZWVwcyBjZW50cm9pZHMgYXMgZmxvYXQgbWVhbnMsIGVuY29kaW5nIHRoZW0gdG8gU3RvcmVkRW1iZWRkaW5nIG9ubHkgYXQgdGhlIGVuZC4gUmVsZWFzZXMgdGhlIGJvcnJvd2VkIGJ1ZmZlcnMgd2hlbiBkb25lLlxuZnVuY3Rpb24gY2x1c3Rlck1lbWJlcnMobWVtYmVyczogQ2VsbEVudHJ5W10sIGNsdXN0ZXJDb3VudDogbnVtYmVyLCBjb25maWc6IEl2ZkNvbmZpZyk6IHsgY2VudHJvaWQ6IFN0b3JlZEVtYmVkZGluZzsgbWVtYmVyczogQ2VsbEVudHJ5W10gfVtdIHtcbiAgICBjb25zdCBtZW1iZXJGbG9hdHM6IEZsb2F0MzJBcnJheVtdID0gW107XG4gICAgZm9yIChjb25zdCBtZW1iZXIgb2YgbWVtYmVycykge1xuICAgICAgICBtZW1iZXJGbG9hdHMucHVzaChlbWJlZGRpbmdUb0Zsb2F0MzIobWVtYmVyLmVtYmVkZGluZywgdHJ1ZSkpO1xuICAgIH1cbiAgICBjb25zdCBsZW5ndGggPSBtZW1iZXJGbG9hdHMubGVuZ3RoID8gbWVtYmVyRmxvYXRzWzBdLmxlbmd0aCA6IDA7XG4gICAgbGV0IGNlbnRyb2lkczogRmxvYXQzMkFycmF5W10gPSBbXTtcbiAgICBjb25zdCBzZWVkU3RlcCA9IG1lbWJlcnMubGVuZ3RoIC8gY2x1c3RlckNvdW50O1xuICAgIGZvciAobGV0IGNsdXN0ZXJJbmRleCA9IDA7IGNsdXN0ZXJJbmRleCA8IGNsdXN0ZXJDb3VudDsgY2x1c3RlckluZGV4KyspIHtcbiAgICAgICAgY2VudHJvaWRzLnB1c2gobmV3IEZsb2F0MzJBcnJheShtZW1iZXJGbG9hdHNbTWF0aC5mbG9vcihjbHVzdGVySW5kZXggKiBzZWVkU3RlcCldKSk7XG4gICAgfVxuICAgIGxldCBncm91cHM6IG51bWJlcltdW10gPSBbXTtcbiAgICBmb3IgKGxldCBpdGVyYXRpb24gPSAwOyBpdGVyYXRpb24gPCBSRUJBTEFOQ0VfSVRFUkFUSU9OUzsgaXRlcmF0aW9uKyspIHtcbiAgICAgICAgZ3JvdXBzID0gW107XG4gICAgICAgIGZvciAobGV0IGNsdXN0ZXJJbmRleCA9IDA7IGNsdXN0ZXJJbmRleCA8IGNlbnRyb2lkcy5sZW5ndGg7IGNsdXN0ZXJJbmRleCsrKSB7XG4gICAgICAgICAgICBncm91cHMucHVzaChbXSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgbWVtYmVySW5kZXggPSAwOyBtZW1iZXJJbmRleCA8IG1lbWJlckZsb2F0cy5sZW5ndGg7IG1lbWJlckluZGV4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IG1lbWJlckZsb2F0ID0gbWVtYmVyRmxvYXRzW21lbWJlckluZGV4XTtcbiAgICAgICAgICAgIGxldCBiZXN0SW5kZXggPSAwO1xuICAgICAgICAgICAgbGV0IGJlc3REb3QgPSAtSW5maW5pdHk7XG4gICAgICAgICAgICBmb3IgKGxldCBjZW50cm9pZEluZGV4ID0gMDsgY2VudHJvaWRJbmRleCA8IGNlbnRyb2lkcy5sZW5ndGg7IGNlbnRyb2lkSW5kZXgrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRyb2lkRmxvYXQgPSBjZW50cm9pZHNbY2VudHJvaWRJbmRleF07XG4gICAgICAgICAgICAgICAgbGV0IGRvdCA9IDA7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgbGVuZ3RoOyBkaW0rKykge1xuICAgICAgICAgICAgICAgICAgICBkb3QgKz0gbWVtYmVyRmxvYXRbZGltXSAqIGNlbnRyb2lkRmxvYXRbZGltXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRvdCA+IGJlc3REb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgYmVzdERvdCA9IGRvdDtcbiAgICAgICAgICAgICAgICAgICAgYmVzdEluZGV4ID0gY2VudHJvaWRJbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBncm91cHNbYmVzdEluZGV4XS5wdXNoKG1lbWJlckluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXh0Q2VudHJvaWRzOiBGbG9hdDMyQXJyYXlbXSA9IFtdO1xuICAgICAgICBjb25zdCBuZXh0R3JvdXBzOiBudW1iZXJbXVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgZ3JvdXBzKSB7XG4gICAgICAgICAgICBpZiAoIWdyb3VwLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWVhbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbWVtYmVySW5kZXggb2YgZ3JvdXApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtZW1iZXJGbG9hdCA9IG1lbWJlckZsb2F0c1ttZW1iZXJJbmRleF07XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgbGVuZ3RoOyBkaW0rKykge1xuICAgICAgICAgICAgICAgICAgICBtZWFuW2RpbV0gKz0gbWVtYmVyRmxvYXRbZGltXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbm9ybSA9IDA7XG4gICAgICAgICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBsZW5ndGg7IGRpbSsrKSB7XG4gICAgICAgICAgICAgICAgbm9ybSArPSBtZWFuW2RpbV0gKiBtZWFuW2RpbV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtYWduaXR1ZGUgPSBNYXRoLnNxcnQobm9ybSkgfHwgMTtcbiAgICAgICAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGxlbmd0aDsgZGltKyspIHtcbiAgICAgICAgICAgICAgICBtZWFuW2RpbV0gLz0gbWFnbml0dWRlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV4dENlbnRyb2lkcy5wdXNoKG1lYW4pO1xuICAgICAgICAgICAgbmV4dEdyb3Vwcy5wdXNoKGdyb3VwKTtcbiAgICAgICAgfVxuICAgICAgICBjZW50cm9pZHMgPSBuZXh0Q2VudHJvaWRzO1xuICAgICAgICBncm91cHMgPSBuZXh0R3JvdXBzO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQ6IHsgY2VudHJvaWQ6IFN0b3JlZEVtYmVkZGluZzsgbWVtYmVyczogQ2VsbEVudHJ5W10gfVtdID0gW107XG4gICAgZm9yIChsZXQgY2x1c3RlckluZGV4ID0gMDsgY2x1c3RlckluZGV4IDwgY2VudHJvaWRzLmxlbmd0aDsgY2x1c3RlckluZGV4KyspIHtcbiAgICAgICAgY29uc3QgY2VudHJvaWQgPSBlbmNvZGVFbWJlZGRpbmcoeyBpbnB1dDogY2VudHJvaWRzW2NsdXN0ZXJJbmRleF0sIGZvcm1hdDogY29uZmlnLmZvcm1hdCwgbW9kZWw6IGNvbmZpZy5tb2RlbCB9KTtcbiAgICAgICAgY29uc3QgY2VsbE1lbWJlcnM6IENlbGxFbnRyeVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgbWVtYmVySW5kZXggb2YgZ3JvdXBzW2NsdXN0ZXJJbmRleF0pIHtcbiAgICAgICAgICAgIGNlbGxNZW1iZXJzLnB1c2gobWVtYmVyc1ttZW1iZXJJbmRleF0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5wdXNoKHsgY2VudHJvaWQsIG1lbWJlcnM6IGNlbGxNZW1iZXJzIH0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG1lbWJlckZsb2F0IG9mIG1lbWJlckZsb2F0cykge1xuICAgICAgICByZWxlYXNlRmxvYXQzMihtZW1iZXJGbG9hdCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIFJlLWNsdXN0ZXIgRVZFUlkgZW1iZWRkaW5nIChmbGF0IHRpZXIgKyBhbGwgY2VsbHMpIGludG8gYSBmcmVzaCBJVkYsIGNsZWFyIHRoZSBmbGF0IHRpZXIsIGFuZCBtYXJrIElWRiBtb2RlLiBUaGlzIGlzIHRoZSByZWFycmFuZ2VyOiBydW4gcHJvYmFiaWxpc3RpY2FsbHkgYXMgdGhlIHNldCBncm93cywgb25jZSBhdCBlYWNoIHJlZ2VuZXJhdGUgdGhyZXNob2xkLCBhbmQgb25jZSB0byB1cGdyYWRlIGZyb20gZmxhdC4gUmVhZHMgZXZlcnl0aGluZyBpdCB1c2VzLCBzbyBpdCBiYWlscyAoZG9lcyBub3RoaW5nKSBpZiBhbnl0aGluZyBpc24ndCBzeW5jZWQgYW5kIHRoZSBjYWxsZXIncyByZXRyeSByZS1ydW5zIGl0OyBubyBjYWxsZXIgY2FyZXMgYWJvdXQgaXRzIHJlc3VsdC5cbmV4cG9ydCBmdW5jdGlvbiByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290Pik6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb25maWcpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm47XG4gICAgY29uc3Qgc3RlcHMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpO1xuICAgIGlmICghc3RlcHMpIHJldHVybjtcblxuICAgIGNvbnN0IGFsbE1lbWJlcnM6IENlbGxFbnRyeVtdID0gW107XG4gICAgLy8gT25seSB0aGUgb25lLXRpbWUgZmxhdC0+SVZGIHVwZ3JhZGUgcHVsbHMgZnJvbSB0aGUgZmxhdCB0aWVyLiBPbmNlIFNURVBfSVZGIGlzIHNldCB0aGUgZmxhdCBkYXRhIGhhcyBhbHJlYWR5IGJlZW4gZm9sZGVkIGludG8gY2VsbHMsIHNvIGxhdGVyIHJlYnVpbGRzIGlnbm9yZSBpdC4gSXQncyBsZWZ0IGluIHBsYWNlLCBuZXZlciBkZWxldGVkOiBkZWxldGVEYXRhIG9ubHkgcmVtb3ZlcyBwcmltaXRpdmUgbGVhdmVzLCBub3QgYSB3aG9sZSBzdG9yZSwgYW5kIHRoZSBmbGF0IHRpZXIgaXMgc21hbGwgZW5vdWdoIG5vdCB0byBtYXR0ZXIuXG4gICAgaWYgKCFzdGVwc1tTVEVQX0lWRl0pIHtcbiAgICAgICAgY29uc3QgZmxhdCA9IHRyYW5zYWN0aW9uUmVhZChmbGF0U3RvcmUoZGF0YWJhc2UpKTtcbiAgICAgICAgaWYgKCFmbGF0KSByZXR1cm47XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIGZsYXQua2V5cygpKSB7XG4gICAgICAgICAgICBhbGxNZW1iZXJzLnB1c2goeyByZWYsIGVtYmVkZGluZzogZmxhdC5nZXQocmVmKSEgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuO1xuICAgIGNvbnN0IG9sZENlbGxJZHMgPSBBcnJheS5mcm9tKGNlbnRyb2lkcy5rZXlzKCkpO1xuICAgIGNvbnN0IGNlbGxTdG9yZXMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IG9sZENlbGxJZHMubWFwKGNlbGxJZCA9PiByb290LmNlbGxzW2NlbGxJZF0pKTtcbiAgICBpZiAoIWNlbGxTdG9yZXMpIHJldHVybjtcbiAgICBmb3IgKGNvbnN0IHN0b3JlIG9mIGNlbGxTdG9yZXMpIHtcbiAgICAgICAgY29uc3QgbWVtYmVycyA9IHJlcGxheVRyYW5zYWN0aW9uU3RvcmU8U3RvcmVkRW1iZWRkaW5nPihzdG9yZSk7XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIG1lbWJlcnMua2V5cygpKSB7XG4gICAgICAgICAgICBhbGxNZW1iZXJzLnB1c2goeyByZWYsIGVtYmVkZGluZzogbWVtYmVycy5nZXQocmVmKSEgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFhbGxNZW1iZXJzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3QgY2x1c3RlckNvdW50ID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChhbGxNZW1iZXJzLmxlbmd0aCAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZSkpO1xuICAgIGNvbnN0IGNsdXN0ZXJzID0gY2x1c3Rlck1lbWJlcnMoYWxsTWVtYmVycywgY2x1c3RlckNvdW50LCBjb25maWcpO1xuXG4gICAgY29uc3QgbmV3Q2VsbElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGNlbnRyb2lkV3JpdGVzOiB7IGtleTogc3RyaW5nOyB2YWx1ZTogU3RvcmVkRW1iZWRkaW5nIHwgdW5kZWZpbmVkIH1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2x1c3RlciBvZiBjbHVzdGVycykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSBoYXNoRW1iZWRkaW5nKGNsdXN0ZXIuY2VudHJvaWQpO1xuICAgICAgICBuZXdDZWxsSWRzLmFkZChjZWxsSWQpO1xuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBjZWxsSWQsIHZhbHVlOiBjbHVzdGVyLmNlbnRyb2lkIH0pO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBjbHVzdGVyLm1lbWJlcnMubWFwKG1lbWJlciA9PiAoeyBrZXk6IG1lbWJlci5yZWYsIHZhbHVlOiBtZW1iZXIuZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoY2VsbFN0b3JlKGRhdGFiYXNlLCBjZWxsSWQpLCBtZW1iZXJXcml0ZXMpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG9sZENlbGxJZCBvZiBvbGRDZWxsSWRzKSB7XG4gICAgICAgIGlmIChuZXdDZWxsSWRzLmhhcyhvbGRDZWxsSWQpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBvbGRDZWxsSWQsIHZhbHVlOiB1bmRlZmluZWQgfSk7XG4gICAgICAgIHRyYW5zYWN0aW9uRGVsZXRlKGNlbGxTdG9yZShkYXRhYmFzZSwgb2xkQ2VsbElkKSk7XG4gICAgfVxuICAgIHRyYW5zYWN0aW9uTXV0YXRlKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpLCBjZW50cm9pZFdyaXRlcyk7XG4gICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgYWxsTWVtYmVycy5sZW5ndGgpO1xuICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3Quc3RlcHNbU1RFUF9JVkZdLCB0cnVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlYXJjaEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIHF1ZXJ5OiBTdG9yZWRFbWJlZGRpbmcsXG4gICAgb3B0aW9uczogeyBwcm9iZUJ1ZGdldDogbnVtYmVyOyByZXN1bHRDb3VudDogbnVtYmVyIH0sXG4pOiBTZWFyY2hIaXRbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY29uZmlnID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByb290LmNvbmZpZyk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc3RlcHMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpO1xuICAgIGlmICghc3RlcHMpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBoaXRzOiBTZWFyY2hIaXRbXSA9IFtdO1xuICAgIGlmICghc3RlcHNbU1RFUF9JVkZdKSB7XG4gICAgICAgIGNvbnN0IGZsYXQgPSB0cmFuc2FjdGlvblJlYWQoZmxhdFN0b3JlKGRhdGFiYXNlKSk7XG4gICAgICAgIGlmICghZmxhdCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCByZWYgb2YgZmxhdC5rZXlzKCkpIHtcbiAgICAgICAgICAgIGhpdHMucHVzaCh7IHJlZiwgY2xvc2VuZXNzOiBnZXRDbG9zZW5lc3MocXVlcnksIGZsYXQuZ2V0KHJlZikhKSB9KTtcbiAgICAgICAgfVxuICAgICAgICBoaXRzLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiByaWdodC5jbG9zZW5lc3MgLSBsZWZ0LmNsb3NlbmVzcyk7XG4gICAgICAgIHJldHVybiBoaXRzLnNsaWNlKDAsIG9wdGlvbnMucmVzdWx0Q291bnQpO1xuICAgIH1cblxuICAgIGNvbnN0IGNlbnRyb2lkcyA9IHRyYW5zYWN0aW9uUmVhZChjZW50cm9pZFN0b3JlKGRhdGFiYXNlKSk7XG4gICAgaWYgKCFjZW50cm9pZHMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFjZW50cm9pZHMuc2l6ZSkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IHByb2JlQ2VsbENvdW50ID0gTWF0aC5tYXgoMSwgTWF0aC5jZWlsKG9wdGlvbnMucHJvYmVCdWRnZXQgLyBjb25maWcuY2VsbFRhcmdldFNpemUpKTtcbiAgICBjb25zdCBwcm9iZUNlbGxJZHMgPSByYW5rQ2VsbHNCeUNsb3NlbmVzcyhxdWVyeSwgY2VudHJvaWRzKS5zbGljZSgwLCBwcm9iZUNlbGxDb3VudCk7XG4gICAgY29uc3Qgc3RvcmVzID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiBwcm9iZUNlbGxJZHMubWFwKGNlbGxJZCA9PiByb290LmNlbGxzW2NlbGxJZF0pKTtcbiAgICBpZiAoIXN0b3JlcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBmb3IgKGNvbnN0IHN0b3JlIG9mIHN0b3Jlcykge1xuICAgICAgICBjb25zdCBtZW1iZXJzID0gcmVwbGF5VHJhbnNhY3Rpb25TdG9yZTxTdG9yZWRFbWJlZGRpbmc+KHN0b3JlKTtcbiAgICAgICAgZm9yIChjb25zdCByZWYgb2YgbWVtYmVycy5rZXlzKCkpIHtcbiAgICAgICAgICAgIGhpdHMucHVzaCh7IHJlZiwgY2xvc2VuZXNzOiBnZXRDbG9zZW5lc3MocXVlcnksIG1lbWJlcnMuZ2V0KHJlZikhKSB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoaXRzLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiByaWdodC5jbG9zZW5lc3MgLSBsZWZ0LmNsb3NlbmVzcyk7XG4gICAgcmV0dXJuIGhpdHMuc2xpY2UoMCwgb3B0aW9ucy5yZXN1bHRDb3VudCk7XG59XG5cbi8vIERpcmVjdCByZWYgLT4gc3RvcmVkIGVtYmVkZGluZyBsb29rdXAgdGhyb3VnaCB0aGUgYnlSZWYgaW5kZXg6IG9uZSBrZXktdmFsdWUgcmVhZCBwZXIgcmVmLCBubyBjZWxsIHNjYW4uIEEgc2VhcmNoIHJldHVybnMgcmVmczsgdGhpcyBmZXRjaGVzIHRoZSBkYXRhIGJlaGluZCB0aGVtLiBTa2lwcyByZWZzIHRoYXQgYXJlbid0IHByZXNlbnQ7IHVuZGVmaW5lZCBpZiBub3Qgc3luY2VkLlxuZXhwb3J0IGZ1bmN0aW9uIGxvb2t1cEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIHJlZnM6IHN0cmluZ1tdLFxuKTogTWFwPHN0cmluZywgU3RvcmVkRW1iZWRkaW5nPiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdmFsdWVzID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByZWZzLm1hcChyZWYgPT4gcm9vdC5ieVJlZltyZWZdKSk7XG4gICAgaWYgKCF2YWx1ZXMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcDxzdHJpbmcsIFN0b3JlZEVtYmVkZGluZz4oKTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcmVmcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJlc3VsdC5zZXQocmVmc1tpbmRleF0sIGRlY29kZVJlZlZhbHVlKHZhbHVlKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIGl0ZW1zOiBFbWJlZGRpbmdJbnB1dFtdLFxuKSB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBjb25maWcgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3QuY29uZmlnKTtcbiAgICBjb25zdCBzdGVwcyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5zdGVwcyk7XG4gICAgbGV0IGNvdW50ID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByb290LmNvdW50KTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuO1xuICAgIGlmICghc3RlcHMpIHJldHVybjtcbiAgICBpZiAoY291bnQgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgIGNvbnN0IG5ld0NvdW50ID0gY291bnQgKyBpdGVtcy5sZW5ndGg7XG5cbiAgICBpZiAoIXN0ZXBzW1NURVBfSVZGXSkge1xuICAgICAgICBjb25zdCBmbGF0V3JpdGVzID0gaXRlbXMubWFwKGl0ZW0gPT4gKHsga2V5OiBpdGVtLnJlZiwgdmFsdWU6IGl0ZW0uZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoZmxhdFN0b3JlKGRhdGFiYXNlKSwgZmxhdFdyaXRlcyk7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICAgICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5ieVJlZltpdGVtLnJlZl0sIGVuY29kZVJlZlZhbHVlKGl0ZW0uZW1iZWRkaW5nKSk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgbmV3Q291bnQpO1xuICAgICAgICBpZiAobmV3Q291bnQgPiBGTEFUX0xJTUlUKSB7XG4gICAgICAgICAgICByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBpdGVtc0J5Q2VsbCA9IG5ldyBNYXA8c3RyaW5nLCBFbWJlZGRpbmdJbnB1dFtdPigpO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSByYW5rQ2VsbHNCeUNsb3NlbmVzcyhpdGVtLmVtYmVkZGluZywgY2VudHJvaWRzKVswXTtcbiAgICAgICAgbGV0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgIGlmICghZ3JvdXApIHtcbiAgICAgICAgICAgIGdyb3VwID0gW107XG4gICAgICAgICAgICBpdGVtc0J5Q2VsbC5zZXQoY2VsbElkLCBncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgZ3JvdXAucHVzaChpdGVtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBjZWxsSWQgb2YgaXRlbXNCeUNlbGwua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCkhO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBncm91cC5tYXAoaXRlbSA9PiAoeyBrZXk6IGl0ZW0ucmVmLCB2YWx1ZTogaXRlbS5lbWJlZGRpbmcgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShjZWxsU3RvcmUoZGF0YWJhc2UsIGNlbGxJZCksIG1lbWJlcldyaXRlcyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBkYXRhYmFzZS53cml0ZURhdGEocm9vdCA9PiByb290LmJ5UmVmW2l0ZW0ucmVmXSwgZW5jb2RlUmVmVmFsdWUoaXRlbS5lbWJlZGRpbmcpKTtcbiAgICB9XG4gICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgbmV3Q291bnQpO1xuXG5cbiAgICBjb25zdCBzaG91bGRSZWdlbmVyYXRlID0gKGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290PikgPT4ge1xuICAgICAgICBsZXQgc3RlcHMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpO1xuICAgICAgICBpZiAoIXN0ZXBzKSByZXR1cm47XG4gICAgICAgIGZvciAoY29uc3QgdGhyZXNob2xkIG9mIFJFR0VORVJBVEVfQVQpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0ZXBOYW1lID0gXCJyZWdlblwiICsgdGhyZXNob2xkO1xuICAgICAgICAgICAgaWYgKCFzdGVwc1tzdGVwTmFtZV0gJiYgbmV3Q291bnQgPiB0aHJlc2hvbGQpIHtcbiAgICAgICAgICAgICAgICBkYXRhYmFzZS53cml0ZURhdGEocm9vdCA9PiByb290LnN0ZXBzW3N0ZXBOYW1lXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXZlcmFnZUZpbGwgPSBuZXdDb3VudCAvIE1hdGgubWF4KDEsIGNlbnRyb2lkcy5zaXplKSAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZTtcbiAgICAgICAgaWYgKE1hdGgucmFuZG9tKCkgPCByZWJhbGFuY2VQcm9iYWJpbGl0eShhdmVyYWdlRmlsbCkpIHtcbiAgICAgICAgICAgIHJlYnVpbGRTdHJ1Y3R1cmUoZGF0YWJhc2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgaWYgKHNob3VsZFJlZ2VuZXJhdGUoZGF0YWJhc2UpKSB7XG4gICAgICAgIHJlYnVpbGRTdHJ1Y3R1cmUoZGF0YWJhc2UpO1xuICAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlbW92ZUVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIHJlZnM6IHN0cmluZ1tdLFxuKSB7XG4gICAgaWYgKCFyZWZzLmxlbmd0aCkgcmV0dXJuO1xuICAgIGNvbnN0IHN0ZXBzID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByb290LnN0ZXBzKTtcbiAgICBjb25zdCBjb3VudCA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb3VudCk7XG4gICAgaWYgKCFzdGVwcykgcmV0dXJuO1xuICAgIGlmIChjb3VudCA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICBpZiAoIXN0ZXBzW1NURVBfSVZGXSkge1xuICAgICAgICBjb25zdCBmbGF0RGVsZXRlcyA9IHJlZnMubWFwKHJlZiA9PiAoeyBrZXk6IHJlZiwgdmFsdWU6IHVuZGVmaW5lZCB9KSk7XG4gICAgICAgIHRyYW5zYWN0aW9uTXV0YXRlKGZsYXRTdG9yZShkYXRhYmFzZSksIGZsYXREZWxldGVzKTtcbiAgICAgICAgZm9yIChjb25zdCByZWYgb2YgcmVmcykge1xuICAgICAgICAgICAgZGF0YWJhc2UuZGVsZXRlRGF0YShyb290ID0+IHJvb3QuYnlSZWZbcmVmXSk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgTWF0aC5tYXgoMCwgY291bnQgLSByZWZzLmxlbmd0aCkpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuO1xuICAgIGlmICghY2VudHJvaWRzLnNpemUpIHJldHVybjtcblxuICAgIC8vIExvb2sgdXAgZWFjaCByZWYncyBlbWJlZGRpbmcgdGhyb3VnaCBieVJlZiwgdGhlbiByYW5rIGl0cyBjZWxscyB0aGUgd2F5IGFuIGluc2VydCB3b3VsZCwgc28gd2UgZGVsZXRlIGZyb20gdGhlIGNlbGwgaXQgYWN0dWFsbHkgbGFuZGVkIGluIChwbHVzIGEgZmV3IG5laWdoYm91cnMsIGluIGNhc2UgYSByZWJ1aWxkIG51ZGdlZCBpdCBhY3Jvc3MgYSBib3VuZGFyeSkuXG4gICAgY29uc3QgcmVmVmFsdWVzID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByZWZzLm1hcChyZWYgPT4gcm9vdC5ieVJlZltyZWZdKSk7XG4gICAgaWYgKCFyZWZWYWx1ZXMpIHJldHVybjtcbiAgICBjb25zdCBjYW5kaWRhdGVzQnlJdGVtOiB7IHJlZjogc3RyaW5nOyBjZWxsSWRzOiBzdHJpbmdbXSB9W10gPSBbXTtcbiAgICBjb25zdCBjYW5kaWRhdGVTZXQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcmVmcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSByZWZWYWx1ZXNbaW5kZXhdO1xuICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlbWJlZGRpbmcgPSBkZWNvZGVSZWZWYWx1ZSh2YWx1ZSk7XG4gICAgICAgIGNvbnN0IGNlbGxJZHMgPSByYW5rQ2VsbHNCeUNsb3NlbmVzcyhlbWJlZGRpbmcsIGNlbnRyb2lkcykuc2xpY2UoMCwgMSArIERFTEVURV9GQUxMQkFDS19DRUxMUyk7XG4gICAgICAgIGNhbmRpZGF0ZXNCeUl0ZW0ucHVzaCh7IHJlZjogcmVmc1tpbmRleF0sIGNlbGxJZHMgfSk7XG4gICAgICAgIGZvciAoY29uc3QgY2VsbElkIG9mIGNlbGxJZHMpIHtcbiAgICAgICAgICAgIGNhbmRpZGF0ZVNldC5hZGQoY2VsbElkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGNhbmRpZGF0ZUNlbGxJZHMgPSBBcnJheS5mcm9tKGNhbmRpZGF0ZVNldCk7XG4gICAgY29uc3Qgc3RvcmVzID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiBjYW5kaWRhdGVDZWxsSWRzLm1hcChjZWxsSWQgPT4gcm9vdC5jZWxsc1tjZWxsSWRdKSk7XG4gICAgaWYgKCFzdG9yZXMpIHJldHVybjtcbiAgICBjb25zdCBtZW1iZXJzQnlDZWxsID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIFN0b3JlZEVtYmVkZGluZz4+KCk7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGNhbmRpZGF0ZUNlbGxJZHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIG1lbWJlcnNCeUNlbGwuc2V0KGNhbmRpZGF0ZUNlbGxJZHNbaW5kZXhdLCByZXBsYXlUcmFuc2FjdGlvblN0b3JlKHN0b3Jlc1tpbmRleF0pKTtcbiAgICB9XG5cbiAgICBjb25zdCBkZWxldGVzQnlDZWxsID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZ1tdPigpO1xuICAgIGNvbnN0IGRlbGV0ZWRSZWZzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXNCeUl0ZW0pIHtcbiAgICAgICAgZm9yIChjb25zdCBjZWxsSWQgb2YgY2FuZGlkYXRlLmNlbGxJZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IG1lbWJlcnMgPSBtZW1iZXJzQnlDZWxsLmdldChjZWxsSWQpO1xuICAgICAgICAgICAgaWYgKCFtZW1iZXJzIHx8ICFtZW1iZXJzLmhhcyhjYW5kaWRhdGUucmVmKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGNlbGxSZWZzID0gZGVsZXRlc0J5Q2VsbC5nZXQoY2VsbElkKTtcbiAgICAgICAgICAgIGlmICghY2VsbFJlZnMpIHtcbiAgICAgICAgICAgICAgICBjZWxsUmVmcyA9IFtdO1xuICAgICAgICAgICAgICAgIGRlbGV0ZXNCeUNlbGwuc2V0KGNlbGxJZCwgY2VsbFJlZnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2VsbFJlZnMucHVzaChjYW5kaWRhdGUucmVmKTtcbiAgICAgICAgICAgIGRlbGV0ZWRSZWZzLnB1c2goY2FuZGlkYXRlLnJlZik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2VsbElkIG9mIGRlbGV0ZXNCeUNlbGwua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IGNlbGxSZWZzID0gZGVsZXRlc0J5Q2VsbC5nZXQoY2VsbElkKSE7XG4gICAgICAgIGNvbnN0IG1lbWJlckRlbGV0ZXMgPSBjZWxsUmVmcy5tYXAocmVmID0+ICh7IGtleTogcmVmLCB2YWx1ZTogdW5kZWZpbmVkIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoY2VsbFN0b3JlKGRhdGFiYXNlLCBjZWxsSWQpLCBtZW1iZXJEZWxldGVzKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCByZWYgb2YgZGVsZXRlZFJlZnMpIHtcbiAgICAgICAgZGF0YWJhc2UuZGVsZXRlRGF0YShyb290ID0+IHJvb3QuYnlSZWZbcmVmXSk7XG4gICAgfVxuICAgIGlmIChkZWxldGVkUmVmcy5sZW5ndGgpIHtcbiAgICAgICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgTWF0aC5tYXgoMCwgY291bnQgLSBkZWxldGVkUmVmcy5sZW5ndGgpKTtcbiAgICB9XG59XG4iXX0=
386
- /* _JS_SOURCE_HASH = "70f29b37ecb31f18faad5b811c7545265a305feca4b9b3397ebf45fe143c3929"; */
397
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXZmRW1iZWRkaW5nRGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpdmZFbWJlZGRpbmdEYXRhYmFzZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBMkI7QUFDM0IseUNBQXlEO0FBQ3pELHFEQUFzSTtBQUN0SSwwREFBeUo7QUF5QnpKLE1BQU0sYUFBYSxHQUFHLElBQUksZ0JBQUssQ0FBQyxPQUFPLENBQUMsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUNuRSxTQUFTLGNBQWMsQ0FBQyxTQUEwQjtJQUM5QyxPQUFPLGFBQWEsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFlLENBQUM7QUFDekQsQ0FBQztBQUNELFNBQVMsY0FBYyxDQUFDLEtBQWlCO0lBQ3JDLE9BQU8sYUFBYSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQW9CLENBQUM7QUFDMUQsQ0FBQztBQUVELGlHQUFpRztBQUNqRyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUM7QUFDeEIseUpBQXlKO0FBQ3pKLE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQztBQUN2QixxSEFBcUg7QUFDckgsTUFBTSxxQkFBcUIsR0FBRyxFQUFFLENBQUM7QUFDakMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7QUFFL0IsU0FBUyxTQUFTLENBQUMsUUFBb0M7SUFDbkQsT0FBTyxJQUFBLDRCQUFpQixFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBQ0QsU0FBUyxhQUFhLENBQUMsUUFBb0M7SUFDdkQsT0FBTyxJQUFBLDRCQUFpQixFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMvRCxDQUFDO0FBQ0QsU0FBUyxTQUFTLENBQUMsUUFBb0MsRUFBRSxNQUFjO0lBQ25FLE9BQU8sSUFBQSw0QkFBaUIsRUFBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7QUFDbkUsQ0FBQztBQUVELFNBQVMsb0JBQW9CLENBQUMsU0FBMEIsRUFBRSxTQUF1QztJQUM3RixNQUFNLE1BQU0sR0FBNEMsRUFBRSxDQUFDO0lBQzNELEtBQUssTUFBTSxNQUFNLElBQUksU0FBUyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFDcEMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBQSwrQkFBWSxFQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDL0QsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzdDLENBQUM7QUFFRCw4UEFBOFA7QUFDOVAsU0FBUyxxQkFBcUIsQ0FBQyxLQUF1QjtJQUNsRCxJQUFJLElBQUksR0FBRyxVQUFVLENBQUM7SUFDdEIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN2QixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUEsZ0NBQWEsRUFBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDckQsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUM5QyxJQUFJLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM5QixJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDckMsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLENBQUMsSUFBSSxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDbEMsQ0FBQztBQUVELHlKQUF5SjtBQUN6SixTQUFTLG9CQUFvQixDQUFDLFNBQWlCO0lBQzNDLElBQUksU0FBUyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxDQUFDO0lBQ2IsQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFHLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDM0IsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztBQUNsRCxDQUFDO0FBRUQsNlNBQTZTO0FBQzdTLFNBQVMsY0FBYyxDQUFDLE9BQW9CLEVBQUUsWUFBb0IsRUFBRSxNQUFpQjtJQUNqRixNQUFNLFlBQVksR0FBbUIsRUFBRSxDQUFDO0lBQ3hDLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7UUFDM0IsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFBLHFDQUFrQixFQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLElBQUksU0FBUyxHQUFtQixFQUFFLENBQUM7SUFDbkMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUM7SUFDL0MsS0FBSyxJQUFJLFlBQVksR0FBRyxDQUFDLEVBQUUsWUFBWSxHQUFHLFlBQVksRUFBRSxZQUFZLEVBQUUsRUFBRSxDQUFDO1FBQ3JFLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxZQUFZLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hGLENBQUM7SUFDRCxJQUFJLE1BQU0sR0FBZSxFQUFFLENBQUM7SUFDNUIsS0FBSyxJQUFJLFNBQVMsR0FBRyxDQUFDLEVBQUUsU0FBUyxHQUFHLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUM7UUFDcEUsTUFBTSxHQUFHLEVBQUUsQ0FBQztRQUNaLEtBQUssSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLFlBQVksR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUFFLENBQUM7WUFDekUsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwQixDQUFDO1FBQ0QsS0FBSyxJQUFJLFdBQVcsR0FBRyxDQUFDLEVBQUUsV0FBVyxHQUFHLFlBQVksQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLEVBQUUsQ0FBQztZQUN6RSxNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7WUFDOUMsSUFBSSxTQUFTLEdBQUcsQ0FBQyxDQUFDO1lBQ2xCLElBQUksT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDO1lBQ3hCLEtBQUssSUFBSSxhQUFhLEdBQUcsQ0FBQyxFQUFFLGFBQWEsR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxFQUFFLENBQUM7Z0JBQzVFLE1BQU0sYUFBYSxHQUFHLFNBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztnQkFDL0MsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO2dCQUNaLEtBQUssSUFBSSxHQUFHLEdBQUcsQ0FBQyxFQUFFLEdBQUcsR0FBRyxNQUFNLEVBQUUsR0FBRyxFQUFFLEVBQUUsQ0FBQztvQkFDcEMsR0FBRyxJQUFJLFdBQVcsQ0FBQyxHQUFHLENBQUMsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2pELENBQUM7Z0JBQ0QsSUFBSSxHQUFHLEdBQUcsT0FBTyxFQUFFLENBQUM7b0JBQ2hCLE9BQU8sR0FBRyxHQUFHLENBQUM7b0JBQ2QsU0FBUyxHQUFHLGFBQWEsQ0FBQztnQkFDOUIsQ0FBQztZQUNMLENBQUM7WUFDRCxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3hDLENBQUM7UUFDRCxNQUFNLGFBQWEsR0FBbUIsRUFBRSxDQUFDO1FBQ3pDLE1BQU0sVUFBVSxHQUFlLEVBQUUsQ0FBQztRQUNsQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2hCLFNBQVM7WUFDYixDQUFDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdEMsS0FBSyxNQUFNLFdBQVcsSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDOUIsTUFBTSxXQUFXLEdBQUcsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDO2dCQUM5QyxLQUFLLElBQUksR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEdBQUcsTUFBTSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUM7b0JBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2xDLENBQUM7WUFDTCxDQUFDO1lBQ0QsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDO1lBQ2IsS0FBSyxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO2dCQUNwQyxJQUFJLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNsQyxDQUFDO1lBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkMsS0FBSyxJQUFJLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxHQUFHLE1BQU0sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO2dCQUNwQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksU0FBUyxDQUFDO1lBQzNCLENBQUM7WUFDRCxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3pCLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUNELFNBQVMsR0FBRyxhQUFhLENBQUM7UUFDMUIsTUFBTSxHQUFHLFVBQVUsQ0FBQztJQUN4QixDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQTBELEVBQUUsQ0FBQztJQUN6RSxLQUFLLElBQUksWUFBWSxHQUFHLENBQUMsRUFBRSxZQUFZLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxZQUFZLEVBQUUsRUFBRSxDQUFDO1FBQ3pFLE1BQU0sUUFBUSxHQUFHLElBQUEsa0NBQWUsRUFBQyxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsWUFBWSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ2pILE1BQU0sV0FBVyxHQUFnQixFQUFFLENBQUM7UUFDcEMsS0FBSyxNQUFNLFdBQVcsSUFBSSxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUM3QyxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFDRCxLQUFLLE1BQU0sV0FBVyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3JDLElBQUEsaUNBQWMsRUFBQyxXQUFXLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDbEIsQ0FBQztBQUVELG9ZQUFvWTtBQUNwWSxTQUFnQixnQkFBZ0IsQ0FBQyxRQUFvQztJQUNqRSxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTztJQUNwQixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BELElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTztJQUVuQixNQUFNLFVBQVUsR0FBZ0IsRUFBRSxDQUFDO0lBQ25DLHFUQUFxVDtJQUNyVCxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDbkIsTUFBTSxJQUFJLEdBQUcsSUFBQSxnQ0FBZSxFQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTztRQUNsQixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzVCLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3hELENBQUM7SUFDTCxDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBQSxnQ0FBZSxFQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQzNELElBQUksQ0FBQyxTQUFTO1FBQUUsT0FBTztJQUN2QixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ2hELE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0YsSUFBSSxDQUFDLFVBQVU7UUFBRSxPQUFPO0lBQ3hCLEtBQUssTUFBTSxLQUFLLElBQUksVUFBVSxFQUFFLENBQUM7UUFDN0IsTUFBTSxPQUFPLEdBQUcsSUFBQSx1Q0FBc0IsRUFBa0IsS0FBSyxDQUFDLENBQUM7UUFDL0QsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUMvQixVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBRSxFQUFFLENBQUMsQ0FBQztRQUMzRCxDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTTtRQUFFLE9BQU87SUFFL0IsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO0lBQ3hGLE1BQU0sUUFBUSxHQUFHLGNBQWMsQ0FBQyxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBRWxFLE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDckMsTUFBTSxjQUFjLEdBQTBELEVBQUUsQ0FBQztJQUNqRixLQUFLLE1BQU0sT0FBTyxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzdCLE1BQU0sTUFBTSxHQUFHLElBQUEsZ0NBQWEsRUFBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0MsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QixjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDOUQsTUFBTSxZQUFZLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbkcsSUFBQSxrQ0FBaUIsRUFBQyxTQUFTLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ2pFLENBQUM7SUFDRCxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ2pDLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQzVCLFNBQVM7UUFDYixDQUFDO1FBQ0QsY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDMUQsSUFBQSxrQ0FBaUIsRUFBQyxTQUFTLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDdEQsQ0FBQztJQUNELElBQUEsa0NBQWlCLEVBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQzNELFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxRCxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBbERELDRDQWtEQztBQUVELFNBQWdCLGdCQUFnQixDQUM1QixRQUFvQyxFQUNwQyxLQUFzQixFQUN0QixPQUFxRDtJQUVyRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDOUIsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwRCxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRTdCLE1BQU0sSUFBSSxHQUFnQixFQUFFLENBQUM7SUFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ25CLE1BQU0sSUFBSSxHQUFHLElBQUEsZ0NBQWUsRUFBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sU0FBUyxDQUFDO1FBQzVCLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7WUFDNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBQSwrQkFBWSxFQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDN0QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELE1BQU0sU0FBUyxHQUFHLElBQUEsZ0NBQWUsRUFBQyxhQUFhLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUMzRCxJQUFJLENBQUMsU0FBUztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ2pDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSTtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQy9CLE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztJQUMzRixNQUFNLFlBQVksR0FBRyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxjQUFjLENBQUMsQ0FBQztJQUNyRixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3pGLElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDOUIsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUN6QixNQUFNLE9BQU8sR0FBRyxJQUFBLHVDQUFzQixFQUFrQixLQUFLLENBQUMsQ0FBQztRQUMvRCxLQUFLLE1BQU0sR0FBRyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLElBQUEsK0JBQVksRUFBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMxRSxDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM3RCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBcENELDRDQW9DQztBQUVELDhOQUE4TjtBQUM5TixTQUFnQixnQkFBZ0IsQ0FDNUIsUUFBb0MsRUFDcEMsSUFBYztJQUVkLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDM0UsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUM5QixNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBMkIsQ0FBQztJQUNsRCxLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQy9DLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDbkQsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQztBQUNsQixDQUFDO0FBZEQsNENBY0M7QUFFRCxTQUFnQixnQkFBZ0IsQ0FDNUIsUUFBb0MsRUFDcEMsS0FBdUI7SUFFdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNO1FBQUUsT0FBTztJQUMxQixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEQsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNsRCxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU87SUFDcEIsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPO0lBQ25CLElBQUksS0FBSyxLQUFLLFNBQVM7UUFBRSxPQUFPO0lBQ2hDLE1BQU0sUUFBUSxHQUFHLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBRXRDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUNuQixNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pGLElBQUEsa0NBQWlCLEVBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ25ELEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDdkIsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUNyRixDQUFDO1FBQ0QsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDakQsSUFBSSxRQUFRLEdBQUcsVUFBVSxFQUFFLENBQUM7WUFDeEIsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDL0IsQ0FBQztRQUNELE9BQU87SUFDWCxDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQUcsSUFBQSxnQ0FBZSxFQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQzNELElBQUksQ0FBQyxTQUFTO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDakMsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQTRCLENBQUM7SUFDeEQsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN2QixNQUFNLE1BQU0sR0FBRyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xFLElBQUksS0FBSyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1QsS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNYLFdBQVcsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFDRCxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFDRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFdBQVcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFFLENBQUM7UUFDdkMsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuRixJQUFBLGtDQUFpQixFQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUNELEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDdkIsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUNyRixDQUFDO0lBQ0QsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFHakQsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFFBQW9DLEVBQUUsRUFBRTtRQUM5RCxJQUFJLEtBQUssR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xELElBQUksQ0FBQyxLQUFLO1lBQUUsT0FBTztRQUNuQixLQUFLLE1BQU0sU0FBUyxJQUFJLGFBQWEsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sUUFBUSxHQUFHLE9BQU8sR0FBRyxTQUFTLENBQUM7WUFDckMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxRQUFRLEdBQUcsU0FBUyxFQUFFLENBQUM7Z0JBQzNDLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUN2RCxPQUFPLElBQUksQ0FBQztZQUNoQixDQUFDO1FBQ0wsQ0FBQztRQUNELE1BQU0sV0FBVyxHQUFHLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLGNBQWMsQ0FBQztRQUNuRixJQUFJLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxHQUFHLG9CQUFvQixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDbkUsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUMsQ0FBQztJQUNGLElBQUksZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztRQUM3QixnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMvQixDQUFDO0FBQ0wsQ0FBQztBQXBFRCw0Q0FvRUM7QUFFRCxTQUFnQixnQkFBZ0IsQ0FDNUIsUUFBb0MsRUFDcEMsSUFBYztJQUVkLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU87SUFDekIsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BELElBQUksQ0FBQyxLQUFLO1FBQUUsT0FBTztJQUNuQixJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTztJQUVoQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDbkIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdEUsSUFBQSxrQ0FBaUIsRUFBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDcEQsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNyQixRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDekUsT0FBTztJQUNYLENBQUM7SUFFRCxNQUFNLFNBQVMsR0FBRyxJQUFBLGdDQUFlLEVBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7SUFDM0QsSUFBSSxDQUFDLFNBQVM7UUFBRSxPQUFPO0lBQ3ZCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSTtRQUFFLE9BQU87SUFFNUIsb05BQW9OO0lBQ3BOLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUUsSUFBSSxDQUFDLFNBQVM7UUFBRSxPQUFPO0lBQ3ZCLE1BQU0sZ0JBQWdCLEdBQXlDLEVBQUUsQ0FBQztJQUNsRSxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQ3ZDLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDL0MsTUFBTSxLQUFLLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNULFNBQVM7UUFDYixDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxxQkFBcUIsQ0FBQyxDQUFDO1FBQy9GLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNyRCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzNCLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztJQUNMLENBQUM7SUFFRCxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbEQsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzdGLElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTztJQUNwQixNQUFNLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBd0MsQ0FBQztJQUN0RSxLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDM0QsYUFBYSxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxJQUFBLHVDQUFzQixFQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdEYsQ0FBQztJQUVELE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO0lBQ2xELE1BQU0sV0FBVyxHQUFhLEVBQUUsQ0FBQztJQUNqQyxLQUFLLE1BQU0sU0FBUyxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDdkMsS0FBSyxNQUFNLE1BQU0sSUFBSSxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDckMsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDMUMsU0FBUztZQUNiLENBQUM7WUFDRCxJQUFJLFFBQVEsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDWixRQUFRLEdBQUcsRUFBRSxDQUFDO2dCQUNkLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3hDLENBQUM7WUFDRCxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUM3QixXQUFXLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQyxNQUFNO1FBQ1YsQ0FBQztJQUNMLENBQUM7SUFFRCxLQUFLLE1BQU0sTUFBTSxJQUFJLGFBQWEsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFFLENBQUM7UUFDNUMsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUUsSUFBQSxrQ0FBaUIsRUFBQyxTQUFTLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFDRCxLQUFLLE1BQU0sR0FBRyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQzVCLFFBQVEsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUNELElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3JCLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNwRixDQUFDO0FBQ0wsQ0FBQztBQWhGRCw0Q0FnRkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY2JvcnggZnJvbSBcImNib3IteFwiO1xuaW1wb3J0IHsgRGF0YWJhc2UsIG5hbWVzcGFjZURhdGFiYXNlIH0gZnJvbSBcIi4vRGF0YWJhc2VcIjtcbmltcG9ydCB7IFRyYW5zYWN0aW9uU2V0U3RvcmUsIHRyYW5zYWN0aW9uUmVhZCwgdHJhbnNhY3Rpb25NdXRhdGUsIHRyYW5zYWN0aW9uRGVsZXRlLCByZXBsYXlUcmFuc2FjdGlvblN0b3JlIH0gZnJvbSBcIi4vdHJhbnNhY3Rpb25TZXRcIjtcbmltcG9ydCB7IFN0b3JlZEVtYmVkZGluZywgRW1iZWRkaW5nRm9ybWF0LCBnZXRDbG9zZW5lc3MsIGVtYmVkZGluZ1RvRmxvYXQzMiwgcmVsZWFzZUZsb2F0MzIsIGVuY29kZUVtYmVkZGluZywgaGFzaEVtYmVkZGluZyB9IGZyb20gXCIuLi9lbWJlZGRpbmdGb3JtYXRzXCI7XG5cbmV4cG9ydCB0eXBlIEl2ZkNvbmZpZyA9IHtcbiAgICBtb2RlbDogc3RyaW5nO1xuICAgIGZvcm1hdDogRW1iZWRkaW5nRm9ybWF0O1xuICAgIC8vIFRhcmdldCBudW1iZXIgb2YgZW1iZWRkaW5ncyBwZXIgY2VsbC5cbiAgICBjZWxsVGFyZ2V0U2l6ZTogbnVtYmVyO1xufTtcblxuLy8gVGllcmVkIHN0b3JhZ2UuIEJlbG93IEZMQVRfTElNSVQgZW1iZWRkaW5ncyB0aGUgd2hvbGUgc2V0IGxpdmVzIGluIG9uZSBmbGF0IHRyYW5zYWN0aW9uIHNldCAobm8gSVZGKTsgb25jZSBpdCBncm93cyBwYXN0IHRoYXQgd2UgYnVpbGQgdGhlIElWRiAoY2VudHJvaWRzICsgcGVyLWNlbGwgc2V0cykgYW5kIHN0YXkgdGhlcmUgZm9yZXZlci4gYGNvdW50YCBpcyB0aGUgbGl2ZSBlbWJlZGRpbmcgY291bnQgKHJlLWRlcml2ZWQgZXhhY3RseSBvbiBhIHJlYnVpbGQpLiBgc3RlcHNgIHJlY29yZHMgb25lLXRpbWUgdXBncmFkZXMgdGhhdCBtdXN0IG5ldmVyIHJlLXJ1biBldmVuIGlmIHRoZSBzZXQgbGF0ZXIgc2hyaW5rcyBhbmQgcmVncm93cy5cbmV4cG9ydCB0eXBlIEl2ZkVtYmVkZGluZ1Jvb3QgPSB7XG4gICAgY29uZmlnOiBJdmZDb25maWc7XG4gICAgY291bnQ6IG51bWJlcjtcbiAgICBmbGF0OiBUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz47XG4gICAgLy8gRGlyZWN0IHJlZiAtPiBlbWJlZGRpbmcgaW5kZXguIEVhY2ggZW50cnkgaXMgb25lIENCT1IgYmxvYiBhdCBpdHMgb3duIGtleSwgc28gYSBsb29rdXAgb3IgZGVsZXRlIGlzIGEgc2luZ2xlIGtleS12YWx1ZSBvcCAobm8gdHJhbnNhY3Rpb24tc2V0IHJlcGxheSkgYW5kIGRlbGV0ZURhdGEgY2FuIGRyb3AgaXQgKGl0J3MgYSBwcmltaXRpdmUgbGVhZikuIFJlZnMgYW5kIHRoZWlyIGVtYmVkZGluZ3MgbmV2ZXIgbW92ZSwgc28gYSByZWJ1aWxkIGxlYXZlcyB0aGlzIHVudG91Y2hlZC5cbiAgICBieVJlZjogeyBbcmVmOiBzdHJpbmddOiBVaW50OEFycmF5IH07XG4gICAgc3RlcHM6IHsgW3N0ZXA6IHN0cmluZ106IGJvb2xlYW4gfTtcbiAgICBjZW50cm9pZHM6IFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPjtcbiAgICBjZWxsczogeyBbY2VsbElkOiBzdHJpbmddOiBUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz4gfTtcbn07XG5cbmV4cG9ydCB0eXBlIEVtYmVkZGluZ0lucHV0ID0geyByZWY6IHN0cmluZzsgZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcgfTtcbmV4cG9ydCB0eXBlIFNlYXJjaEhpdCA9IHsgcmVmOiBzdHJpbmc7IGNsb3NlbmVzczogbnVtYmVyIH07XG50eXBlIENlbGxFbnRyeSA9IHsgcmVmOiBzdHJpbmc7IGVtYmVkZGluZzogU3RvcmVkRW1iZWRkaW5nIH07XG5cbmNvbnN0IGVtYmVkZGluZ0Nib3IgPSBuZXcgY2JvcnguRW5jb2Rlcih7IHN0cnVjdHVyZWRDbG9uZTogdHJ1ZSB9KTtcbmZ1bmN0aW9uIGVuY29kZVJlZlZhbHVlKGVtYmVkZGluZzogU3RvcmVkRW1iZWRkaW5nKTogVWludDhBcnJheSB7XG4gICAgcmV0dXJuIGVtYmVkZGluZ0Nib3IuZW5jb2RlKGVtYmVkZGluZykgYXMgVWludDhBcnJheTtcbn1cbmZ1bmN0aW9uIGRlY29kZVJlZlZhbHVlKHZhbHVlOiBVaW50OEFycmF5KTogU3RvcmVkRW1iZWRkaW5nIHtcbiAgICByZXR1cm4gZW1iZWRkaW5nQ2Jvci5kZWNvZGUodmFsdWUpIGFzIFN0b3JlZEVtYmVkZGluZztcbn1cblxuLy8gQmVsb3cgdGhpcyBtYW55IGVtYmVkZGluZ3Mgd2Ugc2tpcCB0aGUgSVZGIGVudGlyZWx5IChmbGF0IHN0b3JlKS4gMTAyNCA9IGEgY2xlYW4gcG93ZXIgb2YgdHdvLlxuY29uc3QgRkxBVF9MSU1JVCA9IDEwMjQ7XG4vLyBGb3JjZSBhIGZyb20tc2NyYXRjaCByZWJ1aWxkIG9uY2UgYXQgZWFjaCBvZiB0aGVzZSAobXVsdGlwbGVzIG9mIDQgYWJvdmUgRkxBVF9MSU1JVCwgdXAgdG8gfjE2ayksIGdhdGVkIGJ5IGEgc3RlcCBmbGFnIHNvIGVhY2ggcnVucyBhdCBtb3N0IG9uY2UgZXZlci5cbmNvbnN0IFJFR0VORVJBVEVfQVQgPSBbNDA5NiwgMTYzODRdO1xuY29uc3QgU1RFUF9JVkYgPSBcIml2ZlwiO1xuLy8gT24gZGVsZXRlLCB0aGUgbWVtYmVyJ3MgZXhhY3QgY2VsbCBwbHVzIHRoaXMgbWFueSBuZWFyYnkgY2VsbHMgYXJlIGNoZWNrZWQsIGluIGNhc2UgYSByZWJ1aWxkIGxlZnQgaXQgbm9uLW9wdGltYWwuXG5jb25zdCBERUxFVEVfRkFMTEJBQ0tfQ0VMTFMgPSAxMDtcbmNvbnN0IFJFQkFMQU5DRV9JVEVSQVRJT05TID0gNDtcblxuZnVuY3Rpb24gZmxhdFN0b3JlKGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290Pik6IERhdGFiYXNlPFRyYW5zYWN0aW9uU2V0U3RvcmU8U3RvcmVkRW1iZWRkaW5nPj4ge1xuICAgIHJldHVybiBuYW1lc3BhY2VEYXRhYmFzZShkYXRhYmFzZSwgcm9vdCA9PiByb290LmZsYXQpO1xufVxuZnVuY3Rpb24gY2VudHJvaWRTdG9yZShkYXRhYmFzZTogRGF0YWJhc2U8SXZmRW1iZWRkaW5nUm9vdD4pOiBEYXRhYmFzZTxUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz4+IHtcbiAgICByZXR1cm4gbmFtZXNwYWNlRGF0YWJhc2UoZGF0YWJhc2UsIHJvb3QgPT4gcm9vdC5jZW50cm9pZHMpO1xufVxuZnVuY3Rpb24gY2VsbFN0b3JlKGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290PiwgY2VsbElkOiBzdHJpbmcpOiBEYXRhYmFzZTxUcmFuc2FjdGlvblNldFN0b3JlPFN0b3JlZEVtYmVkZGluZz4+IHtcbiAgICByZXR1cm4gbmFtZXNwYWNlRGF0YWJhc2UoZGF0YWJhc2UsIHJvb3QgPT4gcm9vdC5jZWxsc1tjZWxsSWRdKTtcbn1cblxuZnVuY3Rpb24gcmFua0NlbGxzQnlDbG9zZW5lc3MoZW1iZWRkaW5nOiBTdG9yZWRFbWJlZGRpbmcsIGNlbnRyb2lkczogTWFwPHN0cmluZywgU3RvcmVkRW1iZWRkaW5nPik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCByYW5rZWQ6IHsgY2VsbElkOiBzdHJpbmc7IGNsb3NlbmVzczogbnVtYmVyIH1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2VsbElkIG9mIGNlbnRyb2lkcy5rZXlzKCkpIHtcbiAgICAgICAgcmFua2VkLnB1c2goeyBjZWxsSWQsIGNsb3NlbmVzczogZ2V0Q2xvc2VuZXNzKGVtYmVkZGluZywgY2VudHJvaWRzLmdldChjZWxsSWQpISkgfSk7XG4gICAgfVxuICAgIHJhbmtlZC5zb3J0KChsZWZ0LCByaWdodCkgPT4gcmlnaHQuY2xvc2VuZXNzIC0gbGVmdC5jbG9zZW5lc3MpO1xuICAgIHJldHVybiByYW5rZWQubWFwKGVudHJ5ID0+IGVudHJ5LmNlbGxJZCk7XG59XG5cbi8vIFN5bmNlZCBmdW5jdGlvbnMgcmVydW4gKGFuZCBhcmUgcHJlZGljdGVkIGNsaWVudC1zaWRlKSwgc28gdGhlIHJlYmFsYW5jZSByb2xsIG11c3QgYmUgaWRlbnRpY2FsIG9uIGV2ZXJ5IHJ1biBvZiB0aGUgc2FtZSBjYWxsIOKAlCBkZXJpdmUgaXQgZnJvbSB0aGUgaW5zZXJ0ZWQgaXRlbXMgaW5zdGVhZCBvZiBNYXRoLnJhbmRvbSgpLiBGTlYtMWEgb3ZlciBlYWNoIHJlZiBwbHVzIGl0cyBlbWJlZGRpbmcgaGFzaCwgbWFwcGVkIHRvIFswLCAxKS5cbmZ1bmN0aW9uIHNlZWRlZFJhbmRvbUZyb21JdGVtcyhpdGVtczogRW1iZWRkaW5nSW5wdXRbXSk6IG51bWJlciB7XG4gICAgbGV0IGhhc2ggPSAyMTY2MTM2MjYxO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBjb25zdCBrZXkgPSBpdGVtLnJlZiArIGhhc2hFbWJlZGRpbmcoaXRlbS5lbWJlZGRpbmcpO1xuICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwga2V5Lmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgaGFzaCBePSBrZXkuY2hhckNvZGVBdChpbmRleCk7XG4gICAgICAgICAgICBoYXNoID0gTWF0aC5pbXVsKGhhc2gsIDE2Nzc3NjE5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gKGhhc2ggPj4+IDApIC8gMiAqKiAzMjtcbn1cblxuLy8gUGVyLXdyaXRlIGNoYW5jZSBvZiBhIGZ1bGwgcmVidWlsZC4gWmVybyBhdC91bmRlciB0aGUgdGFyZ2V0IHNpemUsIHRoZW4gcmlzZXMgKGN1YmljYWxseSkgcGFzdCBpdCBzbyBjZWxscyBzdGF5IHJvdWdobHkgYmV0d2VlbiB0YXJnZXQgYW5kIH4yeCB0YXJnZXQuXG5mdW5jdGlvbiByZWJhbGFuY2VQcm9iYWJpbGl0eShmaWxsUmF0aW86IG51bWJlcik6IG51bWJlciB7XG4gICAgaWYgKGZpbGxSYXRpbyA8PSAxKSB7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBjb25zdCBvdmVyID0gZmlsbFJhdGlvIC0gMTtcbiAgICByZXR1cm4gTWF0aC5taW4oMSwgb3ZlciAqIG92ZXIgKiBvdmVyICogMC4yNSk7XG59XG5cbi8vIGstbWVhbnMuIERlY29kZXMgZXZlcnkgbWVtYmVyIHRvIGEgcG9vbGVkIGZsb2F0MzIgYnVmZmVyIE9OQ0UsIHRoZW4gYXNzaWducyB3aXRoIGEgcGxhaW4gaW50ZXJuYWwgZmxvYXQgZG90IChubyBnZXRDbG9zZW5lc3MgY2FsbCDigJQgY29tcGFyaW5nIHR3byBmbG9hdCB2ZWN0b3JzIGlzIHRyaXZpYWwpIGFuZCBrZWVwcyBjZW50cm9pZHMgYXMgZmxvYXQgbWVhbnMsIGVuY29kaW5nIHRoZW0gdG8gU3RvcmVkRW1iZWRkaW5nIG9ubHkgYXQgdGhlIGVuZC4gUmVsZWFzZXMgdGhlIGJvcnJvd2VkIGJ1ZmZlcnMgd2hlbiBkb25lLlxuZnVuY3Rpb24gY2x1c3Rlck1lbWJlcnMobWVtYmVyczogQ2VsbEVudHJ5W10sIGNsdXN0ZXJDb3VudDogbnVtYmVyLCBjb25maWc6IEl2ZkNvbmZpZyk6IHsgY2VudHJvaWQ6IFN0b3JlZEVtYmVkZGluZzsgbWVtYmVyczogQ2VsbEVudHJ5W10gfVtdIHtcbiAgICBjb25zdCBtZW1iZXJGbG9hdHM6IEZsb2F0MzJBcnJheVtdID0gW107XG4gICAgZm9yIChjb25zdCBtZW1iZXIgb2YgbWVtYmVycykge1xuICAgICAgICBtZW1iZXJGbG9hdHMucHVzaChlbWJlZGRpbmdUb0Zsb2F0MzIobWVtYmVyLmVtYmVkZGluZywgdHJ1ZSkpO1xuICAgIH1cbiAgICBjb25zdCBsZW5ndGggPSBtZW1iZXJGbG9hdHMubGVuZ3RoID8gbWVtYmVyRmxvYXRzWzBdLmxlbmd0aCA6IDA7XG4gICAgbGV0IGNlbnRyb2lkczogRmxvYXQzMkFycmF5W10gPSBbXTtcbiAgICBjb25zdCBzZWVkU3RlcCA9IG1lbWJlcnMubGVuZ3RoIC8gY2x1c3RlckNvdW50O1xuICAgIGZvciAobGV0IGNsdXN0ZXJJbmRleCA9IDA7IGNsdXN0ZXJJbmRleCA8IGNsdXN0ZXJDb3VudDsgY2x1c3RlckluZGV4KyspIHtcbiAgICAgICAgY2VudHJvaWRzLnB1c2gobmV3IEZsb2F0MzJBcnJheShtZW1iZXJGbG9hdHNbTWF0aC5mbG9vcihjbHVzdGVySW5kZXggKiBzZWVkU3RlcCldKSk7XG4gICAgfVxuICAgIGxldCBncm91cHM6IG51bWJlcltdW10gPSBbXTtcbiAgICBmb3IgKGxldCBpdGVyYXRpb24gPSAwOyBpdGVyYXRpb24gPCBSRUJBTEFOQ0VfSVRFUkFUSU9OUzsgaXRlcmF0aW9uKyspIHtcbiAgICAgICAgZ3JvdXBzID0gW107XG4gICAgICAgIGZvciAobGV0IGNsdXN0ZXJJbmRleCA9IDA7IGNsdXN0ZXJJbmRleCA8IGNlbnRyb2lkcy5sZW5ndGg7IGNsdXN0ZXJJbmRleCsrKSB7XG4gICAgICAgICAgICBncm91cHMucHVzaChbXSk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgbWVtYmVySW5kZXggPSAwOyBtZW1iZXJJbmRleCA8IG1lbWJlckZsb2F0cy5sZW5ndGg7IG1lbWJlckluZGV4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IG1lbWJlckZsb2F0ID0gbWVtYmVyRmxvYXRzW21lbWJlckluZGV4XTtcbiAgICAgICAgICAgIGxldCBiZXN0SW5kZXggPSAwO1xuICAgICAgICAgICAgbGV0IGJlc3REb3QgPSAtSW5maW5pdHk7XG4gICAgICAgICAgICBmb3IgKGxldCBjZW50cm9pZEluZGV4ID0gMDsgY2VudHJvaWRJbmRleCA8IGNlbnRyb2lkcy5sZW5ndGg7IGNlbnRyb2lkSW5kZXgrKykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNlbnRyb2lkRmxvYXQgPSBjZW50cm9pZHNbY2VudHJvaWRJbmRleF07XG4gICAgICAgICAgICAgICAgbGV0IGRvdCA9IDA7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgbGVuZ3RoOyBkaW0rKykge1xuICAgICAgICAgICAgICAgICAgICBkb3QgKz0gbWVtYmVyRmxvYXRbZGltXSAqIGNlbnRyb2lkRmxvYXRbZGltXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGRvdCA+IGJlc3REb3QpIHtcbiAgICAgICAgICAgICAgICAgICAgYmVzdERvdCA9IGRvdDtcbiAgICAgICAgICAgICAgICAgICAgYmVzdEluZGV4ID0gY2VudHJvaWRJbmRleDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBncm91cHNbYmVzdEluZGV4XS5wdXNoKG1lbWJlckluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXh0Q2VudHJvaWRzOiBGbG9hdDMyQXJyYXlbXSA9IFtdO1xuICAgICAgICBjb25zdCBuZXh0R3JvdXBzOiBudW1iZXJbXVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgZ3JvdXBzKSB7XG4gICAgICAgICAgICBpZiAoIWdyb3VwLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgbWVhbiA9IG5ldyBGbG9hdDMyQXJyYXkobGVuZ3RoKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbWVtYmVySW5kZXggb2YgZ3JvdXApIHtcbiAgICAgICAgICAgICAgICBjb25zdCBtZW1iZXJGbG9hdCA9IG1lbWJlckZsb2F0c1ttZW1iZXJJbmRleF07XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgZGltID0gMDsgZGltIDwgbGVuZ3RoOyBkaW0rKykge1xuICAgICAgICAgICAgICAgICAgICBtZWFuW2RpbV0gKz0gbWVtYmVyRmxvYXRbZGltXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgbm9ybSA9IDA7XG4gICAgICAgICAgICBmb3IgKGxldCBkaW0gPSAwOyBkaW0gPCBsZW5ndGg7IGRpbSsrKSB7XG4gICAgICAgICAgICAgICAgbm9ybSArPSBtZWFuW2RpbV0gKiBtZWFuW2RpbV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBtYWduaXR1ZGUgPSBNYXRoLnNxcnQobm9ybSkgfHwgMTtcbiAgICAgICAgICAgIGZvciAobGV0IGRpbSA9IDA7IGRpbSA8IGxlbmd0aDsgZGltKyspIHtcbiAgICAgICAgICAgICAgICBtZWFuW2RpbV0gLz0gbWFnbml0dWRlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbmV4dENlbnRyb2lkcy5wdXNoKG1lYW4pO1xuICAgICAgICAgICAgbmV4dEdyb3Vwcy5wdXNoKGdyb3VwKTtcbiAgICAgICAgfVxuICAgICAgICBjZW50cm9pZHMgPSBuZXh0Q2VudHJvaWRzO1xuICAgICAgICBncm91cHMgPSBuZXh0R3JvdXBzO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQ6IHsgY2VudHJvaWQ6IFN0b3JlZEVtYmVkZGluZzsgbWVtYmVyczogQ2VsbEVudHJ5W10gfVtdID0gW107XG4gICAgZm9yIChsZXQgY2x1c3RlckluZGV4ID0gMDsgY2x1c3RlckluZGV4IDwgY2VudHJvaWRzLmxlbmd0aDsgY2x1c3RlckluZGV4KyspIHtcbiAgICAgICAgY29uc3QgY2VudHJvaWQgPSBlbmNvZGVFbWJlZGRpbmcoeyBpbnB1dDogY2VudHJvaWRzW2NsdXN0ZXJJbmRleF0sIGZvcm1hdDogY29uZmlnLmZvcm1hdCwgbW9kZWw6IGNvbmZpZy5tb2RlbCB9KTtcbiAgICAgICAgY29uc3QgY2VsbE1lbWJlcnM6IENlbGxFbnRyeVtdID0gW107XG4gICAgICAgIGZvciAoY29uc3QgbWVtYmVySW5kZXggb2YgZ3JvdXBzW2NsdXN0ZXJJbmRleF0pIHtcbiAgICAgICAgICAgIGNlbGxNZW1iZXJzLnB1c2gobWVtYmVyc1ttZW1iZXJJbmRleF0pO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdC5wdXNoKHsgY2VudHJvaWQsIG1lbWJlcnM6IGNlbGxNZW1iZXJzIH0pO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG1lbWJlckZsb2F0IG9mIG1lbWJlckZsb2F0cykge1xuICAgICAgICByZWxlYXNlRmxvYXQzMihtZW1iZXJGbG9hdCk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIFJlLWNsdXN0ZXIgRVZFUlkgZW1iZWRkaW5nIChmbGF0IHRpZXIgKyBhbGwgY2VsbHMpIGludG8gYSBmcmVzaCBJVkYsIGNsZWFyIHRoZSBmbGF0IHRpZXIsIGFuZCBtYXJrIElWRiBtb2RlLiBUaGlzIGlzIHRoZSByZWFycmFuZ2VyOiBydW4gcHJvYmFiaWxpc3RpY2FsbHkgYXMgdGhlIHNldCBncm93cywgb25jZSBhdCBlYWNoIHJlZ2VuZXJhdGUgdGhyZXNob2xkLCBhbmQgb25jZSB0byB1cGdyYWRlIGZyb20gZmxhdC4gUmVhZHMgZXZlcnl0aGluZyBpdCB1c2VzLCBzbyBpdCBiYWlscyAoZG9lcyBub3RoaW5nKSBpZiBhbnl0aGluZyBpc24ndCBzeW5jZWQgYW5kIHRoZSBjYWxsZXIncyByZXRyeSByZS1ydW5zIGl0OyBubyBjYWxsZXIgY2FyZXMgYWJvdXQgaXRzIHJlc3VsdC5cbmV4cG9ydCBmdW5jdGlvbiByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290Pik6IHZvaWQge1xuICAgIGNvbnN0IGNvbmZpZyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5jb25maWcpO1xuICAgIGlmICghY29uZmlnKSByZXR1cm47XG4gICAgY29uc3Qgc3RlcHMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpO1xuICAgIGlmICghc3RlcHMpIHJldHVybjtcblxuICAgIGNvbnN0IGFsbE1lbWJlcnM6IENlbGxFbnRyeVtdID0gW107XG4gICAgLy8gT25seSB0aGUgb25lLXRpbWUgZmxhdC0+SVZGIHVwZ3JhZGUgcHVsbHMgZnJvbSB0aGUgZmxhdCB0aWVyLiBPbmNlIFNURVBfSVZGIGlzIHNldCB0aGUgZmxhdCBkYXRhIGhhcyBhbHJlYWR5IGJlZW4gZm9sZGVkIGludG8gY2VsbHMsIHNvIGxhdGVyIHJlYnVpbGRzIGlnbm9yZSBpdC4gSXQncyBsZWZ0IGluIHBsYWNlLCBuZXZlciBkZWxldGVkOiBkZWxldGVEYXRhIG9ubHkgcmVtb3ZlcyBwcmltaXRpdmUgbGVhdmVzLCBub3QgYSB3aG9sZSBzdG9yZSwgYW5kIHRoZSBmbGF0IHRpZXIgaXMgc21hbGwgZW5vdWdoIG5vdCB0byBtYXR0ZXIuXG4gICAgaWYgKCFzdGVwc1tTVEVQX0lWRl0pIHtcbiAgICAgICAgY29uc3QgZmxhdCA9IHRyYW5zYWN0aW9uUmVhZChmbGF0U3RvcmUoZGF0YWJhc2UpKTtcbiAgICAgICAgaWYgKCFmbGF0KSByZXR1cm47XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIGZsYXQua2V5cygpKSB7XG4gICAgICAgICAgICBhbGxNZW1iZXJzLnB1c2goeyByZWYsIGVtYmVkZGluZzogZmxhdC5nZXQocmVmKSEgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuO1xuICAgIGNvbnN0IG9sZENlbGxJZHMgPSBBcnJheS5mcm9tKGNlbnRyb2lkcy5rZXlzKCkpO1xuICAgIGNvbnN0IGNlbGxTdG9yZXMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IG9sZENlbGxJZHMubWFwKGNlbGxJZCA9PiByb290LmNlbGxzW2NlbGxJZF0pKTtcbiAgICBpZiAoIWNlbGxTdG9yZXMpIHJldHVybjtcbiAgICBmb3IgKGNvbnN0IHN0b3JlIG9mIGNlbGxTdG9yZXMpIHtcbiAgICAgICAgY29uc3QgbWVtYmVycyA9IHJlcGxheVRyYW5zYWN0aW9uU3RvcmU8U3RvcmVkRW1iZWRkaW5nPihzdG9yZSk7XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIG1lbWJlcnMua2V5cygpKSB7XG4gICAgICAgICAgICBhbGxNZW1iZXJzLnB1c2goeyByZWYsIGVtYmVkZGluZzogbWVtYmVycy5nZXQocmVmKSEgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFhbGxNZW1iZXJzLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgY29uc3QgY2x1c3RlckNvdW50ID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZChhbGxNZW1iZXJzLmxlbmd0aCAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZSkpO1xuICAgIGNvbnN0IGNsdXN0ZXJzID0gY2x1c3Rlck1lbWJlcnMoYWxsTWVtYmVycywgY2x1c3RlckNvdW50LCBjb25maWcpO1xuXG4gICAgY29uc3QgbmV3Q2VsbElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IGNlbnRyb2lkV3JpdGVzOiB7IGtleTogc3RyaW5nOyB2YWx1ZTogU3RvcmVkRW1iZWRkaW5nIHwgdW5kZWZpbmVkIH1bXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY2x1c3RlciBvZiBjbHVzdGVycykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSBoYXNoRW1iZWRkaW5nKGNsdXN0ZXIuY2VudHJvaWQpO1xuICAgICAgICBuZXdDZWxsSWRzLmFkZChjZWxsSWQpO1xuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBjZWxsSWQsIHZhbHVlOiBjbHVzdGVyLmNlbnRyb2lkIH0pO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBjbHVzdGVyLm1lbWJlcnMubWFwKG1lbWJlciA9PiAoeyBrZXk6IG1lbWJlci5yZWYsIHZhbHVlOiBtZW1iZXIuZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoY2VsbFN0b3JlKGRhdGFiYXNlLCBjZWxsSWQpLCBtZW1iZXJXcml0ZXMpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG9sZENlbGxJZCBvZiBvbGRDZWxsSWRzKSB7XG4gICAgICAgIGlmIChuZXdDZWxsSWRzLmhhcyhvbGRDZWxsSWQpKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjZW50cm9pZFdyaXRlcy5wdXNoKHsga2V5OiBvbGRDZWxsSWQsIHZhbHVlOiB1bmRlZmluZWQgfSk7XG4gICAgICAgIHRyYW5zYWN0aW9uRGVsZXRlKGNlbGxTdG9yZShkYXRhYmFzZSwgb2xkQ2VsbElkKSk7XG4gICAgfVxuICAgIHRyYW5zYWN0aW9uTXV0YXRlKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpLCBjZW50cm9pZFdyaXRlcyk7XG4gICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgYWxsTWVtYmVycy5sZW5ndGgpO1xuICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3Quc3RlcHNbU1RFUF9JVkZdLCB0cnVlKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNlYXJjaEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIHF1ZXJ5OiBTdG9yZWRFbWJlZGRpbmcsXG4gICAgb3B0aW9uczogeyBwcm9iZUJ1ZGdldDogbnVtYmVyOyByZXN1bHRDb3VudDogbnVtYmVyIH0sXG4pOiBTZWFyY2hIaXRbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY29uZmlnID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByb290LmNvbmZpZyk7XG4gICAgaWYgKCFjb25maWcpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc3RlcHMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpO1xuICAgIGlmICghc3RlcHMpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgICBjb25zdCBoaXRzOiBTZWFyY2hIaXRbXSA9IFtdO1xuICAgIGlmICghc3RlcHNbU1RFUF9JVkZdKSB7XG4gICAgICAgIGNvbnN0IGZsYXQgPSB0cmFuc2FjdGlvblJlYWQoZmxhdFN0b3JlKGRhdGFiYXNlKSk7XG4gICAgICAgIGlmICghZmxhdCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgZm9yIChjb25zdCByZWYgb2YgZmxhdC5rZXlzKCkpIHtcbiAgICAgICAgICAgIGhpdHMucHVzaCh7IHJlZiwgY2xvc2VuZXNzOiBnZXRDbG9zZW5lc3MocXVlcnksIGZsYXQuZ2V0KHJlZikhKSB9KTtcbiAgICAgICAgfVxuICAgICAgICBoaXRzLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiByaWdodC5jbG9zZW5lc3MgLSBsZWZ0LmNsb3NlbmVzcyk7XG4gICAgICAgIHJldHVybiBoaXRzLnNsaWNlKDAsIG9wdGlvbnMucmVzdWx0Q291bnQpO1xuICAgIH1cblxuICAgIGNvbnN0IGNlbnRyb2lkcyA9IHRyYW5zYWN0aW9uUmVhZChjZW50cm9pZFN0b3JlKGRhdGFiYXNlKSk7XG4gICAgaWYgKCFjZW50cm9pZHMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFjZW50cm9pZHMuc2l6ZSkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IHByb2JlQ2VsbENvdW50ID0gTWF0aC5tYXgoMSwgTWF0aC5jZWlsKG9wdGlvbnMucHJvYmVCdWRnZXQgLyBjb25maWcuY2VsbFRhcmdldFNpemUpKTtcbiAgICBjb25zdCBwcm9iZUNlbGxJZHMgPSByYW5rQ2VsbHNCeUNsb3NlbmVzcyhxdWVyeSwgY2VudHJvaWRzKS5zbGljZSgwLCBwcm9iZUNlbGxDb3VudCk7XG4gICAgY29uc3Qgc3RvcmVzID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiBwcm9iZUNlbGxJZHMubWFwKGNlbGxJZCA9PiByb290LmNlbGxzW2NlbGxJZF0pKTtcbiAgICBpZiAoIXN0b3JlcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBmb3IgKGNvbnN0IHN0b3JlIG9mIHN0b3Jlcykge1xuICAgICAgICBjb25zdCBtZW1iZXJzID0gcmVwbGF5VHJhbnNhY3Rpb25TdG9yZTxTdG9yZWRFbWJlZGRpbmc+KHN0b3JlKTtcbiAgICAgICAgZm9yIChjb25zdCByZWYgb2YgbWVtYmVycy5rZXlzKCkpIHtcbiAgICAgICAgICAgIGhpdHMucHVzaCh7IHJlZiwgY2xvc2VuZXNzOiBnZXRDbG9zZW5lc3MocXVlcnksIG1lbWJlcnMuZ2V0KHJlZikhKSB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoaXRzLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiByaWdodC5jbG9zZW5lc3MgLSBsZWZ0LmNsb3NlbmVzcyk7XG4gICAgcmV0dXJuIGhpdHMuc2xpY2UoMCwgb3B0aW9ucy5yZXN1bHRDb3VudCk7XG59XG5cbi8vIERpcmVjdCByZWYgLT4gc3RvcmVkIGVtYmVkZGluZyBsb29rdXAgdGhyb3VnaCB0aGUgYnlSZWYgaW5kZXg6IG9uZSBrZXktdmFsdWUgcmVhZCBwZXIgcmVmLCBubyBjZWxsIHNjYW4uIEEgc2VhcmNoIHJldHVybnMgcmVmczsgdGhpcyBmZXRjaGVzIHRoZSBkYXRhIGJlaGluZCB0aGVtLiBTa2lwcyByZWZzIHRoYXQgYXJlbid0IHByZXNlbnQ7IHVuZGVmaW5lZCBpZiBub3Qgc3luY2VkLlxuZXhwb3J0IGZ1bmN0aW9uIGxvb2t1cEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIHJlZnM6IHN0cmluZ1tdLFxuKTogTWFwPHN0cmluZywgU3RvcmVkRW1iZWRkaW5nPiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdmFsdWVzID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByZWZzLm1hcChyZWYgPT4gcm9vdC5ieVJlZltyZWZdKSk7XG4gICAgaWYgKCF2YWx1ZXMpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcDxzdHJpbmcsIFN0b3JlZEVtYmVkZGluZz4oKTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgcmVmcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB2YWx1ZXNbaW5kZXhdO1xuICAgICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJlc3VsdC5zZXQocmVmc1tpbmRleF0sIGRlY29kZVJlZlZhbHVlKHZhbHVlKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGluc2VydEVtYmVkZGluZ3MoXG4gICAgZGF0YWJhc2U6IERhdGFiYXNlPEl2ZkVtYmVkZGluZ1Jvb3Q+LFxuICAgIGl0ZW1zOiBFbWJlZGRpbmdJbnB1dFtdLFxuKSB7XG4gICAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBjb25maWcgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3QuY29uZmlnKTtcbiAgICBjb25zdCBzdGVwcyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5zdGVwcyk7XG4gICAgbGV0IGNvdW50ID0gZGF0YWJhc2UucmVhZERhdGEocm9vdCA9PiByb290LmNvdW50KTtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuO1xuICAgIGlmICghc3RlcHMpIHJldHVybjtcbiAgICBpZiAoY291bnQgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgIGNvbnN0IG5ld0NvdW50ID0gY291bnQgKyBpdGVtcy5sZW5ndGg7XG5cbiAgICBpZiAoIXN0ZXBzW1NURVBfSVZGXSkge1xuICAgICAgICBjb25zdCBmbGF0V3JpdGVzID0gaXRlbXMubWFwKGl0ZW0gPT4gKHsga2V5OiBpdGVtLnJlZiwgdmFsdWU6IGl0ZW0uZW1iZWRkaW5nIH0pKTtcbiAgICAgICAgdHJhbnNhY3Rpb25NdXRhdGUoZmxhdFN0b3JlKGRhdGFiYXNlKSwgZmxhdFdyaXRlcyk7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICAgICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5ieVJlZltpdGVtLnJlZl0sIGVuY29kZVJlZlZhbHVlKGl0ZW0uZW1iZWRkaW5nKSk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgbmV3Q291bnQpO1xuICAgICAgICBpZiAobmV3Q291bnQgPiBGTEFUX0xJTUlUKSB7XG4gICAgICAgICAgICByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY2VudHJvaWRzID0gdHJhbnNhY3Rpb25SZWFkKGNlbnRyb2lkU3RvcmUoZGF0YWJhc2UpKTtcbiAgICBpZiAoIWNlbnRyb2lkcykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBjb25zdCBpdGVtc0J5Q2VsbCA9IG5ldyBNYXA8c3RyaW5nLCBFbWJlZGRpbmdJbnB1dFtdPigpO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBjb25zdCBjZWxsSWQgPSByYW5rQ2VsbHNCeUNsb3NlbmVzcyhpdGVtLmVtYmVkZGluZywgY2VudHJvaWRzKVswXTtcbiAgICAgICAgbGV0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgIGlmICghZ3JvdXApIHtcbiAgICAgICAgICAgIGdyb3VwID0gW107XG4gICAgICAgICAgICBpdGVtc0J5Q2VsbC5zZXQoY2VsbElkLCBncm91cCk7XG4gICAgICAgIH1cbiAgICAgICAgZ3JvdXAucHVzaChpdGVtKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBjZWxsSWQgb2YgaXRlbXNCeUNlbGwua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IGdyb3VwID0gaXRlbXNCeUNlbGwuZ2V0KGNlbGxJZCkhO1xuICAgICAgICBjb25zdCBtZW1iZXJXcml0ZXMgPSBncm91cC5tYXAoaXRlbSA9PiAoeyBrZXk6IGl0ZW0ucmVmLCB2YWx1ZTogaXRlbS5lbWJlZGRpbmcgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShjZWxsU3RvcmUoZGF0YWJhc2UsIGNlbGxJZCksIG1lbWJlcldyaXRlcyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBkYXRhYmFzZS53cml0ZURhdGEocm9vdCA9PiByb290LmJ5UmVmW2l0ZW0ucmVmXSwgZW5jb2RlUmVmVmFsdWUoaXRlbS5lbWJlZGRpbmcpKTtcbiAgICB9XG4gICAgZGF0YWJhc2Uud3JpdGVEYXRhKHJvb3QgPT4gcm9vdC5jb3VudCwgbmV3Q291bnQpO1xuXG5cbiAgICBjb25zdCBzaG91bGRSZWdlbmVyYXRlID0gKGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290PikgPT4ge1xuICAgICAgICBsZXQgc3RlcHMgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3Quc3RlcHMpO1xuICAgICAgICBpZiAoIXN0ZXBzKSByZXR1cm47XG4gICAgICAgIGZvciAoY29uc3QgdGhyZXNob2xkIG9mIFJFR0VORVJBVEVfQVQpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0ZXBOYW1lID0gXCJyZWdlblwiICsgdGhyZXNob2xkO1xuICAgICAgICAgICAgaWYgKCFzdGVwc1tzdGVwTmFtZV0gJiYgbmV3Q291bnQgPiB0aHJlc2hvbGQpIHtcbiAgICAgICAgICAgICAgICBkYXRhYmFzZS53cml0ZURhdGEocm9vdCA9PiByb290LnN0ZXBzW3N0ZXBOYW1lXSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXZlcmFnZUZpbGwgPSBuZXdDb3VudCAvIE1hdGgubWF4KDEsIGNlbnRyb2lkcy5zaXplKSAvIGNvbmZpZy5jZWxsVGFyZ2V0U2l6ZTtcbiAgICAgICAgaWYgKHNlZWRlZFJhbmRvbUZyb21JdGVtcyhpdGVtcykgPCByZWJhbGFuY2VQcm9iYWJpbGl0eShhdmVyYWdlRmlsbCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIGlmIChzaG91bGRSZWdlbmVyYXRlKGRhdGFiYXNlKSkge1xuICAgICAgICByZWJ1aWxkU3RydWN0dXJlKGRhdGFiYXNlKTtcbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmVFbWJlZGRpbmdzKFxuICAgIGRhdGFiYXNlOiBEYXRhYmFzZTxJdmZFbWJlZGRpbmdSb290PixcbiAgICByZWZzOiBzdHJpbmdbXSxcbikge1xuICAgIGlmICghcmVmcy5sZW5ndGgpIHJldHVybjtcbiAgICBjb25zdCBzdGVwcyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcm9vdC5zdGVwcyk7XG4gICAgY29uc3QgY291bnQgPSBkYXRhYmFzZS5yZWFkRGF0YShyb290ID0+IHJvb3QuY291bnQpO1xuICAgIGlmICghc3RlcHMpIHJldHVybjtcbiAgICBpZiAoY291bnQgPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuXG4gICAgaWYgKCFzdGVwc1tTVEVQX0lWRl0pIHtcbiAgICAgICAgY29uc3QgZmxhdERlbGV0ZXMgPSByZWZzLm1hcChyZWYgPT4gKHsga2V5OiByZWYsIHZhbHVlOiB1bmRlZmluZWQgfSkpO1xuICAgICAgICB0cmFuc2FjdGlvbk11dGF0ZShmbGF0U3RvcmUoZGF0YWJhc2UpLCBmbGF0RGVsZXRlcyk7XG4gICAgICAgIGZvciAoY29uc3QgcmVmIG9mIHJlZnMpIHtcbiAgICAgICAgICAgIGRhdGFiYXNlLmRlbGV0ZURhdGEocm9vdCA9PiByb290LmJ5UmVmW3JlZl0pO1xuICAgICAgICB9XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIE1hdGgubWF4KDAsIGNvdW50IC0gcmVmcy5sZW5ndGgpKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNlbnRyb2lkcyA9IHRyYW5zYWN0aW9uUmVhZChjZW50cm9pZFN0b3JlKGRhdGFiYXNlKSk7XG4gICAgaWYgKCFjZW50cm9pZHMpIHJldHVybjtcbiAgICBpZiAoIWNlbnRyb2lkcy5zaXplKSByZXR1cm47XG5cbiAgICAvLyBMb29rIHVwIGVhY2ggcmVmJ3MgZW1iZWRkaW5nIHRocm91Z2ggYnlSZWYsIHRoZW4gcmFuayBpdHMgY2VsbHMgdGhlIHdheSBhbiBpbnNlcnQgd291bGQsIHNvIHdlIGRlbGV0ZSBmcm9tIHRoZSBjZWxsIGl0IGFjdHVhbGx5IGxhbmRlZCBpbiAocGx1cyBhIGZldyBuZWlnaGJvdXJzLCBpbiBjYXNlIGEgcmVidWlsZCBudWRnZWQgaXQgYWNyb3NzIGEgYm91bmRhcnkpLlxuICAgIGNvbnN0IHJlZlZhbHVlcyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gcmVmcy5tYXAocmVmID0+IHJvb3QuYnlSZWZbcmVmXSkpO1xuICAgIGlmICghcmVmVmFsdWVzKSByZXR1cm47XG4gICAgY29uc3QgY2FuZGlkYXRlc0J5SXRlbTogeyByZWY6IHN0cmluZzsgY2VsbElkczogc3RyaW5nW10gfVtdID0gW107XG4gICAgY29uc3QgY2FuZGlkYXRlU2V0ID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHJlZnMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcmVmVmFsdWVzW2luZGV4XTtcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZW1iZWRkaW5nID0gZGVjb2RlUmVmVmFsdWUodmFsdWUpO1xuICAgICAgICBjb25zdCBjZWxsSWRzID0gcmFua0NlbGxzQnlDbG9zZW5lc3MoZW1iZWRkaW5nLCBjZW50cm9pZHMpLnNsaWNlKDAsIDEgKyBERUxFVEVfRkFMTEJBQ0tfQ0VMTFMpO1xuICAgICAgICBjYW5kaWRhdGVzQnlJdGVtLnB1c2goeyByZWY6IHJlZnNbaW5kZXhdLCBjZWxsSWRzIH0pO1xuICAgICAgICBmb3IgKGNvbnN0IGNlbGxJZCBvZiBjZWxsSWRzKSB7XG4gICAgICAgICAgICBjYW5kaWRhdGVTZXQuYWRkKGNlbGxJZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjYW5kaWRhdGVDZWxsSWRzID0gQXJyYXkuZnJvbShjYW5kaWRhdGVTZXQpO1xuICAgIGNvbnN0IHN0b3JlcyA9IGRhdGFiYXNlLnJlYWREYXRhKHJvb3QgPT4gY2FuZGlkYXRlQ2VsbElkcy5tYXAoY2VsbElkID0+IHJvb3QuY2VsbHNbY2VsbElkXSkpO1xuICAgIGlmICghc3RvcmVzKSByZXR1cm47XG4gICAgY29uc3QgbWVtYmVyc0J5Q2VsbCA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBTdG9yZWRFbWJlZGRpbmc+PigpO1xuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjYW5kaWRhdGVDZWxsSWRzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICBtZW1iZXJzQnlDZWxsLnNldChjYW5kaWRhdGVDZWxsSWRzW2luZGV4XSwgcmVwbGF5VHJhbnNhY3Rpb25TdG9yZShzdG9yZXNbaW5kZXhdKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZGVsZXRlc0J5Q2VsbCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmdbXT4oKTtcbiAgICBjb25zdCBkZWxldGVkUmVmczogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBjYW5kaWRhdGVzQnlJdGVtKSB7XG4gICAgICAgIGZvciAoY29uc3QgY2VsbElkIG9mIGNhbmRpZGF0ZS5jZWxsSWRzKSB7XG4gICAgICAgICAgICBjb25zdCBtZW1iZXJzID0gbWVtYmVyc0J5Q2VsbC5nZXQoY2VsbElkKTtcbiAgICAgICAgICAgIGlmICghbWVtYmVycyB8fCAhbWVtYmVycy5oYXMoY2FuZGlkYXRlLnJlZikpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCBjZWxsUmVmcyA9IGRlbGV0ZXNCeUNlbGwuZ2V0KGNlbGxJZCk7XG4gICAgICAgICAgICBpZiAoIWNlbGxSZWZzKSB7XG4gICAgICAgICAgICAgICAgY2VsbFJlZnMgPSBbXTtcbiAgICAgICAgICAgICAgICBkZWxldGVzQnlDZWxsLnNldChjZWxsSWQsIGNlbGxSZWZzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNlbGxSZWZzLnB1c2goY2FuZGlkYXRlLnJlZik7XG4gICAgICAgICAgICBkZWxldGVkUmVmcy5wdXNoKGNhbmRpZGF0ZS5yZWYpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNlbGxJZCBvZiBkZWxldGVzQnlDZWxsLmtleXMoKSkge1xuICAgICAgICBjb25zdCBjZWxsUmVmcyA9IGRlbGV0ZXNCeUNlbGwuZ2V0KGNlbGxJZCkhO1xuICAgICAgICBjb25zdCBtZW1iZXJEZWxldGVzID0gY2VsbFJlZnMubWFwKHJlZiA9PiAoeyBrZXk6IHJlZiwgdmFsdWU6IHVuZGVmaW5lZCB9KSk7XG4gICAgICAgIHRyYW5zYWN0aW9uTXV0YXRlKGNlbGxTdG9yZShkYXRhYmFzZSwgY2VsbElkKSwgbWVtYmVyRGVsZXRlcyk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgcmVmIG9mIGRlbGV0ZWRSZWZzKSB7XG4gICAgICAgIGRhdGFiYXNlLmRlbGV0ZURhdGEocm9vdCA9PiByb290LmJ5UmVmW3JlZl0pO1xuICAgIH1cbiAgICBpZiAoZGVsZXRlZFJlZnMubGVuZ3RoKSB7XG4gICAgICAgIGRhdGFiYXNlLndyaXRlRGF0YShyb290ID0+IHJvb3QuY291bnQsIE1hdGgubWF4KDAsIGNvdW50IC0gZGVsZXRlZFJlZnMubGVuZ3RoKSk7XG4gICAgfVxufVxuIl19
398
+ /* _JS_SOURCE_HASH = "7738edfe7274720d37653564293cf51b8d98ca738046a46cc7458562ed13a7bf"; */
@@ -62,6 +62,19 @@ function rankCellsByCloseness(embedding: StoredEmbedding, centroids: Map<string,
62
62
  return ranked.map(entry => entry.cellId);
63
63
  }
64
64
 
65
+ // Synced functions rerun (and are predicted client-side), so the rebalance roll must be identical on every run of the same call — derive it from the inserted items instead of Math.random(). FNV-1a over each ref plus its embedding hash, mapped to [0, 1).
66
+ function seededRandomFromItems(items: EmbeddingInput[]): number {
67
+ let hash = 2166136261;
68
+ for (const item of items) {
69
+ const key = item.ref + hashEmbedding(item.embedding);
70
+ for (let index = 0; index < key.length; index++) {
71
+ hash ^= key.charCodeAt(index);
72
+ hash = Math.imul(hash, 16777619);
73
+ }
74
+ }
75
+ return (hash >>> 0) / 2 ** 32;
76
+ }
77
+
65
78
  // Per-write chance of a full rebuild. Zero at/under the target size, then rises (cubically) past it so cells stay roughly between target and ~2x target.
66
79
  function rebalanceProbability(fillRatio: number): number {
67
80
  if (fillRatio <= 1) {
@@ -316,10 +329,10 @@ export function insertEmbeddings(
316
329
  }
317
330
  }
318
331
  const averageFill = newCount / Math.max(1, centroids.size) / config.cellTargetSize;
319
- if (Math.random() < rebalanceProbability(averageFill)) {
320
- rebuildStructure(database);
332
+ if (seededRandomFromItems(items) < rebalanceProbability(averageFill)) {
333
+ return true;
321
334
  }
322
- return true;
335
+ return false;
323
336
  };
324
337
  if (shouldRegenerate(database)) {
325
338
  rebuildStructure(database);
@@ -19,6 +19,13 @@ export declare class ArchivesChain implements IArchives {
19
19
  private runPrimary;
20
20
  /** Races call against a size-based deadline. Uploads know their size upfront; gets are given SMART_TIMEOUT_PROBE to produce anything, and only then is the file's info fetched (from the same source, itself time-limited) to size the deadline - measured from the call's start, so a source that was slow before the probe doesn't get the full allowance again. Timed-out calls keep running in the background (they cannot be cancelled) but their eventual result is ignored. */
21
21
  private applySmartTimeout;
22
+ /** Runs one call under a window that can be pushed back while it runs. The window covers the
23
+ next piece of work rather than the whole call, so nothing has to guess how long a transfer
24
+ "should" take from its size: as long as pieces keep landing, the call keeps its time.
25
+
26
+ The waiting is a loop rather than one race, because a refresh that arrives while we are
27
+ already waiting has to move the deadline we are waiting on. */
28
+ private applyRefreshableTimeout;
22
29
  private lastConfigRefresh;
23
30
  private prepareWrongTargetRetry;
24
31
  private request;
@@ -55,6 +62,18 @@ export declare class ArchivesChain implements IArchives {
55
62
  size?: undefined;
56
63
  url: string;
57
64
  }>;
65
+ /** Reads a whole file as a series of ranged reads, so a big one arrives in pieces instead of
66
+ as one request nobody can see inside of.
67
+
68
+ The first read asks for CHUNK_FIRST_SIZE. Less than that coming back IS the whole file, so
69
+ a small file costs exactly one request - and because every backend reports the file's FULL
70
+ size alongside a ranged read, a big one already knows its size from that same answer and
71
+ never needs a getInfo to find out.
72
+
73
+ Every chunk after the first goes to the source that served the first, so the pieces cannot
74
+ be assembled out of two different versions living on two replicas. Finishing a chunk pushes
75
+ the timeout back, so the deadline covers one chunk rather than the whole transfer. */
76
+ private readInChunks;
58
77
  getInfo(fileName: string, config?: GetInfoConfig): Promise<{
59
78
  writeTime: number;
60
79
  size: number;
@@ -31,22 +31,42 @@ const PRIMARY_RETRY_TIMEOUT = 30 * 1000;
31
31
  const PRIMARY_RETRY_DELAY = 2 * 1000;
32
32
  const COVERING_RETRY_TIMEOUT = 30 * 1000;
33
33
  const COVERING_RETRY_DELAY = 5 * 1000;
34
- // Smart timeouts: an attempt gets this long to produce anything before we probe getInfo for the file's size (and the probe itself gets the same window)
35
- const SMART_TIMEOUT_PROBE = 60 * 1000;
36
- // Very generous assumed transfer rates - the resulting deadline exists to catch stuck sources, not slow ones
37
- const SMART_TIMEOUT_DOWNLOAD_BYTES_PER_SECOND = 1024 * 1024;
38
- const SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND = 512 * 1024;
39
- // Marker in smart-timeout errors, so the read loop can log them and continue with the other sources (a connected source's other errors still throw)
34
+ // A read waits this long for its FIRST chunk, and the window grows to CHUNK_TIMEOUT_MAX as the
35
+ // download goes on - the further in we are, the more a restart costs, so the more patience is
36
+ // worth it. Not size based: the window covers one chunk, and finishing a chunk resets it.
37
+ const CHUNK_TIMEOUT_START = 60 * 1000;
38
+ const CHUNK_TIMEOUT_MAX = 5 * 60 * 1000;
39
+ // How many chunks the window takes to grow from START to MAX, linearly
40
+ const CHUNK_TIMEOUT_RAMP = 10;
41
+ // The first read asks for this much. Anything smaller coming back IS the whole file, so a small
42
+ // file costs exactly one request and never touches getInfo.
43
+ const CHUNK_FIRST_SIZE = 1024 * 1024;
44
+ // Chunks double from CHUNK_FIRST_SIZE up to this, so a big file stops paying per-request latency
45
+ const CHUNK_MAX_SIZE = 32 * 1024 * 1024;
46
+ // A file rewritten under us is read again from the start. After this many it is not worth chasing,
47
+ // and the plain unranged read - one request, one version, no assembly - is the way to get it.
48
+ const MAX_MODIFIED_RETRIES = 3;
49
+ // Uploads still get one deadline sized from the bytes they carry: a flat base plus the transfer
50
+ // at a very generous assumed rate, so a tiny upload still gets the full base window
51
+ const SMART_TIMEOUT_UPLOAD_BASE = 60 * 1000;
52
+ const SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND = 256 * 1024;
53
+ // Marker in timeout errors, so the read loop can log them and continue with the other sources (a connected source's other errors still throw)
40
54
  const SMART_TIMEOUT_MARKER = "ARCHIVES_SMART_TIMEOUT_c41a9d";
41
55
 
42
- // Sizes a generous per-attempt deadline. Get-style calls pass path: the size is only fetched (via getInfo) when the call turns out to be slow. Set-style calls pass uploadBytes, which they already know.
56
+ // Sizes a generous per-attempt deadline for a set-style call, from the bytes it already knows it is sending.
43
57
  type SmartTimeout = {
44
- path?: string;
45
58
  uploadBytes?: number;
46
59
  // Names the operation in timeout errors - without it a deletion (a tombstone write, uploadBytes 0) reads as "Upload of 0 bytes", which looks like a bug rather than a delete
47
60
  label?: string;
48
61
  };
49
62
 
63
+ /** The window for the chunk at this index: CHUNK_TIMEOUT_START, growing linearly to
64
+ CHUNK_TIMEOUT_MAX over CHUNK_TIMEOUT_RAMP chunks. */
65
+ function chunkTimeout(chunkIndex: number) {
66
+ let ramp = Math.min(chunkIndex, CHUNK_TIMEOUT_RAMP) / CHUNK_TIMEOUT_RAMP;
67
+ return CHUNK_TIMEOUT_START + (CHUNK_TIMEOUT_MAX - CHUNK_TIMEOUT_START) * ramp;
68
+ }
69
+
50
70
  /** The address, port, account, and bucket name a bucket routing URL addresses. Throws when the URL isn't a hosted bucket routing URL (https://host:port/file/<account>/<bucketName>/storage/storagerouting.json). */
51
71
  export { parseHostedUrl, parseBackblazeUrl, getBucketBaseUrl } from "./remoteConfig";
52
72
 
@@ -257,38 +277,47 @@ export class ArchivesChain implements IArchives {
257
277
  let abandon = () => void callPromise.then(() => { }, () => { });
258
278
  if (timeout.uploadBytes !== undefined) {
259
279
  // A flat base plus the predicted transfer time, so tiny uploads still get the full base window
260
- let allowed = SMART_TIMEOUT_PROBE + timeout.uploadBytes / SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND * 1000;
280
+ let allowed = SMART_TIMEOUT_UPLOAD_BASE + timeout.uploadBytes / SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND * 1000;
261
281
  let result = await Promise.race([callPromise.then(value => ({ value })), delay(allowed).then(() => undefined)]);
262
282
  if (result) return result.value;
263
283
  abandon();
264
- throw new Error(`${SMART_TIMEOUT_MARKER} Upload timed out. ${timeout.label || `Upload of ${timeout.uploadBytes} bytes`} to ${source.getDebugName()} timed out after ${Date.now() - start}ms (allowed ${Math.round(allowed)}ms: ${SMART_TIMEOUT_PROBE}ms base plus transfer at an assumed ${SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND} bytes/s)`);
265
- }
266
- const path = timeout.path;
267
- if (path === undefined) return await callPromise;
268
- let first = await Promise.race([callPromise.then(value => ({ value })), delay(SMART_TIMEOUT_PROBE).then(() => undefined)]);
269
- if (first) return first.value;
270
- let probeError: string | undefined;
271
- let info: { size: number } | undefined;
272
- try {
273
- info = await Promise.race([
274
- source.read(archives => archives.getInfo(path)).then(x => ({ size: x && x.size || 0 })),
275
- delay(SMART_TIMEOUT_PROBE).then(() => undefined),
276
- ]);
277
- } catch (e) {
278
- probeError = String((e as Error).stack ?? e);
279
- }
280
- if (!info) {
281
- abandon();
282
- throw new Error(`${SMART_TIMEOUT_MARKER} Read timed out with no size probe. Read of ${JSON.stringify(path)} from ${source.getDebugName()}: no result after ${Date.now() - start}ms, and getInfo ${probeError && `failed (${probeError})` || `could not answer within ${SMART_TIMEOUT_PROBE}ms either`}`);
284
+ throw new Error(`${SMART_TIMEOUT_MARKER} Upload timed out. ${timeout.label || `Upload of ${timeout.uploadBytes} bytes`} to ${source.getDebugName()} timed out after ${Date.now() - start}ms (allowed ${Math.round(allowed)}ms: ${SMART_TIMEOUT_UPLOAD_BASE}ms base plus transfer at an assumed ${SMART_TIMEOUT_UPLOAD_BYTES_PER_SECOND} bytes/s)`);
283
285
  }
284
- let allowed = Math.max(SMART_TIMEOUT_PROBE, info.size / SMART_TIMEOUT_DOWNLOAD_BYTES_PER_SECOND * 1000);
285
- let remaining = start + allowed - Date.now();
286
- if (remaining > 0) {
287
- let second = await Promise.race([callPromise.then(value => ({ value })), delay(remaining).then(() => undefined)]);
288
- if (second) return second.value;
286
+ return await callPromise;
287
+ }
288
+
289
+ /** Runs one call under a window that can be pushed back while it runs. The window covers the
290
+ next piece of work rather than the whole call, so nothing has to guess how long a transfer
291
+ "should" take from its size: as long as pieces keep landing, the call keeps its time.
292
+
293
+ The waiting is a loop rather than one race, because a refresh that arrives while we are
294
+ already waiting has to move the deadline we are waiting on. */
295
+ private async applyRefreshableTimeout<T>(
296
+ config: { label: string; sourceUrl: string; windowMs: number },
297
+ call: (refresh: (windowMs: number) => void) => Promise<T>,
298
+ ): Promise<T> {
299
+ let start = Date.now();
300
+ let windowMs = config.windowMs;
301
+ let deadline = Date.now() + windowMs;
302
+ let refresh = (nextWindowMs: number) => {
303
+ windowMs = nextWindowMs;
304
+ deadline = Date.now() + nextWindowMs;
305
+ };
306
+ let callPromise = call(refresh);
307
+ // An abandoned call must not surface an unhandled rejection when it eventually fails
308
+ let abandon = () => void callPromise.then(() => { }, () => { });
309
+ while (true) {
310
+ let remaining = deadline - Date.now();
311
+ if (remaining <= 0) {
312
+ abandon();
313
+ throw new Error(
314
+ `${SMART_TIMEOUT_MARKER} ${config.label} from ${config.sourceUrl} timed out after`
315
+ + ` ${Date.now() - start}ms: nothing arrived within the last ${Math.round(windowMs)}ms`
316
+ );
317
+ }
318
+ let result = await Promise.race([callPromise.then(value => ({ value })), delay(remaining).then(() => undefined)]);
319
+ if (result) return result.value;
289
320
  }
290
- abandon();
291
- throw new Error(`${SMART_TIMEOUT_MARKER} Read timed out. Read of ${JSON.stringify(path)} (${info.size} bytes) from ${source.getDebugName()} timed out after ${Date.now() - start}ms (allowed ${Math.round(allowed)}ms from the call's start, at an assumed ${SMART_TIMEOUT_DOWNLOAD_BYTES_PER_SECOND} bytes/s)`);
292
321
  }
293
322
 
294
323
  private lastConfigRefresh = 0;
@@ -355,12 +384,16 @@ export class ArchivesChain implements IArchives {
355
384
  // A specific source leaves nothing for the latency ordering to decide
356
385
  return await this.get2(fileName, config);
357
386
  }
358
- return await this.request({ fallbacks: !config?.noFallbacks, route: getRoute(fileName), retries: config?.retries, fast: true, timeout: { path: fileName } }, async (archives, url) => {
359
- let result = await archives.get2(fileName, config);
360
- // Empty data is a tombstone, not content - see get2
361
- if (!result || !result.data || !result.data.length && !config?.includeTombstones && !(config?.range && result.size)) return { url };
362
- return { data: result.data, writeTime: result.writeTime, size: result.size, url };
363
- });
387
+ if (config?.range) {
388
+ return await this.request({ fallbacks: !config?.noFallbacks, route: getRoute(fileName), retries: config?.retries, fast: true }, async (archives, url) => {
389
+ let result = await archives.get2(fileName, config);
390
+ // Empty data is a tombstone, not content - see get2
391
+ if (!result || !result.data || !result.data.length && !config?.includeTombstones && !(config?.range && result.size)) return { url };
392
+ return { data: result.data, writeTime: result.writeTime, size: result.size, url };
393
+ });
394
+ }
395
+ // Latency order decides who serves the FIRST chunk; the rest follow it, like any other read
396
+ return await this.readInChunks(fileName, config, { fast: true });
364
397
  }
365
398
  /** Always resolves with a url - the authority that answered. A value that doesn't exist is still an answer FROM a server, so it comes back as { url } with no data (never plain undefined); errors from every source throw instead. */
366
399
  public async get2(fileName: string, config?: GetConfig): Promise<{ data: Buffer; writeTime: number; size: number; url: string } | { data?: undefined; writeTime?: undefined; size?: undefined; url: string }> {
@@ -373,13 +406,91 @@ export class ArchivesChain implements IArchives {
373
406
  return { data: result.data, writeTime: result.writeTime, size: result.size, url: sourceUrl };
374
407
  });
375
408
  }
376
- return await this.request({ fallbacks: !config?.noFallbacks, route: getRoute(fileName), retries: config?.retries, timeout: { path: fileName } }, async (archives, url) => {
409
+ // A caller that named its own range asked for exactly those bytes, so it is one request.
410
+ if (config?.range) {
411
+ return await this.request({ fallbacks: !config?.noFallbacks, route: getRoute(fileName), retries: config?.retries }, async (archives, url) => {
412
+ let result = await archives.get2(fileName, config);
413
+ // Empty data is a tombstone, not content (unless the caller asked for tombstones) - a ranged read of a REAL file can legitimately be empty though (range past EOF), which the total size distinguishes
414
+ if (!result || !result.data || !result.data.length && !config?.includeTombstones && !(config?.range && result.size)) return { url };
415
+ return { data: result.data, writeTime: result.writeTime, size: result.size, url };
416
+ });
417
+ }
418
+ return await this.readInChunks(fileName, config);
419
+ }
420
+
421
+ /** Reads a whole file as a series of ranged reads, so a big one arrives in pieces instead of
422
+ as one request nobody can see inside of.
423
+
424
+ The first read asks for CHUNK_FIRST_SIZE. Less than that coming back IS the whole file, so
425
+ a small file costs exactly one request - and because every backend reports the file's FULL
426
+ size alongside a ranged read, a big one already knows its size from that same answer and
427
+ never needs a getInfo to find out.
428
+
429
+ Every chunk after the first goes to the source that served the first, so the pieces cannot
430
+ be assembled out of two different versions living on two replicas. Finishing a chunk pushes
431
+ the timeout back, so the deadline covers one chunk rather than the whole transfer. */
432
+ private async readInChunks(fileName: string, config?: GetConfig, options?: { fast?: boolean }): Promise<{ data: Buffer; writeTime: number; size: number; url: string } | { data?: undefined; writeTime?: undefined; size?: undefined; url: string }> {
433
+ for (let attempt = 1; attempt <= MAX_MODIFIED_RETRIES; attempt++) {
434
+ let first = await this.request({ fallbacks: !config?.noFallbacks, route: getRoute(fileName), retries: config?.retries, fast: options?.fast }, async (archives, url) => {
435
+ let result = await this.applyRefreshableTimeout(
436
+ { label: `The first ${CHUNK_FIRST_SIZE} bytes of ${JSON.stringify(fileName)}`, sourceUrl: url, windowMs: chunkTimeout(0) },
437
+ async () => await archives.get2(fileName, { ...config, range: { start: 0, end: CHUNK_FIRST_SIZE } }),
438
+ );
439
+ if (!result || !result.data || !result.data.length && !config?.includeTombstones && !result.size) return { url };
440
+ return { data: result.data, writeTime: result.writeTime, size: result.size, url };
441
+ });
442
+ if (!first.data) return first;
443
+ // The whole file fit in the first read, so there is nothing else to fetch and nothing
444
+ // that could have changed underneath us
445
+ if (first.data.length >= first.size) {
446
+ return first;
447
+ }
448
+
449
+ let url = first.url;
450
+ let pieces = [first.data];
451
+ let offset = first.data.length;
452
+ let chunkSize = CHUNK_FIRST_SIZE;
453
+ let torn = false;
454
+ for (let chunkIndex = 1; offset < first.size; chunkIndex++) {
455
+ chunkSize = Math.min(chunkSize * 2, CHUNK_MAX_SIZE);
456
+ let end = Math.min(offset + chunkSize, first.size);
457
+ let start = offset;
458
+ let piece = await this.applyRefreshableTimeout(
459
+ { label: `Bytes ${start}-${end} of ${JSON.stringify(fileName)}`, sourceUrl: url, windowMs: chunkTimeout(chunkIndex) },
460
+ async () => await this.runOnSource(url, archives => archives.get2(fileName, { ...config, range: { start, end } })),
461
+ );
462
+ // The file shrank under us, so what we have is already a mix of two versions
463
+ if (!piece || !piece.data || !piece.data.length) {
464
+ torn = true;
465
+ break;
466
+ }
467
+ pieces.push(piece.data);
468
+ offset += piece.data.length;
469
+ }
470
+
471
+ // Read back to back rather than watched per chunk: one call at the end says whether
472
+ // everything we just assembled came from the same version of the file.
473
+ let after = !torn && await this.runOnSource(url, archives => archives.getInfo(fileName, config));
474
+ if (!torn && after && after.writeTime === first.writeTime && after.size === first.size) {
475
+ return { data: Buffer.concat(pieces), writeTime: first.writeTime, size: first.size, url };
476
+ }
477
+ console.warn(
478
+ `${JSON.stringify(fileName)} was written while we were reading it from ${url}`
479
+ + ` (${first.size} bytes at ${first.writeTime}, now ${after && `${after.size} bytes at ${after.writeTime}` || "gone"}).`
480
+ + ` Reading it again, attempt ${attempt} of ${MAX_MODIFIED_RETRIES}.`
481
+ );
482
+ }
483
+
484
+ // Whatever is rewriting it is faster than we can read it in pieces, so take it in one
485
+ // request: no assembly, no chance of two versions, and no ranged reads to keep in step.
486
+ console.warn(`${JSON.stringify(fileName)} kept changing while being read in chunks, reading it in one request instead`);
487
+ return await this.request({ fallbacks: !config?.noFallbacks, route: getRoute(fileName), retries: config?.retries }, async (archives, url) => {
377
488
  let result = await archives.get2(fileName, config);
378
- // Empty data is a tombstone, not content (unless the caller asked for tombstones) - a ranged read of a REAL file can legitimately be empty though (range past EOF), which the total size distinguishes
379
- if (!result || !result.data || !result.data.length && !config?.includeTombstones && !(config?.range && result.size)) return { url };
489
+ if (!result || !result.data || !result.data.length && !config?.includeTombstones) return { url };
380
490
  return { data: result.data, writeTime: result.writeTime, size: result.size, url };
381
491
  });
382
492
  }
493
+
383
494
  public async getInfo(fileName: string, config?: GetInfoConfig): Promise<{ writeTime: number; size: number; url: string } | undefined> {
384
495
  validateFileName(fileName, "getInfo");
385
496
  const sourceUrl = config?.sourceUrl;