sliftutils 1.7.54 → 1.7.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -2195,6 +2195,7 @@ declare module "sliftutils/storage/IArchives" {
2195
2195
  validWindow: [number, number];
2196
2196
  route?: [number, number];
2197
2197
  noFullSync?: boolean;
2198
+ intermediate?: boolean;
2198
2199
  identity?: string;
2199
2200
  };
2200
2201
  export declare const STORAGE_WRONG_VALID_WINDOW = "REMOTE_STORAGE_WRONG_VALID_WINDOW_a7c1f04e";
@@ -3040,6 +3041,7 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3040
3041
  validWindow: [number, number];
3041
3042
  route?: [number, number];
3042
3043
  noFullSync?: boolean;
3044
+ intermediate?: boolean;
3043
3045
  create: () => IArchives;
3044
3046
  };
3045
3047
  export declare class BlobStore implements IBucketStore {
@@ -3118,6 +3120,7 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3118
3120
  }>;
3119
3121
  private flushIndex;
3120
3122
  private runSourceSync;
3123
+ private isDeadIntermediate;
3121
3124
  private scanSource;
3122
3125
  private reconcileSource;
3123
3126
  private updateScanIndex;
@@ -3244,6 +3247,9 @@ declare module "sliftutils/storage/remoteStorage/createArchives" {
3244
3247
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
3245
3248
  private setRoutingConfig;
3246
3249
  del(fileName: string): Promise<void>;
3250
+ private getVariableShardTargets;
3251
+ /** The key setVariableShard would materialize for this VARIABLE_SHARD key (a value in the preferred shard's route range), without writing anything. */
3252
+ getShardKey(key: string): Promise<string>;
3247
3253
  private setVariableShard;
3248
3254
  setLargeFile(config: {
3249
3255
  path: string;
@@ -3251,7 +3257,7 @@ declare module "sliftutils/storage/remoteStorage/createArchives" {
3251
3257
  getNextData(): Promise<Buffer | undefined>;
3252
3258
  }): Promise<void>;
3253
3259
  getURL(path: string): Promise<string>;
3254
- /** Every URL that could serve this path, in source order. Empty when no public source covers the path's route. */
3260
+ /** Every URL that could serve this path, in source order: public sources matching both the path's route and the current valid window. Empty when none qualify. */
3255
3261
  getURLs(path: string): Promise<string[]>;
3256
3262
  dispose(): void;
3257
3263
  }
@@ -3426,11 +3432,11 @@ declare module "sliftutils/storage/remoteStorage/sourceWrapper" {
3426
3432
  private pings;
3427
3433
  private pingTimer;
3428
3434
  private loggedConnected;
3429
- /** Starts measuring this source's latency (for variable-shard target preference). Only hosted remotes are pinged; our own local server counts as 0, everything else as Infinity. */
3435
+ /** Starts measuring this source's latency, which decides which hosts reads and variable-shard writes prefer. Hosted remotes ping over their API connection; URL-only sources (read-only mode, backblaze without credentials) probe over plain HTTPS instead - the client NEEDS their latency too, or it cannot rank the hosts it reads from. Our own local server counts as 0; only sources with neither form stay Infinity. */
3430
3436
  startPinging(): void;
3431
3437
  /** Seeds the latency estimate before the first ping lands (e.g. from the initial routing fetch), so variable-shard picking has something immediately. Real pings take over from the first measurement on. */
3432
3438
  seedLatency(ms: number): void;
3433
- /** Median of the recent pings. Sources that can't be pinged sort last (Infinity), except our own in-process server, which is the best possible target (0). */
3439
+ /** Median of the recent pings (API or URL-form, whichever this source measures). Sources with no measurements yet sort last (Infinity), except our own in-process server, which is the best possible target (0). */
3434
3440
  getLatency(): number;
3435
3441
  /** Writes always go through the API, so a permission error throws to the caller on every write (and access granted in the meantime is picked up automatically). */
3436
3442
  write<T>(run: (archives: IArchives) => Promise<T>): Promise<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.7.54",
3
+ "version": "1.7.56",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -104,6 +104,7 @@ export type ArchivesSource = {
104
104
  validWindow: [number, number];
105
105
  route?: [number, number];
106
106
  noFullSync?: boolean;
107
+ intermediate?: boolean;
107
108
  identity?: string;
108
109
  };
109
110
  export declare const STORAGE_WRONG_VALID_WINDOW = "REMOTE_STORAGE_WRONG_VALID_WINDOW_a7c1f04e";
@@ -147,6 +147,8 @@ export type ArchivesSource = {
147
147
  route?: [number, number];
148
148
  // From the source's CommonConfig; see there.
149
149
  noFullSync?: boolean;
150
+ // From the source's CommonConfig: a deploy switchover's temporary alternate-port entry. Once its window is past, the port it points at is gone for good - so it is never scanned then, and scan failures are never retried.
151
+ intermediate?: boolean;
150
152
  // Stable identity of the underlying endpoint (its config with windows/routes stripped) - how BlobStore.updateSources recognizes a source across config changes so it can update it in place instead of removing and re-adding it
151
153
  identity?: string;
152
154
  };
@@ -71,5 +71,5 @@ async function copyArchiveFile(config) {
71
71
  return { writeTime: finalWriteTime, size: totalSize };
72
72
  }
73
73
  exports.copyArchiveFile = copyArchiveFile;
74
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSUFyY2hpdmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiSUFyY2hpdmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx3S0FBd0s7OztBQUV4SyxzSkFBc0o7QUFDekksUUFBQSx3QkFBd0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUV2RCx5TEFBeUw7QUFDNUssUUFBQSxvQkFBb0IsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2pELFNBQWdCLHVCQUF1QixDQUFDLFlBQW9CO0lBQ3hELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxnQ0FBd0IsQ0FBQztJQUNoRCxJQUFJLFlBQVksR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxZQUFZLE1BQU0sR0FBRyxxQkFBcUIsQ0FBQyxDQUFDO0lBQzFHLENBQUM7QUFDTCxDQUFDO0FBTEQsMERBS0M7QUF1RVksUUFBQSxpQkFBaUIsR0FBcUIsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFzRWhGLHdYQUF3WDtBQUMzVyxRQUFBLDBCQUEwQixHQUFHLDRDQUE0QyxDQUFDO0FBRXZGLDhMQUE4TDtBQUNqTCxRQUFBLG1CQUFtQixHQUFHLHFDQUFxQyxDQUFDO0FBRTVELFFBQUEsVUFBVSxHQUFxQixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVuRCwyUkFBMlI7QUFDOVEsUUFBQSxjQUFjLEdBQUcsNkNBQTZDLENBQUM7QUFDNUUsb0xBQW9MO0FBQ3BMLFNBQWdCLG1CQUFtQixDQUFDLFdBQXlDO0lBQ3pFLElBQUksQ0FBQyxXQUFXO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDOUIsT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUFIRCxrREFHQztBQUVELE1BQU0sb0JB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Q0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgaW1wb3J0YW50IG9wZXJhdGlvbnMgb2YgYW4gYXJjaGl2ZSBidWNrZXQgKGV4dHJhY3RlZCBmcm9tIEFyY2hpdmVzQmFja2JsYXplKSwgc28gb3RoZXIgYmFja2VuZHMgKGUuZy4gb3VyIG93biByZW1vdGUgc3RvcmFnZSBzZXJ2ZXIpIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseS5cblxuLy8gQSB3cml0ZSBtYXkgbm90IGJlIHN0YW1wZWQgbW9yZSB0aGFuIHRoaXMgZmFyIGluIHRoZSBmdXR1cmUsIG9yIGNsb2NrIHNrZXcgYmV0d2VlbiBtYWNoaW5lcyB3b3VsZCBsZXQgYSBiYWQgdGltZXN0YW1wIGJsb2NrIHdyaXRlcyBmb3IgYSBsb25nIHRpbWUuXG5leHBvcnQgY29uc3QgTUFYX0xBU1RfTU9ESUZJRURfRlVUVVJFID0gMTUgKiA2MCAqIDEwMDA7XG5cbi8vIEhvdyBsb25nIGJyb3dzZXJzIG1heSBjYWNoZSBmaWxlcyBmcm9tIGltbXV0YWJsZSBidWNrZXRzICh0aGUgQ2FjaGUtQ29udHJvbCBtYXgtYWdlKSwgc2hhcmVkIGJ5IGV2ZXJ5IGhvc3RpbmcgcGF0aCAoYmFja2JsYXplIGJ1Y2tldCBzZXR0aW5ncyBhbmQgb3VyIG93biBzdG9yYWdlIHNlcnZlcidzIEhUVFAgcm91dGUpXG5leHBvcnQgY29uc3QgSU1NVVRBQkxFX0NBQ0hFX1RJTUUgPSA4NjQwMCAqIDEwMDA7XG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0VmFsaWRMYXN0TW9kaWZpZWQobGFzdE1vZGlmaWVkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBsZXQgbWF4ID0gRGF0ZS5ub3coKSArIE1BWF9MQVNUX01PRElGSUVEX0ZVVFVSRTtcbiAgICBpZiAobGFzdE1vZGlmaWVkID4gbWF4KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbGFzdE1vZGlmaWVkIGlzIHRvbyBmYXIgaW4gdGhlIGZ1dHVyZTogJHtsYXN0TW9kaWZpZWR9ID4gJHttYXh9IChub3cgKyAxNSBtaW51dGVzKWApO1xuICAgIH1cbn1cblxuXG5leHBvcnQgdHlwZSBSZW1vdGVDb25maWcgPSB7XG4gICAgLy8gTk9URTogVmVyc2lvbiBpcyB1c2VkIHdoZW4gdXBkYXRpbmcgdGhlIGNvbmZpZ3VyYXRpb24uIFRoZSBuZXdlciB2ZXJzaW9uIGlzIGFsd2F5cyB0YWtlbi4gQSBtaXNzaW5nIHZlcnNpb24gY291bnRzIGFzIHZlcnNpb24gLTEuXG4gICAgdmVyc2lvbj86IG51bWJlcjtcbiAgICBzb3VyY2VzOiBSZW1vdGVDb25maWdCYXNlW107XG59O1xuXG4vKipcbiAgICBzdHJpbmcgYXJndW1lbnRzIHdpbGwgYmUgYSB1cmwsIGxvb2tpbmcgbGlrZTpcbiAgICAgICAgaHR0cHM6Ly9zdG9yYWdlMi52aWRncmlkd2ViLmNvbTo0NDQ1L2ZpbGUvZXhhbXBsZWFjY291bnQvZXhhbXBsZWJ1Y2tldC9zdG9yYWdlL3N0b3JhZ2Vyb3V0aW5nLmpzb25cbiAgICAgICAgaHR0cHM6Ly9mMDAyLmJhY2tibGF6ZWIyLmNvbS9maWxlL3F1ZXJ5c3VidGVzdC1jb20tcHVibGljLWltbXV0YWJsZS9zdG9yYWdlL3N0b3JhZ2Vyb3V0aW5nLmpzb25cbiAgICAgICAgLSBUaGVzZSBtYXAgdG8geyB1cmwgfSwgd2l0aCB0aGUgdHlwZSBpbmZlcnJlZCBmcm9tIHRoZSB1cmxcbiAgICAgICAgLSBIb3N0ZWQgdXJscyBhcmUgL2ZpbGUvPGFjY291bnQ+LzxidWNrZXROYW1lPi8uLi4sIGJhY2tibGF6ZSB1cmxzIGFyZSAvZmlsZS88YnVja2V0TmFtZT4vLi4uXG5cbiAgICBOT1RFOiBJZiB3ZSBkbyBub3QgaGF2ZSByaWdodCBhY2Nlc3MgdG8gdGhlc2UsIHRoZW4gaXQgYmVjb21lcyBhIHJlYWQtb25seSBJQXJjaGl2ZXMsIHdoZXJlIHdlIHNvbGVseSByZWFkIHVzaW5nIHRoZSB1cmwgZm9ybSAod2hpY2ggbWlnaHQgdGhyb3cgZHVlIHRvIG5vdCBoYXZpbmcgYWNjZXNzIGFzIHdlbGwpLiBVTkxFU1MgT3VyIGNvbmZpZ3VyYXRpb24gZXhwbGljaXRseSBoYXMgcHVibGljOiBmYWxzZSwgaW4gd2hpY2ggY2FzZSwgd2UgZG9uJ3QgZXZlbiBoaXQgdGhlIFVSTCBhbmQgd2UgdGhyb3cgb24gYWNjZXNzLlxuXG4gICAgTk9URTogSWYgd2UncmUgaW4gdGhlIGJyb3dzZXIsIHdlIHNob3VsZCBhbGxvdyBkb3dubG9hZGluZyB0aGUgZmlsZXMgdmlhIHRoZSBVUkwgZm9ybSAoaWYgaXQncyBhIHB1YmxpYyBidWNrZXQpLCBob3dldmVyLCB3ZSB3b24ndCBhbGxvdyB3cml0aW5nLCBiZWNhdXNlIHRoZWlyIHNlcnZlcnMgZG8gbm90IGFsbG93IHNlY3VyZSBicm93c2VyIHdyaXRlcy5cbiovXG5leHBvcnQgdHlwZSBSZW1vdGVDb25maWdCYXNlID0gc3RyaW5nIHwgSG9zdGVkQ29uZmlnIHwgQmFja2JsYXplQ29uZmlnO1xuXG5leHBvcnQgdHlwZSBDb21tb25Db25maWcgPSB7XG4gICAgLyoqIEJ5IGRlZmF1bHQgYSBzZXJ2ZXIgaG9zdGluZyB0aGlzIGJ1Y2tldCBlYWdlcmx5IGNvcGllcyB0aGlzIHNvdXJjZSdzIGZ1bGwgY29udGVudHMgb250byBpdHMgb3duIGRpc2sgKG9uIHRvcCBvZiB0aGUgbGF6eSByZWFkLXRocm91Z2ggY2FjaGluZykuIFNldCB0aGlzIHRvIGJlIGEgZnJvbnQgZW5kIGZvciBhIHZlcnkgbGFyZ2UgZGF0YWJhc2Ugd2l0aG91dCBjb3B5aW5nIHRoZSBmdWxsIGRhdGFiYXNlIC0gcmVhZHMgc3RpbGwgZG93bi1jYWNoZSBpbmRpdmlkdWFsIGZpbGVzIG9uIGRlbWFuZC4gKi9cbiAgICBub0Z1bGxTeW5jPzogYm9vbGVhbjtcbiAgICAvKiogQnl0ZXMgb2YgcmVhZC1jYWNoZSB0aGlzIHNlcnZlcidzIGRpc2sgbWF5IGhvbGQ7IGxlYXN0LXJlY2VudGx5LXVzZWQgZmlsZXMgYXJlIGRlbGV0ZWQgZnJvbSBkaXNrIHRvIHN0YXkgdW5kZXIgaXQgKG9ubHkgZXZlciB3aGVuIGFub3RoZXIgc291cmNlIHZlcmlmaWFibHkgaG9sZHMgdGhlIGZpbGUgLSB0aGUgb25seSBjb3B5IGlzIG5ldmVyIGRlbGV0ZWQpLiBSZXF1aXJlcyBub0Z1bGxTeW5jIChhIGZ1bGwgY29weSBjYW4ndCBiZSBib3VuZGVkKS4gKi9cbiAgICByZWFkZXJEaXNrTGltaXQ/OiBudW1iZXI7XG4gICAgLyoqIFRoZSB3cml0ZSB0aW1lcyAoW3N0YXJ0TXMsIGVuZE1zXSkgdGhpcyBzb3VyY2UgaXMgdmFsaWQgZm9yIChzZWUgQXJjaGl2ZXNTb3VyY2UudmFsaWRXaW5kb3cgZm9yIHRoZSBzeW5jaHJvbml6YXRpb24gc2VtYW50aWNzKS4gUmVxdWlyZWQgb24gb2JqZWN0IGNvbmZpZ3M6IGNvbmZpZ3VyYXRpb24gY2hhbmdlcyBtdXN0IGJlIFNDSEVEVUxFRCAoYSBuZXcgc291cmNlIGJlY29tZXMgdmFsaWQgYXQgYSBmdXR1cmUgdGltZSB3aGlsZSB0aGUgb2xkIG9uZSdzIHdpbmRvdyBlbmRzKSwgbm90IGZsaXBwZWQgaW5zdGFudGx5LiBQbGFpbiBVUkwtc3RyaW5nIHNvdXJjZXMgZGVmYXVsdCB0byBGVUxMX1ZBTElEX1dJTkRPVyAtIG9uY2UgeW91J3JlIHdyaXRpbmcgb2JqZWN0IGNvbmZpZ3MsIHlvdSdyZSBkb2luZyBzb21ldGhpbmcgY29tcGxpY2F0ZWQgZW5vdWdoIHRvIHRoaW5rIGFib3V0IHdoZW4gdGhpbmdzIGNoYW5nZS4gKi9cbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICAvKiogU2hhcmRpbmc6IHRoZSBmcmFjdGlvbiBvZiB0aGUga2V5IHNwYWNlIHRoaXMgc291cmNlIGhhbmRsZXMsIGFzIFtzdGFydCwgZW5kKSBvdmVyIFswLCAxKSAoa2V5cyBhcmUgcm91dGVkIGJ5IGdldFJvdXRlIGluIHJlbW90ZUNvbmZpZy50cykuIERlZmF1bHRzIHRvIEZVTExfUk9VVEUgKHVuc2hhcmRlZCkuIEF0IGV2ZXJ5IHBvaW50IGluIHRpbWUgdGhlIHNvdXJjZXMnIHJvdXRlcyBtdXN0IGZ1bGx5IGNvdmVyIFswLCAxKSwgb3Igc29tZSBrZXlzIGNvdWxkIG5ldmVyIGJlIHJlYWQuICovXG4gICAgcm91dGU/OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIC8qKiBTZXQgb24gZW50cmllcyBpbmplY3RlZCBpbnRvIHRoZSBpbi1tZW1vcnkgY29uZmlnIGJ5IGFuIG92ZXJsYXkgKGEgZGVwbG95IHN3aXRjaG92ZXIncyBhbHRlcm5hdGUtcG9ydCB3aW5kb3cpLiBOZXZlciB3cml0dGVuIHRvIGRpc2s6IHJlc29sdmVJbnRlcm1lZGlhdGVTb3VyY2VzIHN0cmlwcyB0aGVzZSBhbmQgcmVqb2lucyB0aGUgd2luZG93cyBhcm91bmQgdGhlbSwgd2hpY2ggaXMgYWxzbyBob3cgYSBjbGllbnQgdGVsbHMgd2hldGhlciBhbiB1cGRhdGUgaXMgYSByZWFsIGNvbmZpZ3VyYXRpb24gY2hhbmdlIG9yIGp1c3QgYW4gb3ZlcmxheS4gKi9cbiAgICBpbnRlcm1lZGlhdGU/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgSG9zdGVkQ29uZmlnID0gQ29tbW9uQ29uZmlnICYge1xuICAgIHR5cGU6IFwicmVtb3RlXCI7XG5cbiAgICAvLyBFeDogaHR0cHM6Ly85OS0yNTAtMTI0LTkxLnF1ZXJ5c3VidGVzdC5jb206NTIzMy9maWxlL3Jvb3QvdW5pcXVlYnVja2V0bmFtZS9zdG9yYWdlL3N0b3JhZ2Vyb3V0aW5nLmpzb25cbiAgICAvLyBOT1RFOiBUaGUgYWNjb3VudCBhbmQgYnVja2V0IG5hbWUgYXJlIG9idGFpbmVkIGZyb20gdGhlIFVSTC5cbiAgICB1cmw6IHN0cmluZztcblxuICAgIC8vIE5PVEU6IEF1dGhlbnRpY2F0aW9uIGlzIGhhbmRsZWQgYnkgY2VydC50cywgdmlhIGhhdmluZyB5b3VyIG1hY2hpbmUgdHJ1c3RlZCB0byBhY2Nlc3MgdGhpcyBhY2NvdW50LiBcblxuICAgIHB1YmxpYz86IGJvb2xlYW47XG4gICAgLy8gRmFzdCBtb2RlOiB0aGUgc2VydmVyIGFja25vd2xlZGdlcyB3cml0ZXMgb25jZSB0aGV5IGFyZSBpbiBtZW1vcnksIGZsdXNoaW5nIHRvIGRpc2sgYWZ0ZXIgd3JpdGVEZWxheSAoZGVmYXVsdCA1IG1pbnV0ZXMpIGFuZCBjb2FsZXNjaW5nIHdyaXRlcyB0byB0aGUgc2FtZSBmaWxlLiBBIHNlcnZlciBjcmFzaCBsb3NlcyB3cml0ZXMgdGhhdCBoYXZlbid0IGZsdXNoZWQgeWV0LlxuICAgIGZhc3Q/OiBib29sZWFuO1xuICAgIHdyaXRlRGVsYXk/OiBudW1iZXI7XG4gICAgLy8gVGhlIGJ1Y2tldCBpcyBzZXJ2ZWQgc3RyYWlnaHQgZnJvbSB0aGUgc2VydmVyJ3MgZGlzaywgd2l0aCBubyBpbmRleCDigJQgc28gbm8gZmFzdCB3cml0ZXMsIG5vIGdldFN5bmNTdGF0dXMsIGFuZCBnZXRDaGFuZ2VzQWZ0ZXIyIGZhbGxzIGJhY2sgdG8gYSBmdWxsIGxpc3RpbmcuXG4gICAgcmF3RGlzaz86IGJvb2xlYW47XG4gICAgLy8gV3JpdGVzIHRvIHBhdGhzIHRoYXQgYWxyZWFkeSBleGlzdCBhcmUgZGlzYWxsb3dlZCAoZGVsZXRlcyBzdGlsbCB3b3JrKS5cbiAgICBpbW11dGFibGU/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2JsYXplQ29uZmlnID0gQ29tbW9uQ29uZmlnICYge1xuICAgIHR5cGU6IFwiYmFja2JsYXplXCI7XG4gICAgLy8gRXg6IGh0dHBzOi8vZjAwMi5iYWNrYmxhemViMi5jb20vZmlsZS9xdWVyeXN1YnRlc3QtY29tLXB1YmxpYy1pbW11dGFibGUvc3RvcmFnZS9zdG9yYWdlcm91dGluZy5qc29uXG4gICAgLy8gTk9URTogVGhlIGJ1Y2tldCBuYW1lIGlzIG9idGFpbmVkIGZyb20gdGhlIFVSTC5cbiAgICB1cmw6IHN0cmluZztcbiAgICAvLyBQdWJsaWMgYnVja2V0cyBhcmUgc2VydmVkIG92ZXIgcGxhaW4gSFRUUFMgR0VUcyAoZ2V0VVJMKS4gUHJpdmF0ZSBidWNrZXRzIGFyZSBBUEktYWNjZXNzIG9ubHkuXG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICAvLyBOT1RFOiBUaGlzIGlzbid0IGVuZm9yY2VkIG9uIHRoZSBiYWNrYmxhemUgbGV2ZWwsIHNvIHRoaXMgaXMganVzdCBhIGNsaWVudC1zaWRlIGd1YXJhbnRlZS4gVGhpcyBjYW4gY2hhbmdlIGhvdyB3ZSBjYWNoZSBmaWxlcy5cbiAgICAvLyAgLSBCYWNrYmxhemUgZG9lcyBzdXBwb3J0IGltbXV0YWJpbGl0eS4gSG93ZXZlciwgYXBwYXJlbnRseSwgb25jZSB3ZSBlbmFibGUgaXQgb24gYSBidWNrZXQsIHdlIGNhbid0IGRpc2FibGUgaXQsIHdoaWNoIGlzIHJlYWxseSBiYWQsIGFzIGl0IG1lYW5zIGlmIG91ciBjb2RlIGNvdWxkIGV2ZXIgZW5hYmxlIGl0IGFuZCB3ZSBhY2NpZGVudGFsbHkgZW5hYmxlIGl0IG9uIGFuIGltcG9ydGFudCBidWNrZXQsIHdlIGVzc2VudGlhbGx5IGp1c3QgYnJpY2tlZCB0aGF0IGJ1Y2tldC4gU28gd2Ugc2hvdWxkIG5ldmVyIHdyaXRlIGFueSBjb2RlIHRoYXQgZXZlciB0cmllcyB0byB1c2UgYmFja2JsYXplIHRvIG1ha2UgdGhpbmdzIGltbXV0YWJsZS4gXG4gICAgaW1tdXRhYmxlPzogYm9vbGVhbjtcbiAgICAvLyBDT1JTIG9yaWdpbnMgYWxsb3dlZCB0byBjb25zdW1lIHRoZSBidWNrZXQncyBmaWxlcyBpbiBhIGJyb3dzZXIuIE5vdCBhIHNlY3VyaXR5IGJvdW5kYXJ5IChhY2Nlc3MgaXMgZ2F0ZWQgYnkgdGhlIEFQSSBrZXkgLyBzaWduZWQgVVJMcywgbmVpdGhlciBvZiB3aGljaCByaWRlcyBpbiBjb29raWVzKSAtIGl0IG9ubHkgY29udHJvbHMgd2hpY2ggc2l0ZXMnIGluLXBhZ2UgSmF2YVNjcmlwdCBjYW4gcmVhZCByZXNwb25zZXMuIERlZmF1bHRzIHRvIGFueSBIVFRQUyBvcmlnaW4uXG4gICAgYWxsb3dlZE9yaWdpbnM/OiBzdHJpbmdbXTtcblxuICAgIC8vIE5PVEU6IFdlIHdpbGwgYWNjZXNzIHRoZSBhcGkga2V5IGZyb20gZ2V0U2VjcmV0LCBzZWUgYmFja2JsYXplLnRzIGZvciB0aGUgc3BlY2lmaWMga2V5cy5cbn07XG5cblxuZXhwb3J0IGNvbnN0IEZVTExfVkFMSURfV0lORE9XOiBbbnVtYmVyLCBudW1iZXJdID0gWzAsIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXTtcblxuXG5cblxuZXhwb3J0IHR5cGUgR2V0Q29uZmlnID0ge1xuICAgIHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9O1xuICAgIC8qKiBSZWFkIE9OTFkgZnJvbSB0aGUgcHJpbWFyeSBzb3VyY2UgLSB0aGUgb25lIHdyaXRlcyB3b3VsZCB0YXJnZXQgLSBpbnN0ZWFkIG9mIGZhbGxpbmcgYmFjayBhY3Jvc3MgdGhlIHJlZHVuZGFudCBzb3VyY2VzLiBVc2UgdGhpcyB3aGVuIHlvdSB3YW50IHlvdXIgcmVhZHMgYW5kIHdyaXRlcyB0byBiZSBzb21ld2hhdCBhdG9taWM6IHRoZXJlIHdpbGwgc3RpbGwgYmUgaXNzdWVzIHdpdGggdGhlIHJvdW5kIHRyaXAsIGJ1dCB3aXRob3V0IGl0IHlvdSBjb3VsZCB0YWxrIHRvIGEgY29tcGxldGVseSBkaWZmZXJlbnQgbm9kZSBhbmQgZ2V0IGEgbXVjaCBvbGRlciB2YWx1ZS4gTW9zdCByZWFkcyBhcmVuJ3QgZm9sbG93ZWQgYnkgYSB3cml0ZSB0aG91Z2gsIHNvIGZvciBtb3N0IGNhc2VzIGl0J3MgYmV0dGVyIHRvIGdldCBhIHZhbHVlIHRoYW4gdG8gaGF2ZSB0byB3YWl0IChvciBldmVuIHRocm93KSB3aGVuIHRoZSBwcmltYXJ5IG5vZGUgaXMgbm90IGF2YWlsYWJsZS4gKi9cbiAgICBub0ZhbGxiYWNrcz86IGJvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBDaGFuZ2VzQWZ0ZXJDb25maWcgPSB7XG4gICAgdGltZTogbnVtYmVyO1xuICAgIC8qKiBPbmx5IGtleXMgcm91dGluZyBpbnRvIG9uZSBvZiB0aGVzZSBbc3RhcnQsIGVuZCkgcmFuZ2VzLiBPbmx5IHNjYW5uaW5nIHBhc3NlcyB0aGlzIC0gaXQgbGV0cyBhIHN0b3JlIHN5bmNpbmcgYSBwYXJ0aWFsIHNoYXJkIGFzayBmb3IganVzdCBpdHMgc2xpY2UuICovXG4gICAgcm91dGVzPzogW251bWJlciwgbnVtYmVyXVtdO1xufTtcblxuZXhwb3J0IHR5cGUgU2V0Q29uZmlnID0ge1xuICAgIGxhc3RNb2RpZmllZD86IG51bWJlcjtcbiAgICAvKiogTWFrZXMgdGhlIHdyaXRlIGFjY2VwdGFibGUgb24gaW1tdXRhYmxlIHRhcmdldHM6IGFuIGV4aXN0aW5nIHBhdGggaXMgc2ltcGx5IGtlcHQgKGltbXV0YWJpbGl0eSB3aW5zIC0gbm90aGluZyBpcyBvdmVyd3JpdHRlbikgaW5zdGVhZCBvZiB0aGUgd3JpdGUgdGhyb3dpbmcuIFJlcXVpcmVzIGxhc3RNb2RpZmllZC4gU3luY2hyb25pemF0aW9uIE1VU1QgcGFzcyB0aGlzIG9uIGV2ZXJ5IHB1c2ggLSBhIHBsYWluIHNldCB0aHJvd3Mgb24gaW1tdXRhYmxlIHRhcmdldHMsIHdoaWNoIHdvdWxkIGFib3J0IHJlY29uY2lsaWF0aW9uIHdoZW5ldmVyIG9uZSBzb3VyY2UgaW4gYSBjaGFpbiBpcyBpbW11dGFibGUuICovXG4gICAgZm9yY2VTZXRJbW11dGFibGU/OiBib29sZWFuO1xuICAgIC8qKiBTa2lwcyB0aGUgdGFyZ2V0LXNpZGUgc2FmZXR5IHJlYWRzIGFyb3VuZCB0aGUgd3JpdGUgKGJhY2tibGF6ZTogdGhlIHByZS13cml0ZSBnZXRJbmZvIGNvbXBhcmlzb24gYW5kIHRoZSBwb3N0LXVwbG9hZCBleGlzdGVuY2UgcG9sbCkuIEZvciB3cml0ZXJzIHdob3NlIG93biBib29ra2VlcGluZyBhbHJlYWR5IGRlY2lkZXMgd2hhdCB0byB3cml0ZSBhbmQgb3JkZXJzIGl0IGJ5IHdyaXRlIHRpbWUgKEJsb2JTdG9yZSdzIGluZGV4LWRyaXZlbiB3cml0ZXMgYW5kIHN5bmNocm9uaXphdGlvbiksIHRob3NlIHJlYWRzIGFyZSBwdXJlIGV4dHJhIEFQSSBjYWxscyAtIGJ1dCB0aGUgZGVmYXVsdCBzdGF5cyBjaGVja2VkLCBiZWNhdXNlIG90aGVyIHVzZXJzIG9mIHRoZSByYXcgYmFja2VuZHMgcmVseSBvbiB0aGUgY2hlY2tzLiAqL1xuICAgIG5vQ2hlY2tzPzogYm9vbGVhbjtcbn07XG5cbi8vIGNyZWF0ZVRpbWUgaXMgYSBtaXNub21lciBrZXB0IGZvciBjb21wYXRpYmlsaXR5IOKAlCBpdCBpcyByZWFsbHkgdGhlIExBU1QtV1JJVEUgdGltZSwgc2FtZSBhcyBnZXRJbmZvJ3Mgd3JpdGVUaW1lLiBOZWl0aGVyIEJhY2tibGF6ZSBub3Igb3VyIHJlbW90ZSBzdG9yYWdlIHRyYWNrcyBhIGRpc3RpbmN0IGNyZWF0aW9uIGRhdGU6IGVhY2ggd3JpdGUgc3RhbXBzIGEgZnJlc2ggdGltZXN0YW1wIG9uIHRoZSBjdXJyZW50IHZlcnNpb24sIHNvIGJvdGggZmllbGRzIGFyZSBqdXN0IFwid2hlbiB0aGUgYnl0ZXMgc2VydmVkIGJ5IGdldCgpIHdlcmUgbW9zdCByZWNlbnRseSB3cml0dGVuXCIuXG5leHBvcnQgdHlwZSBBcmNoaXZlRmlsZUluZm8gPSB7IHBhdGg6IHN0cmluZzsgY3JlYXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfTtcblxuLy8gQW4gaW4tcHJvZ3Jlc3MgYmFja2dyb3VuZCBzeW5jaHJvbml6YXRpb24gdGFzayAoc2VlIEFyY2hpdmVzQ29uZmlnLnN5bmNpbmcpXG5leHBvcnQgdHlwZSBTeW5jQWN0aXZpdHkgPSB7XG4gICAgLy8gQSBtZXRhZGF0YSBzY2FuIGlzIGEgc2luZ2xlIGxpc3RpbmcgY2FsbCwgc28gaXQgaGFzIG5vIGluY3JlbWVudGFsIHByb2dyZXNzIC0ganVzdCB0aGF0IGl0J3MgcnVubmluZyBhbmQgc2luY2Ugd2hlbi4gQSBmdWxsIHN5bmMga25vd3MgaXRzIGV4YWN0IGZpbGUvYnl0ZSBwcm9ncmVzcy5cbiAgICB0eXBlOiBcIm1ldGFkYXRhU2NhblwiIHwgXCJmdWxsU3luY1wiO1xuICAgIHNvdXJjZURlYnVnTmFtZTogc3RyaW5nO1xuICAgIHN0YXJ0VGltZTogbnVtYmVyO1xuICAgIGRvbmVGaWxlcz86IG51bWJlcjtcbiAgICB0b3RhbEZpbGVzPzogbnVtYmVyO1xuICAgIGRvbmVCeXRlcz86IG51bWJlcjtcbiAgICB0b3RhbEJ5dGVzPzogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgQXJjaGl2ZXNDb25maWcgPSB7XG4gICAgLy8gV2hldGhlciBnZXRDaGFuZ2VzQWZ0ZXIyIGlzIG5hdGl2ZWx5IGluZGV4LWJhY2tlZCAoZmFzdCBjaGFuZ2UgcG9sbGluZzsgZXZlcnkgYmFja2VuZCBzdGlsbCBzZXJ2ZXMgaXQsIGJ1dCB0aGUgb3RoZXJzIGVtdWxhdGUgaXQgd2l0aCBhIGZ1bGwgbGlzdGluZylcbiAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcj86IGJvb2xlYW47XG4gICAgLy8gVGhlIGJ1Y2tldCdzIGZ1bGwgcm91dGluZyBjb25maWcgKFJPVVRJTkdfRklMRSkuIEFic2VudCBmb3Igc291cmNlcyB0aGF0IGRvbid0IGhhdmUgb25lIChhIGJhcmUgZGlzayBzb3VyY2UsIG9yIGEgYnVja2V0IHRoYXQgZG9lc24ndCBleGlzdCB5ZXQpLlxuICAgIHJlbW90ZUNvbmZpZz86IFJlbW90ZUNvbmZpZztcbiAgICAvLyBMaXZlIGluZGV4IHRvdGFscyAodG9tYnN0b25lcyBleGNsdWRlZCksIGtlcHQgdXAgdG8gZGF0ZSBpbiBtZW1vcnkgb24gZXZlcnkgbXV0YXRpb24gYW5kIHJlY29tcHV0ZWQgb24gbG9hZCAtIHNvIGFueSBkcmlmdCBoZWFscyBvbiByZXN0YXJ0XG4gICAgaW5kZXg/OiB7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9O1xuICAgIC8vIFRoZSBzYW1lIHRvdGFscyBicm9rZW4gZG93biBieSB3aGljaCBzb3VyY2UgY3VycmVudGx5IGhvbGRzIGVhY2ggZmlsZSdzIGJ5dGVzICh0aGUgZmlyc3QgZW50cnkgaXMgdGhlIHNlcnZlcidzIG93biBkaXNrKVxuICAgIGluZGV4U291cmNlcz86IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W107XG4gICAgLy8gVGhlIHNlcnZlcidzIGNvbmZpZ3VyZWQgcmVhZGVyRGlza0xpbWl0LCB3aGVuIGl0IHJ1bnMgYXMgYSBib3VuZGVkIHJlYWQgY2FjaGVcbiAgICByZWFkZXJEaXNrTGltaXQ/OiBudW1iZXI7XG4gICAgLy8gQmFja2dyb3VuZCBzeW5jaHJvbml6YXRpb24gY3VycmVudGx5IGluIHByb2dyZXNzIChlbXB0eSB3aGVuIGlkbGUpXG4gICAgc3luY2luZz86IFN5bmNBY3Rpdml0eVtdO1xufTtcblxuLy8gQSBzeW5jaHJvbml6YXRpb24gc291cmNlIG9mIGEgQmxvYlN0b3JlICh3aGljaCBzeW5jaHJvbml6ZXMgYW4gaW5kZXggKyBsb2NhbCBjYWNoZSBmcm9tIHRoZW0pXG5leHBvcnQgdHlwZSBBcmNoaXZlc1NvdXJjZSA9IHtcbiAgICBzb3VyY2U6IElBcmNoaXZlcztcbiAgICAvKiogVGhlIHBlcnNpc3RlbnQgaWRlbnRpdHkgb2YgdGhlIGVuZHBvaW50OiBpdHMgcm91dGluZyBVUkwgKGhvc3RlZC9iYWNrYmxhemUpLCBvciB0aGUgZGlzayBmb2xkZXIgcGF0aCBmb3IgdGhlIGJhc2UgZGlzayBzb3VyY2UuIFRoZSBzdG9yZSBwZXJzaXN0cyB0aGlzICh2aWEgaXRzIGFwcGVuZC1vbmx5IHNvdXJjZXMgbGlzdCkgYXMgSW5kZXhFbnRyeS5zb3VyY2VzTGlzdEluZGV4LCBzbyBpdCBtdXN0IG1lYW4gdGhlIHNhbWUgZW5kcG9pbnQgZm9yZXZlci4gKi9cbiAgICB1cmw6IHN0cmluZztcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWcuIFZhbHVlcyB3aXRoIHdyaXRlIHRpbWVzIG91dHNpZGUgdGhlIHdpbmRvdyBhcmUgaWdub3JlZCB3aGVuIHNjYW5uaW5nLCBhbmQgb25jZSBpdHMgZW5kIGlzIHBhc3QgKHNlZSB3aW5kb3dBY2NlcHRzV3JpdGVzKSB0aGUgc291cmNlIHN0b3BzIHJlY2VpdmluZyB3cml0ZXMgZW50aXJlbHkgLSBzdGlsbCBzY2FubmVkIChpdCBob2xkcyB0aGUgYXV0aG9yaXRhdGl2ZSBkYXRhIGZvciBpdHMgd2luZG93KSwgaXQganVzdCBzdG9wcyBncm93aW5nLlxuICAgIHZhbGlkV2luZG93OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIC8vIEZyb20gdGhlIHNvdXJjZSdzIENvbW1vbkNvbmZpZyAoaW50ZXJzZWN0ZWQgd2l0aCB0aGUgb3duaW5nIHN0b3JlJ3Mgb3duIHJvdXRlKTogb25seSBrZXlzIHJvdXRpbmcgaW50byBbc3RhcnQsIGVuZCkgYXJlIGFjY2VwdGVkIGZyb20gdGhpcyBzb3VyY2UncyBzY2FucyBhbmQgc2VudCB0byBpdCBpbiB3cml0ZXMvcmVjb25jaWxpYXRpb24uIFRoZSByb3V0aW5nIGZpbGUgaXMgZXhlbXB0IC0gY29uZmlnIGZsb3dzIGV2ZXJ5d2hlcmUuIEFic2VudCA9IGFsbCBrZXlzLlxuICAgIHJvdXRlPzogW251bWJlciwgbnVtYmVyXTtcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWc7IHNlZSB0aGVyZS5cbiAgICBub0Z1bGxTeW5jPzogYm9vbGVhbjtcbiAgICAvLyBTdGFibGUgaWRlbnRpdHkgb2YgdGhlIHVuZGVybHlpbmcgZW5kcG9pbnQgKGl0cyBjb25maWcgd2l0aCB3aW5kb3dzL3JvdXRlcyBzdHJpcHBlZCkgLSBob3cgQmxvYlN0b3JlLnVwZGF0ZVNvdXJjZXMgcmVjb2duaXplcyBhIHNvdXJjZSBhY3Jvc3MgY29uZmlnIGNoYW5nZXMgc28gaXQgY2FuIHVwZGF0ZSBpdCBpbiBwbGFjZSBpbnN0ZWFkIG9mIHJlbW92aW5nIGFuZCByZS1hZGRpbmcgaXRcbiAgICBpZGVudGl0eT86IHN0cmluZztcbn07XG5cbi8vIEVycm9yIG1hcmtlciBhIHNlcnZlciBpbmNsdWRlcyB3aGVuIGEgZnJlc2hseS1zdGFtcGVkIHdyaXRlIHJlYWNoZXMgaXQgb3V0c2lkZSBpdHMgdmFsaWQgd2luZG93cyAodGhlIGNsaWVudCByZXNvbHZlZCBpdHMgdGFyZ2V0LCB0aGVuIHRpbWUgY3Jvc3NlZCBhIHdpbmRvdyBib3VuZGFyeSBiZWZvcmUgdGhlIHdyaXRlIGxhbmRlZCkuIENsaWVudHMgZGV0ZWN0IHRoaXMgbWFya2VyIGFuZCByZS1yZXNvbHZlIHRoZSBjdXJyZW50bHktdmFsaWQgc291cmNlLCByZXRyeWluZyBPTkNFIC0gYm91bmRhcmllcyBhcmUgZmFyIGFwYXJ0LCBzbyBoaXR0aW5nIGl0IHR3aWNlIGluIG9uZSBhdHRlbXB0IG1lYW5zIHNvbWV0aGluZyBpcyBhY3R1YWxseSB3cm9uZy5cbmV4cG9ydCBjb25zdCBTVE9SQUdFX1dST05HX1ZBTElEX1dJTkRPVyA9IFwiUkVNT1RFX1NUT1JBR0VfV1JPTkdfVkFMSURfV0lORE9XX2E3YzFmMDRlXCI7XG5cbi8vIEVycm9yIG1hcmtlciBhIHNlcnZlciBpbmNsdWRlcyB3aGVuIGEgZnJlc2hseS1zdGFtcGVkIHdyaXRlJ3Mga2V5IHJvdXRlcyBvdXRzaWRlIHRoZSBzaGFyZHMgdGhpcyBzZXJ2ZXIgaGFuZGxlcyAodGhlIGNsaWVudCdzIGNvbmZpZyBkaXNhZ3JlZXMgd2l0aCB0aGUgc2VydmVyJ3MgLSBjbGllbnRzIHJlLXJlc29sdmUgb25jZSlcbmV4cG9ydCBjb25zdCBTVE9SQUdFX1dST05HX1JPVVRFID0gXCJSRU1PVEVfU1RPUkFHRV9XUk9OR19ST1VURV9jOTRkMmUxN1wiO1xuXG5leHBvcnQgY29uc3QgRlVMTF9ST1VURTogW251bWJlciwgbnVtYmVyXSA9IFswLCAxXTtcblxuLy8gQSBrZXkgY29udGFpbmluZyB0aGlzIHNlbnRpbmVsIGRvZXNuJ3QgaGF2ZSBhIGZpeGVkIHNoYXJkOiBzZXRWYXJpYWJsZVNoYXJkIHBpY2tzIHRoZSAobG93ZXN0IGxhdGVuY3ksIHVwKSB3cml0ZSBzaGFyZCwgYXBwZW5kcyBcIl88dmFsdWUgaW4gdGhlIHNoYXJkJ3Mgcm91dGU+XCIgZGlyZWN0bHkgYWZ0ZXIgdGhlIHNlbnRpbmVsLCBhbmQgcmV0dXJucyB0aGUgbWF0ZXJpYWxpemVkIGtleS4gZ2V0Um91dGUgdHJlYXRzIHRoYXQgc3VmZml4IGFzIGEgY29tcGxldGUgcm91dGUgb3ZlcnJpZGUuXG5leHBvcnQgY29uc3QgVkFSSUFCTEVfU0hBUkQgPSBcIlZBUklBQkxFX1NIQVJEX2YwMjM0amZhaDA4Zmd5aGZneXNzZGRzODNubXBcIjtcbi8vIE5vIGdyYWNlIHBhc3QgdGhlIGVuZDogYSB3aW5kb3cgYm91bmRhcnkgaXMgYSBoYXJkIGhhbmRvZmYgKGNsaWVudHMgcmV0cnkgYSByZWplY3RlZCB3cml0ZSBhZ2FpbnN0IHRoZSBuZXdseS12YWxpZCBzb3VyY2UsIHNvIGxlbmllbmN5IGhlcmUgd291bGQgb25seSBkZXN5bmNocm9uaXplIHRoZSBoYW5kb2ZmKVxuZXhwb3J0IGZ1bmN0aW9uIHdpbmRvd0FjY2VwdHNXcml0ZXModmFsaWRXaW5kb3c6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkV2luZG93KSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gdmFsaWRXaW5kb3dbMV0gPiBEYXRlLm5vdygpO1xufVxuXG5jb25zdCBMQVJHRV9DT1BZX1RIUkVTSE9MRCA9IDY0ICogMTAyNCAqIDEwMjQ7XG5jb25zdCBMQVJHRV9DT1BZX0NIVU5LID0gMzIgKiAxMDI0ICogMTAyNDtcblxuLyoqIENvcGllcyBvbmUgZmlsZSBiZXR3ZWVuIHR3byBhcmNoaXZlcy4gU21hbGwgZmlsZXMgZ28gYXMgYSBzaW5nbGUgZ2V0MitzZXQ7IHBhc3QgTEFSR0VfQ09QWV9USFJFU0hPTEQgdGhlIGNvcHkgc3RyZWFtcyB0aHJvdWdoIHNldExhcmdlRmlsZSBpbiBMQVJHRV9DT1BZX0NIVU5LIHJhbmdlZCByZWFkcywgc28gdGhlIHdob2xlIGZpbGUgaXMgbmV2ZXIgaW4gbWVtb3J5LiBzaXplL3dyaXRlVGltZSB1c3VhbGx5IGNvbWUgZnJvbSB0aGUgY2FsbGVyJ3MgbWV0YWRhdGEgc2Nhbjsgd2hlbiBlaXRoZXIgaXMgb21pdHRlZCwgZ2V0SW5mbyBmaWxscyB0aGVtIGluLiBSZXR1cm5zIHRoZSBjb3BpZWQgZmlsZSdzIGluZm8sIG9yIHVuZGVmaW5lZCB3aGVuIHRoZSBzb3VyY2UgZG9lc24ndCBoYXZlIHRoZSBmaWxlLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvcHlBcmNoaXZlRmlsZShjb25maWc6IHtcbiAgICBmcm9tOiBJQXJjaGl2ZXM7XG4gICAgdG86IElBcmNoaXZlcztcbiAgICBwYXRoOiBzdHJpbmc7XG4gICAgc2l6ZT86IG51bWJlcjtcbiAgICB3cml0ZVRpbWU/OiBudW1iZXI7XG4gICAgZm9yY2VTZXRJbW11dGFibGU/OiBib29sZWFuO1xuICAgIG5vQ2hlY2tzPzogYm9vbGVhbjtcbn0pOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgbGV0IHsgZnJvbSwgdG8sIHBhdGggfSA9IGNvbmZpZztcbiAgICBsZXQgc2l6ZSA9IGNvbmZpZy5zaXplO1xuICAgIGxldCB3cml0ZVRpbWUgPSBjb25maWcud3JpdGVUaW1lO1xuICAgIGlmIChzaXplID09PSB1bmRlZmluZWQgfHwgd3JpdGVUaW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGV0IGluZm8gPSBhd2FpdCBmcm9tLmdldEluZm8ocGF0aCk7XG4gICAgICAgIGlmICghaW5mbykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgc2l6ZSA9IGluZm8uc2l6ZTtcbiAgICAgICAgd3JpdGVUaW1lID0gaW5mby53cml0ZVRpbWU7XG4gICAgfVxuICAgIGlmIChzaXplIDw9IExBUkdFX0NPUFlfVEhSRVNIT0xEKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBmcm9tLmdldDIocGF0aCk7XG4gICAgICAgIGlmICghcmVzdWx0KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBhd2FpdCB0by5zZXQocGF0aCwgcmVzdWx0LmRhdGEsIHsgbGFzdE1vZGlmaWVkOiByZXN1bHQud3JpdGVUaW1lLCBmb3JjZVNldEltbXV0YWJsZTogY29uZmlnLmZvcmNlU2V0SW1tdXRhYmxlLCBub0NoZWNrczogY29uZmlnLm5vQ2hlY2tzIH0pO1xuICAgICAgICByZXR1cm4geyB3cml0ZVRpbWU6IHJlc3VsdC53cml0ZVRpbWUsIHNpemU6IHJlc3VsdC5kYXRhLmxlbmd0aCB9O1xuICAgIH1cbiAgICAvLyBDb25zdHMgc28gdGhlIGNsb3N1cmUga2VlcHMgdGhlIG5hcnJvd2VkIHR5cGVzXG4gICAgY29uc3QgdG90YWxTaXplID0gc2l6ZTtcbiAgICBjb25zdCBmaW5hbFdyaXRlVGltZSA9IHdyaXRlVGltZTtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBhd2FpdCB0by5zZXRMYXJnZUZpbGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBsYXN0TW9kaWZpZWQ6IGZpbmFsV3JpdGVUaW1lLFxuICAgICAgICBnZXROZXh0RGF0YTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKG9mZnNldCA+PSB0b3RhbFNpemUpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBsZXQgZW5kID0gTWF0aC5taW4ob2Zmc2V0ICsgTEFSR0VfQ09QWV9DSFVOSywgdG90YWxTaXplKTtcbiAgICAgICAgICAgIGxldCBkYXRhID0gYXdhaXQgZnJvbS5nZXQocGF0aCwgeyByYW5nZTogeyBzdGFydDogb2Zmc2V0LCBlbmQgfSB9KTtcbiAgICAgICAgICAgIGlmICghZGF0YSB8fCAhZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJhbmdlZCByZWFkIG9mICR7SlNPTi5zdHJpbmdpZnkocGF0aCl9IGZyb20gJHtmcm9tLmdldERlYnVnTmFtZSgpfSByZXR1cm5lZCAke2RhdGEgJiYgZGF0YS5sZW5ndGggfHwgXCJub3RoaW5nXCJ9IGF0ICR7b2Zmc2V0fS0ke2VuZH0gKGV4cGVjdGVkICR7ZW5kIC0gb2Zmc2V0fSBieXRlcyBvZiBhICR7dG90YWxTaXplfSBieXRlIGZpbGUgLSBpdCBjaGFuZ2VkIG9yIHZhbmlzaGVkIG1pZC1jb3B5KWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2Zmc2V0ICs9IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHsgd3JpdGVUaW1lOiBmaW5hbFdyaXRlVGltZSwgc2l6ZTogdG90YWxTaXplIH07XG59XG5cbmV4cG9ydCB0eXBlIEFyY2hpdmVzU3luY1NvdXJjZVN0YXR1cyA9IHtcbiAgICBkZWJ1Z05hbWU6IHN0cmluZztcbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICByb3V0ZT86IFtudW1iZXIsIG51bWJlcl07XG4gICAgbm9GdWxsU3luYz86IGJvb2xlYW47XG4gICAgc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI6IGJvb2xlYW47XG4gICAgaW5pdGlhbFNjYW5Db21wbGV0ZTogYm9vbGVhbjtcbiAgICAvLyBGaWxlcyBzZWVuIGluIHRoaXMgc291cmNlJ3Mgc2NhbnMgLyBjaGFuZ2UgcG9sbHMgc28gZmFyXG4gICAgc2Nhbm5lZENvdW50OiBudW1iZXI7XG59O1xuZXhwb3J0IHR5cGUgQXJjaGl2ZXNTeW5jU3RhdHVzID0ge1xuICAgIGFsbFNjYW5zQ29tcGxldGU6IGJvb2xlYW47XG4gICAgLy8gTnVtYmVyIG9mIGZpbGVzIGluIHRoZSBpbmRleFxuICAgIGluZGV4U2l6ZTogbnVtYmVyO1xuICAgIHNvdXJjZXM6IEFyY2hpdmVzU3luY1NvdXJjZVN0YXR1c1tdO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBJQXJjaGl2ZXMge1xuICAgIGdldERlYnVnTmFtZSgpOiBzdHJpbmc7XG4gICAgLyoqIFdoZXRoZXIgd3JpdGVzIHdvdWxkIGJlIGFjY2VwdGVkIChjcmVkZW50aWFscyBleGlzdCwgdGhlIGFjY291bnQgdHJ1c3RzIHRoaXMgbWFjaGluZSwgZXRjKS4gQ2hlY2tlZCB3aXRob3V0IHdyaXRpbmcgYW55dGhpbmcuICovXG4gICAgaGFzV3JpdGVBY2Nlc3MoKTogUHJvbWlzZTxib29sZWFuPjtcbiAgICAvKipcbiAgICAgKiBSZWFkcyBhdXRvbWF0aWNhbGx5IGZhbGwgYmFjayBhY3Jvc3MgdGhlIHJlZHVuZGFudCBzb3VyY2VzIHVubGVzcyBjb25maWcubm9GYWxsYmFja3MgaXMgc2V0LlxuICAgICAqIEEgZmFsbGJhY2sgY29weSBjYW4gbGFnIHRoZSB3cml0ZSB0YXJnZXQsIHNvIGEgY2FsbGVyIHJlYWRpbmcgc3RhdGUgaW4gb3JkZXIgdG8gbXV0YXRlIGl0XG4gICAgICogKGUuZy4geCsrKSwgd2hlcmUgYWN0aW5nIG9uIHByZXZpb3VzIHN0YXRlIHdvdWxkIGNhdXNlIGJpZyBpc3N1ZXMsIHNob3VsZCBwYXNzIG5vRmFsbGJhY2tzIC1cbiAgICAgKiBhbmQgdHJ5L2NhdGNoIHRoZSByZWFkLCBoYW5kbGluZyB0aGUgY2F0Y2ggY2FzZSAoYSBkb3duIHByaW1hcnkgaXMgcmV0cmllZCBmb3IgYSB3aGlsZSwgdGhlblxuICAgICAqIHRocm93cyBpbnN0ZWFkIG9mIGRlZ3JhZGluZyB0byBhIHN0YWxlIGNvcHkpLlxuICAgICAqL1xuICAgIGdldChmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiBHZXRDb25maWcpOiBQcm9taXNlPEJ1ZmZlciB8IHVuZGVmaW5lZD47XG4gICAgLyoqIFNlZSBnZXQgZm9yIHRoZSBmYWxsYmFjayBzZW1hbnRpY3MgKGFuZCB3aGVuIHRvIHBhc3Mgbm9GYWxsYmFja3MpLiB1cmwgaXMgdGhlIGNvbmZpZyBVUkwgb2YgdGhlIHNvdXJjZSB0aGF0IHNlcnZlZCB0aGUgdmFsdWUgLSBzZXQgYnkgbXVsdGktc291cmNlIGltcGxlbWVudGF0aW9ucyAoQXJjaGl2ZXNDaGFpbiksIGFic2VudCBmcm9tIHNpbmdsZS1zb3VyY2UgYmFja2VuZHMuICovXG4gICAgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiBHZXRDb25maWcpOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyOyB1cmw/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZD47XG4gICAgLyoqXG4gICAgICogbGFzdE1vZGlmaWVkIHN0YW1wcyB0aGUgd3JpdGUgd2l0aCB0aGF0IGxhc3Qtd3JpdGUgdGltZSBpbnN0ZWFkIG9mIG5vdy4gSWYgaXQgaXMgT0xERVIgdGhhblxuICAgICAqIHRoZSBmaWxlJ3MgY3VycmVudCBsYXN0LXdyaXRlIHRpbWUgdGhlIHdyaXRlIG5vLW9wcyAoc28gZGVsYXllZCAvIHN5bmNocm9uaXplZCB3cml0ZXMgY2FuXG4gICAgICogbmV2ZXIgY2xvYmJlciBuZXdlciBkYXRhKS4gVGltZXMgbW9yZSB0aGFuIDE1IG1pbnV0ZXMgaW4gdGhlIGZ1dHVyZSBhcmUgcmVqZWN0ZWQuXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIHRoZSBmdWxsIGtleSBhY3R1YWxseSB3cml0dGVuIC0gaWRlbnRpY2FsIHRvIGZpbGVOYW1lLCBFWENFUFQgZm9yIGtleXMgY29udGFpbmluZ1xuICAgICAqIFZBUklBQkxFX1NIQVJELCB3aGVyZSB0aGUgc2hhcmQgdmFsdWUgaXMgbWF0ZXJpYWxpemVkIGludG8gdGhlIGtleSAocGlja2VkIGJ5IHNoYXJkIGxhdGVuY3ksXG4gICAgICogc2VlIEFyY2hpdmVzQ2hhaW4pIGFuZCB0aGUgY2FsbGVyIG5lZWRzIHRoZSByZXR1cm5lZCBrZXkgdG8gZXZlciByZWFkIHRoZSB2YWx1ZSBiYWNrLlxuICAgICAqL1xuICAgIHNldChmaWxlTmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IFNldENvbmZpZyk6IFByb21pc2U8c3RyaW5nPjtcbiAgICBkZWwoZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gICAgLyoqIFN0cmVhbXMgYSBmaWxlIHRvbyBsYXJnZSB0byBob2xkIGluIG1lbW9yeS4gZ2V0TmV4dERhdGEgcmV0dXJucyB1bmRlZmluZWQgd2hlbiBkb25lLiBsYXN0TW9kaWZpZWQgc3RhbXBzIHRoZSBmaW5pc2hlZCBmaWxlIGxpa2Ugc2V0J3MgKHN5bmNocm9uaXplZCBjb3BpZXMgbmVlZCBpdCB0byBrZWVwIHdyaXRlIG9yZGVyaW5nKTsgYmFja2VuZHMgdGhhdCBzdGFtcCB0aGVpciBvd24gdGltZXMgKGJhY2tibGF6ZSkgYWNjZXB0IGFuZCBpZ25vcmUgaXQuICovXG4gICAgc2V0TGFyZ2VGaWxlKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGxhc3RNb2RpZmllZD86IG51bWJlcjsgZ2V0TmV4dERhdGEoKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IH0pOiBQcm9taXNlPHZvaWQ+O1xuICAgIC8qKiB3cml0ZVRpbWUgaXMgdGhlIGxhc3Qtd3JpdGUgdGltZSDigJQgc2VlIEFyY2hpdmVGaWxlSW5mby5jcmVhdGVUaW1lLCB3aGljaCBpcyB0aGUgc2FtZSB2YWx1ZS4gdXJsIGFzIGluIGdldDIuICovXG4gICAgZ2V0SW5mbyhmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXI7IHVybD86IHN0cmluZyB9IHwgdW5kZWZpbmVkPjtcbiAgICBmaW5kKHByZWZpeDogc3RyaW5nLCBjb25maWc/OiB7IHNoYWxsb3c/OiBib29sZWFuOyB0eXBlOiBcImZpbGVzXCIgfCBcImZvbGRlcnNcIiB9KTogUHJvbWlzZTxzdHJpbmdbXT47XG4gICAgZmluZEluZm8ocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPjtcbiAgICAvKiogT25seSB3b3JrcyBmb3IgcHVibGljIGJ1Y2tldHMgKHByaXZhdGUgYnVja2V0cyBhcmUgQVBJLWFjY2VzcyBvbmx5KS4gKi9cbiAgICBnZXRVUkwocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+O1xuICAgIC8qKiBUaGUgYnVja2V0J3MgY29uZmlndXJhdGlvbiwgd2hpY2ggdGVsbHMgd2hldGhlciB0aGUgb3B0aW9uYWwgZnVuY3Rpb25zIGFyZSBzdXBwb3J0ZWQuICovXG4gICAgZ2V0Q29uZmlnKCk6IFByb21pc2U8QXJjaGl2ZXNDb25maWc+O1xuICAgIC8qKlxuICAgICAqIEFsbCBmaWxlcyBjaGFuZ2VkIGFmdGVyIGNvbmZpZy50aW1lLCBvcHRpb25hbGx5IHJlc3RyaWN0ZWQgdG8ga2V5cyByb3V0aW5nIGludG8gb25lIG9mXG4gICAgICogY29uZmlnLnJvdXRlcyAodXNlZCBieSBzY2FubmluZywgc28gcGFydGlhbGx5LW92ZXJsYXBwaW5nIHNoYXJkcyBvbmx5IHJlY2VpdmUgdGhlaXIgc2xpY2UpLlxuICAgICAqIFdoZW4gZ2V0Q29uZmlnKCkuc3VwcG9ydHNDaGFuZ2VzQWZ0ZXIsIHRoaXMgaXMgYmFja2VkIGJ5IGFuIGluZGV4IChmYXN0LCBhbmQgZGVsZXRpb25zIEFSRVxuICAgICAqIHJlcG9ydGVkLCBhcyBzaXplLTAgdG9tYnN0b25lIGVudHJpZXMpLiBFdmVyeSBvdGhlciBiYWNrZW5kIGVtdWxhdGVzIGl0OiBhIGZ1bGwgZmluZEluZm9cbiAgICAgKiBsaXN0aW5nIGZpbHRlcmVkIGluIG1lbW9yeSAtIGNvcnJlY3QsIGJ1dCBubyBjaGVhcGVyIHRoYW4gdGhlIGxpc3RpbmcgaXRzZWxmLlxuICAgICAqL1xuICAgIGdldENoYW5nZXNBZnRlcjIoY29uZmlnOiBDaGFuZ2VzQWZ0ZXJDb25maWcpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPjtcbiAgICAvKiogU3luY2hyb25pemF0aW9uIGludHJvc3BlY3Rpb24sIGZvciBiYWNrZW5kcyB0aGF0IHN5bmNocm9uaXplIGZyb20gc291cmNlcyAoc2VlIEJsb2JTdG9yZSkuICovXG4gICAgZ2V0U3luY1N0YXR1cz8oKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+O1xufVxuIl19
75
- /* _JS_SOURCE_HASH = "f846d9d56dbc23a52ccc3b16dd9d75375269c41ed9854c4fee86fc1e0f41d8ae"; */
74
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSUFyY2hpdmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiSUFyY2hpdmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx3S0FBd0s7OztBQUV4SyxzSkFBc0o7QUFDekksUUFBQSx3QkFBd0IsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUV2RCx5TEFBeUw7QUFDNUssUUFBQSxvQkFBb0IsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2pELFNBQWdCLHVCQUF1QixDQUFDLFlBQW9CO0lBQ3hELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxnQ0FBd0IsQ0FBQztJQUNoRCxJQUFJLFlBQVksR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxZQUFZLE1BQU0sR0FBRyxxQkFBcUIsQ0FBQyxDQUFDO0lBQzFHLENBQUM7QUFDTCxDQUFDO0FBTEQsMERBS0M7QUF1RVksUUFBQSxpQkFBaUIsR0FBcUIsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUF3RWhGLHdYQUF3WDtBQUMzVyxRQUFBLDBCQUEwQixHQUFHLDRDQUE0QyxDQUFDO0FBRXZGLDhMQUE4TDtBQUNqTCxRQUFBLG1CQUFtQixHQUFHLHFDQUFxQyxDQUFDO0FBRTVELFFBQUEsVUFBVSxHQUFxQixDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUVuRCwyUkFBMlI7QUFDOVEsUUFBQSxjQUFjLEdBQUcsNkNBQTZDLENBQUM7QUFDNUUsb0xBQW9MO0FBQ3BMLFNBQWdCLG1CQUFtQixDQUFDLFdBQXlDO0lBQ3pFLElBQUksQ0FBQyxXQUFXO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDOUIsT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUFIRCxrREFHQztBQUVELE1BQU0sb0JB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Q0MiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgaW1wb3J0YW50IG9wZXJhdGlvbnMgb2YgYW4gYXJjaGl2ZSBidWNrZXQgKGV4dHJhY3RlZCBmcm9tIEFyY2hpdmVzQmFja2JsYXplKSwgc28gb3RoZXIgYmFja2VuZHMgKGUuZy4gb3VyIG93biByZW1vdGUgc3RvcmFnZSBzZXJ2ZXIpIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseS5cblxuLy8gQSB3cml0ZSBtYXkgbm90IGJlIHN0YW1wZWQgbW9yZSB0aGFuIHRoaXMgZmFyIGluIHRoZSBmdXR1cmUsIG9yIGNsb2NrIHNrZXcgYmV0d2VlbiBtYWNoaW5lcyB3b3VsZCBsZXQgYSBiYWQgdGltZXN0YW1wIGJsb2NrIHdyaXRlcyBmb3IgYSBsb25nIHRpbWUuXG5leHBvcnQgY29uc3QgTUFYX0xBU1RfTU9ESUZJRURfRlVUVVJFID0gMTUgKiA2MCAqIDEwMDA7XG5cbi8vIEhvdyBsb25nIGJyb3dzZXJzIG1heSBjYWNoZSBmaWxlcyBmcm9tIGltbXV0YWJsZSBidWNrZXRzICh0aGUgQ2FjaGUtQ29udHJvbCBtYXgtYWdlKSwgc2hhcmVkIGJ5IGV2ZXJ5IGhvc3RpbmcgcGF0aCAoYmFja2JsYXplIGJ1Y2tldCBzZXR0aW5ncyBhbmQgb3VyIG93biBzdG9yYWdlIHNlcnZlcidzIEhUVFAgcm91dGUpXG5leHBvcnQgY29uc3QgSU1NVVRBQkxFX0NBQ0hFX1RJTUUgPSA4NjQwMCAqIDEwMDA7XG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0VmFsaWRMYXN0TW9kaWZpZWQobGFzdE1vZGlmaWVkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBsZXQgbWF4ID0gRGF0ZS5ub3coKSArIE1BWF9MQVNUX01PRElGSUVEX0ZVVFVSRTtcbiAgICBpZiAobGFzdE1vZGlmaWVkID4gbWF4KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbGFzdE1vZGlmaWVkIGlzIHRvbyBmYXIgaW4gdGhlIGZ1dHVyZTogJHtsYXN0TW9kaWZpZWR9ID4gJHttYXh9IChub3cgKyAxNSBtaW51dGVzKWApO1xuICAgIH1cbn1cblxuXG5leHBvcnQgdHlwZSBSZW1vdGVDb25maWcgPSB7XG4gICAgLy8gTk9URTogVmVyc2lvbiBpcyB1c2VkIHdoZW4gdXBkYXRpbmcgdGhlIGNvbmZpZ3VyYXRpb24uIFRoZSBuZXdlciB2ZXJzaW9uIGlzIGFsd2F5cyB0YWtlbi4gQSBtaXNzaW5nIHZlcnNpb24gY291bnRzIGFzIHZlcnNpb24gLTEuXG4gICAgdmVyc2lvbj86IG51bWJlcjtcbiAgICBzb3VyY2VzOiBSZW1vdGVDb25maWdCYXNlW107XG59O1xuXG4vKipcbiAgICBzdHJpbmcgYXJndW1lbnRzIHdpbGwgYmUgYSB1cmwsIGxvb2tpbmcgbGlrZTpcbiAgICAgICAgaHR0cHM6Ly9zdG9yYWdlMi52aWRncmlkd2ViLmNvbTo0NDQ1L2ZpbGUvZXhhbXBsZWFjY291bnQvZXhhbXBsZWJ1Y2tldC9zdG9yYWdlL3N0b3JhZ2Vyb3V0aW5nLmpzb25cbiAgICAgICAgaHR0cHM6Ly9mMDAyLmJhY2tibGF6ZWIyLmNvbS9maWxlL3F1ZXJ5c3VidGVzdC1jb20tcHVibGljLWltbXV0YWJsZS9zdG9yYWdlL3N0b3JhZ2Vyb3V0aW5nLmpzb25cbiAgICAgICAgLSBUaGVzZSBtYXAgdG8geyB1cmwgfSwgd2l0aCB0aGUgdHlwZSBpbmZlcnJlZCBmcm9tIHRoZSB1cmxcbiAgICAgICAgLSBIb3N0ZWQgdXJscyBhcmUgL2ZpbGUvPGFjY291bnQ+LzxidWNrZXROYW1lPi8uLi4sIGJhY2tibGF6ZSB1cmxzIGFyZSAvZmlsZS88YnVja2V0TmFtZT4vLi4uXG5cbiAgICBOT1RFOiBJZiB3ZSBkbyBub3QgaGF2ZSByaWdodCBhY2Nlc3MgdG8gdGhlc2UsIHRoZW4gaXQgYmVjb21lcyBhIHJlYWQtb25seSBJQXJjaGl2ZXMsIHdoZXJlIHdlIHNvbGVseSByZWFkIHVzaW5nIHRoZSB1cmwgZm9ybSAod2hpY2ggbWlnaHQgdGhyb3cgZHVlIHRvIG5vdCBoYXZpbmcgYWNjZXNzIGFzIHdlbGwpLiBVTkxFU1MgT3VyIGNvbmZpZ3VyYXRpb24gZXhwbGljaXRseSBoYXMgcHVibGljOiBmYWxzZSwgaW4gd2hpY2ggY2FzZSwgd2UgZG9uJ3QgZXZlbiBoaXQgdGhlIFVSTCBhbmQgd2UgdGhyb3cgb24gYWNjZXNzLlxuXG4gICAgTk9URTogSWYgd2UncmUgaW4gdGhlIGJyb3dzZXIsIHdlIHNob3VsZCBhbGxvdyBkb3dubG9hZGluZyB0aGUgZmlsZXMgdmlhIHRoZSBVUkwgZm9ybSAoaWYgaXQncyBhIHB1YmxpYyBidWNrZXQpLCBob3dldmVyLCB3ZSB3b24ndCBhbGxvdyB3cml0aW5nLCBiZWNhdXNlIHRoZWlyIHNlcnZlcnMgZG8gbm90IGFsbG93IHNlY3VyZSBicm93c2VyIHdyaXRlcy5cbiovXG5leHBvcnQgdHlwZSBSZW1vdGVDb25maWdCYXNlID0gc3RyaW5nIHwgSG9zdGVkQ29uZmlnIHwgQmFja2JsYXplQ29uZmlnO1xuXG5leHBvcnQgdHlwZSBDb21tb25Db25maWcgPSB7XG4gICAgLyoqIEJ5IGRlZmF1bHQgYSBzZXJ2ZXIgaG9zdGluZyB0aGlzIGJ1Y2tldCBlYWdlcmx5IGNvcGllcyB0aGlzIHNvdXJjZSdzIGZ1bGwgY29udGVudHMgb250byBpdHMgb3duIGRpc2sgKG9uIHRvcCBvZiB0aGUgbGF6eSByZWFkLXRocm91Z2ggY2FjaGluZykuIFNldCB0aGlzIHRvIGJlIGEgZnJvbnQgZW5kIGZvciBhIHZlcnkgbGFyZ2UgZGF0YWJhc2Ugd2l0aG91dCBjb3B5aW5nIHRoZSBmdWxsIGRhdGFiYXNlIC0gcmVhZHMgc3RpbGwgZG93bi1jYWNoZSBpbmRpdmlkdWFsIGZpbGVzIG9uIGRlbWFuZC4gKi9cbiAgICBub0Z1bGxTeW5jPzogYm9vbGVhbjtcbiAgICAvKiogQnl0ZXMgb2YgcmVhZC1jYWNoZSB0aGlzIHNlcnZlcidzIGRpc2sgbWF5IGhvbGQ7IGxlYXN0LXJlY2VudGx5LXVzZWQgZmlsZXMgYXJlIGRlbGV0ZWQgZnJvbSBkaXNrIHRvIHN0YXkgdW5kZXIgaXQgKG9ubHkgZXZlciB3aGVuIGFub3RoZXIgc291cmNlIHZlcmlmaWFibHkgaG9sZHMgdGhlIGZpbGUgLSB0aGUgb25seSBjb3B5IGlzIG5ldmVyIGRlbGV0ZWQpLiBSZXF1aXJlcyBub0Z1bGxTeW5jIChhIGZ1bGwgY29weSBjYW4ndCBiZSBib3VuZGVkKS4gKi9cbiAgICByZWFkZXJEaXNrTGltaXQ/OiBudW1iZXI7XG4gICAgLyoqIFRoZSB3cml0ZSB0aW1lcyAoW3N0YXJ0TXMsIGVuZE1zXSkgdGhpcyBzb3VyY2UgaXMgdmFsaWQgZm9yIChzZWUgQXJjaGl2ZXNTb3VyY2UudmFsaWRXaW5kb3cgZm9yIHRoZSBzeW5jaHJvbml6YXRpb24gc2VtYW50aWNzKS4gUmVxdWlyZWQgb24gb2JqZWN0IGNvbmZpZ3M6IGNvbmZpZ3VyYXRpb24gY2hhbmdlcyBtdXN0IGJlIFNDSEVEVUxFRCAoYSBuZXcgc291cmNlIGJlY29tZXMgdmFsaWQgYXQgYSBmdXR1cmUgdGltZSB3aGlsZSB0aGUgb2xkIG9uZSdzIHdpbmRvdyBlbmRzKSwgbm90IGZsaXBwZWQgaW5zdGFudGx5LiBQbGFpbiBVUkwtc3RyaW5nIHNvdXJjZXMgZGVmYXVsdCB0byBGVUxMX1ZBTElEX1dJTkRPVyAtIG9uY2UgeW91J3JlIHdyaXRpbmcgb2JqZWN0IGNvbmZpZ3MsIHlvdSdyZSBkb2luZyBzb21ldGhpbmcgY29tcGxpY2F0ZWQgZW5vdWdoIHRvIHRoaW5rIGFib3V0IHdoZW4gdGhpbmdzIGNoYW5nZS4gKi9cbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICAvKiogU2hhcmRpbmc6IHRoZSBmcmFjdGlvbiBvZiB0aGUga2V5IHNwYWNlIHRoaXMgc291cmNlIGhhbmRsZXMsIGFzIFtzdGFydCwgZW5kKSBvdmVyIFswLCAxKSAoa2V5cyBhcmUgcm91dGVkIGJ5IGdldFJvdXRlIGluIHJlbW90ZUNvbmZpZy50cykuIERlZmF1bHRzIHRvIEZVTExfUk9VVEUgKHVuc2hhcmRlZCkuIEF0IGV2ZXJ5IHBvaW50IGluIHRpbWUgdGhlIHNvdXJjZXMnIHJvdXRlcyBtdXN0IGZ1bGx5IGNvdmVyIFswLCAxKSwgb3Igc29tZSBrZXlzIGNvdWxkIG5ldmVyIGJlIHJlYWQuICovXG4gICAgcm91dGU/OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIC8qKiBTZXQgb24gZW50cmllcyBpbmplY3RlZCBpbnRvIHRoZSBpbi1tZW1vcnkgY29uZmlnIGJ5IGFuIG92ZXJsYXkgKGEgZGVwbG95IHN3aXRjaG92ZXIncyBhbHRlcm5hdGUtcG9ydCB3aW5kb3cpLiBOZXZlciB3cml0dGVuIHRvIGRpc2s6IHJlc29sdmVJbnRlcm1lZGlhdGVTb3VyY2VzIHN0cmlwcyB0aGVzZSBhbmQgcmVqb2lucyB0aGUgd2luZG93cyBhcm91bmQgdGhlbSwgd2hpY2ggaXMgYWxzbyBob3cgYSBjbGllbnQgdGVsbHMgd2hldGhlciBhbiB1cGRhdGUgaXMgYSByZWFsIGNvbmZpZ3VyYXRpb24gY2hhbmdlIG9yIGp1c3QgYW4gb3ZlcmxheS4gKi9cbiAgICBpbnRlcm1lZGlhdGU/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgSG9zdGVkQ29uZmlnID0gQ29tbW9uQ29uZmlnICYge1xuICAgIHR5cGU6IFwicmVtb3RlXCI7XG5cbiAgICAvLyBFeDogaHR0cHM6Ly85OS0yNTAtMTI0LTkxLnF1ZXJ5c3VidGVzdC5jb206NTIzMy9maWxlL3Jvb3QvdW5pcXVlYnVja2V0bmFtZS9zdG9yYWdlL3N0b3JhZ2Vyb3V0aW5nLmpzb25cbiAgICAvLyBOT1RFOiBUaGUgYWNjb3VudCBhbmQgYnVja2V0IG5hbWUgYXJlIG9idGFpbmVkIGZyb20gdGhlIFVSTC5cbiAgICB1cmw6IHN0cmluZztcblxuICAgIC8vIE5PVEU6IEF1dGhlbnRpY2F0aW9uIGlzIGhhbmRsZWQgYnkgY2VydC50cywgdmlhIGhhdmluZyB5b3VyIG1hY2hpbmUgdHJ1c3RlZCB0byBhY2Nlc3MgdGhpcyBhY2NvdW50LiBcblxuICAgIHB1YmxpYz86IGJvb2xlYW47XG4gICAgLy8gRmFzdCBtb2RlOiB0aGUgc2VydmVyIGFja25vd2xlZGdlcyB3cml0ZXMgb25jZSB0aGV5IGFyZSBpbiBtZW1vcnksIGZsdXNoaW5nIHRvIGRpc2sgYWZ0ZXIgd3JpdGVEZWxheSAoZGVmYXVsdCA1IG1pbnV0ZXMpIGFuZCBjb2FsZXNjaW5nIHdyaXRlcyB0byB0aGUgc2FtZSBmaWxlLiBBIHNlcnZlciBjcmFzaCBsb3NlcyB3cml0ZXMgdGhhdCBoYXZlbid0IGZsdXNoZWQgeWV0LlxuICAgIGZhc3Q/OiBib29sZWFuO1xuICAgIHdyaXRlRGVsYXk/OiBudW1iZXI7XG4gICAgLy8gVGhlIGJ1Y2tldCBpcyBzZXJ2ZWQgc3RyYWlnaHQgZnJvbSB0aGUgc2VydmVyJ3MgZGlzaywgd2l0aCBubyBpbmRleCDigJQgc28gbm8gZmFzdCB3cml0ZXMsIG5vIGdldFN5bmNTdGF0dXMsIGFuZCBnZXRDaGFuZ2VzQWZ0ZXIyIGZhbGxzIGJhY2sgdG8gYSBmdWxsIGxpc3RpbmcuXG4gICAgcmF3RGlzaz86IGJvb2xlYW47XG4gICAgLy8gV3JpdGVzIHRvIHBhdGhzIHRoYXQgYWxyZWFkeSBleGlzdCBhcmUgZGlzYWxsb3dlZCAoZGVsZXRlcyBzdGlsbCB3b3JrKS5cbiAgICBpbW11dGFibGU/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2JsYXplQ29uZmlnID0gQ29tbW9uQ29uZmlnICYge1xuICAgIHR5cGU6IFwiYmFja2JsYXplXCI7XG4gICAgLy8gRXg6IGh0dHBzOi8vZjAwMi5iYWNrYmxhemViMi5jb20vZmlsZS9xdWVyeXN1YnRlc3QtY29tLXB1YmxpYy1pbW11dGFibGUvc3RvcmFnZS9zdG9yYWdlcm91dGluZy5qc29uXG4gICAgLy8gTk9URTogVGhlIGJ1Y2tldCBuYW1lIGlzIG9idGFpbmVkIGZyb20gdGhlIFVSTC5cbiAgICB1cmw6IHN0cmluZztcbiAgICAvLyBQdWJsaWMgYnVja2V0cyBhcmUgc2VydmVkIG92ZXIgcGxhaW4gSFRUUFMgR0VUcyAoZ2V0VVJMKS4gUHJpdmF0ZSBidWNrZXRzIGFyZSBBUEktYWNjZXNzIG9ubHkuXG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICAvLyBOT1RFOiBUaGlzIGlzbid0IGVuZm9yY2VkIG9uIHRoZSBiYWNrYmxhemUgbGV2ZWwsIHNvIHRoaXMgaXMganVzdCBhIGNsaWVudC1zaWRlIGd1YXJhbnRlZS4gVGhpcyBjYW4gY2hhbmdlIGhvdyB3ZSBjYWNoZSBmaWxlcy5cbiAgICAvLyAgLSBCYWNrYmxhemUgZG9lcyBzdXBwb3J0IGltbXV0YWJpbGl0eS4gSG93ZXZlciwgYXBwYXJlbnRseSwgb25jZSB3ZSBlbmFibGUgaXQgb24gYSBidWNrZXQsIHdlIGNhbid0IGRpc2FibGUgaXQsIHdoaWNoIGlzIHJlYWxseSBiYWQsIGFzIGl0IG1lYW5zIGlmIG91ciBjb2RlIGNvdWxkIGV2ZXIgZW5hYmxlIGl0IGFuZCB3ZSBhY2NpZGVudGFsbHkgZW5hYmxlIGl0IG9uIGFuIGltcG9ydGFudCBidWNrZXQsIHdlIGVzc2VudGlhbGx5IGp1c3QgYnJpY2tlZCB0aGF0IGJ1Y2tldC4gU28gd2Ugc2hvdWxkIG5ldmVyIHdyaXRlIGFueSBjb2RlIHRoYXQgZXZlciB0cmllcyB0byB1c2UgYmFja2JsYXplIHRvIG1ha2UgdGhpbmdzIGltbXV0YWJsZS4gXG4gICAgaW1tdXRhYmxlPzogYm9vbGVhbjtcbiAgICAvLyBDT1JTIG9yaWdpbnMgYWxsb3dlZCB0byBjb25zdW1lIHRoZSBidWNrZXQncyBmaWxlcyBpbiBhIGJyb3dzZXIuIE5vdCBhIHNlY3VyaXR5IGJvdW5kYXJ5IChhY2Nlc3MgaXMgZ2F0ZWQgYnkgdGhlIEFQSSBrZXkgLyBzaWduZWQgVVJMcywgbmVpdGhlciBvZiB3aGljaCByaWRlcyBpbiBjb29raWVzKSAtIGl0IG9ubHkgY29udHJvbHMgd2hpY2ggc2l0ZXMnIGluLXBhZ2UgSmF2YVNjcmlwdCBjYW4gcmVhZCByZXNwb25zZXMuIERlZmF1bHRzIHRvIGFueSBIVFRQUyBvcmlnaW4uXG4gICAgYWxsb3dlZE9yaWdpbnM/OiBzdHJpbmdbXTtcblxuICAgIC8vIE5PVEU6IFdlIHdpbGwgYWNjZXNzIHRoZSBhcGkga2V5IGZyb20gZ2V0U2VjcmV0LCBzZWUgYmFja2JsYXplLnRzIGZvciB0aGUgc3BlY2lmaWMga2V5cy5cbn07XG5cblxuZXhwb3J0IGNvbnN0IEZVTExfVkFMSURfV0lORE9XOiBbbnVtYmVyLCBudW1iZXJdID0gWzAsIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXTtcblxuXG5cblxuZXhwb3J0IHR5cGUgR2V0Q29uZmlnID0ge1xuICAgIHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9O1xuICAgIC8qKiBSZWFkIE9OTFkgZnJvbSB0aGUgcHJpbWFyeSBzb3VyY2UgLSB0aGUgb25lIHdyaXRlcyB3b3VsZCB0YXJnZXQgLSBpbnN0ZWFkIG9mIGZhbGxpbmcgYmFjayBhY3Jvc3MgdGhlIHJlZHVuZGFudCBzb3VyY2VzLiBVc2UgdGhpcyB3aGVuIHlvdSB3YW50IHlvdXIgcmVhZHMgYW5kIHdyaXRlcyB0byBiZSBzb21ld2hhdCBhdG9taWM6IHRoZXJlIHdpbGwgc3RpbGwgYmUgaXNzdWVzIHdpdGggdGhlIHJvdW5kIHRyaXAsIGJ1dCB3aXRob3V0IGl0IHlvdSBjb3VsZCB0YWxrIHRvIGEgY29tcGxldGVseSBkaWZmZXJlbnQgbm9kZSBhbmQgZ2V0IGEgbXVjaCBvbGRlciB2YWx1ZS4gTW9zdCByZWFkcyBhcmVuJ3QgZm9sbG93ZWQgYnkgYSB3cml0ZSB0aG91Z2gsIHNvIGZvciBtb3N0IGNhc2VzIGl0J3MgYmV0dGVyIHRvIGdldCBhIHZhbHVlIHRoYW4gdG8gaGF2ZSB0byB3YWl0IChvciBldmVuIHRocm93KSB3aGVuIHRoZSBwcmltYXJ5IG5vZGUgaXMgbm90IGF2YWlsYWJsZS4gKi9cbiAgICBub0ZhbGxiYWNrcz86IGJvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBDaGFuZ2VzQWZ0ZXJDb25maWcgPSB7XG4gICAgdGltZTogbnVtYmVyO1xuICAgIC8qKiBPbmx5IGtleXMgcm91dGluZyBpbnRvIG9uZSBvZiB0aGVzZSBbc3RhcnQsIGVuZCkgcmFuZ2VzLiBPbmx5IHNjYW5uaW5nIHBhc3NlcyB0aGlzIC0gaXQgbGV0cyBhIHN0b3JlIHN5bmNpbmcgYSBwYXJ0aWFsIHNoYXJkIGFzayBmb3IganVzdCBpdHMgc2xpY2UuICovXG4gICAgcm91dGVzPzogW251bWJlciwgbnVtYmVyXVtdO1xufTtcblxuZXhwb3J0IHR5cGUgU2V0Q29uZmlnID0ge1xuICAgIGxhc3RNb2RpZmllZD86IG51bWJlcjtcbiAgICAvKiogTWFrZXMgdGhlIHdyaXRlIGFjY2VwdGFibGUgb24gaW1tdXRhYmxlIHRhcmdldHM6IGFuIGV4aXN0aW5nIHBhdGggaXMgc2ltcGx5IGtlcHQgKGltbXV0YWJpbGl0eSB3aW5zIC0gbm90aGluZyBpcyBvdmVyd3JpdHRlbikgaW5zdGVhZCBvZiB0aGUgd3JpdGUgdGhyb3dpbmcuIFJlcXVpcmVzIGxhc3RNb2RpZmllZC4gU3luY2hyb25pemF0aW9uIE1VU1QgcGFzcyB0aGlzIG9uIGV2ZXJ5IHB1c2ggLSBhIHBsYWluIHNldCB0aHJvd3Mgb24gaW1tdXRhYmxlIHRhcmdldHMsIHdoaWNoIHdvdWxkIGFib3J0IHJlY29uY2lsaWF0aW9uIHdoZW5ldmVyIG9uZSBzb3VyY2UgaW4gYSBjaGFpbiBpcyBpbW11dGFibGUuICovXG4gICAgZm9yY2VTZXRJbW11dGFibGU/OiBib29sZWFuO1xuICAgIC8qKiBTa2lwcyB0aGUgdGFyZ2V0LXNpZGUgc2FmZXR5IHJlYWRzIGFyb3VuZCB0aGUgd3JpdGUgKGJhY2tibGF6ZTogdGhlIHByZS13cml0ZSBnZXRJbmZvIGNvbXBhcmlzb24gYW5kIHRoZSBwb3N0LXVwbG9hZCBleGlzdGVuY2UgcG9sbCkuIEZvciB3cml0ZXJzIHdob3NlIG93biBib29ra2VlcGluZyBhbHJlYWR5IGRlY2lkZXMgd2hhdCB0byB3cml0ZSBhbmQgb3JkZXJzIGl0IGJ5IHdyaXRlIHRpbWUgKEJsb2JTdG9yZSdzIGluZGV4LWRyaXZlbiB3cml0ZXMgYW5kIHN5bmNocm9uaXphdGlvbiksIHRob3NlIHJlYWRzIGFyZSBwdXJlIGV4dHJhIEFQSSBjYWxscyAtIGJ1dCB0aGUgZGVmYXVsdCBzdGF5cyBjaGVja2VkLCBiZWNhdXNlIG90aGVyIHVzZXJzIG9mIHRoZSByYXcgYmFja2VuZHMgcmVseSBvbiB0aGUgY2hlY2tzLiAqL1xuICAgIG5vQ2hlY2tzPzogYm9vbGVhbjtcbn07XG5cbi8vIGNyZWF0ZVRpbWUgaXMgYSBtaXNub21lciBrZXB0IGZvciBjb21wYXRpYmlsaXR5IOKAlCBpdCBpcyByZWFsbHkgdGhlIExBU1QtV1JJVEUgdGltZSwgc2FtZSBhcyBnZXRJbmZvJ3Mgd3JpdGVUaW1lLiBOZWl0aGVyIEJhY2tibGF6ZSBub3Igb3VyIHJlbW90ZSBzdG9yYWdlIHRyYWNrcyBhIGRpc3RpbmN0IGNyZWF0aW9uIGRhdGU6IGVhY2ggd3JpdGUgc3RhbXBzIGEgZnJlc2ggdGltZXN0YW1wIG9uIHRoZSBjdXJyZW50IHZlcnNpb24sIHNvIGJvdGggZmllbGRzIGFyZSBqdXN0IFwid2hlbiB0aGUgYnl0ZXMgc2VydmVkIGJ5IGdldCgpIHdlcmUgbW9zdCByZWNlbnRseSB3cml0dGVuXCIuXG5leHBvcnQgdHlwZSBBcmNoaXZlRmlsZUluZm8gPSB7IHBhdGg6IHN0cmluZzsgY3JlYXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfTtcblxuLy8gQW4gaW4tcHJvZ3Jlc3MgYmFja2dyb3VuZCBzeW5jaHJvbml6YXRpb24gdGFzayAoc2VlIEFyY2hpdmVzQ29uZmlnLnN5bmNpbmcpXG5leHBvcnQgdHlwZSBTeW5jQWN0aXZpdHkgPSB7XG4gICAgLy8gQSBtZXRhZGF0YSBzY2FuIGlzIGEgc2luZ2xlIGxpc3RpbmcgY2FsbCwgc28gaXQgaGFzIG5vIGluY3JlbWVudGFsIHByb2dyZXNzIC0ganVzdCB0aGF0IGl0J3MgcnVubmluZyBhbmQgc2luY2Ugd2hlbi4gQSBmdWxsIHN5bmMga25vd3MgaXRzIGV4YWN0IGZpbGUvYnl0ZSBwcm9ncmVzcy5cbiAgICB0eXBlOiBcIm1ldGFkYXRhU2NhblwiIHwgXCJmdWxsU3luY1wiO1xuICAgIHNvdXJjZURlYnVnTmFtZTogc3RyaW5nO1xuICAgIHN0YXJ0VGltZTogbnVtYmVyO1xuICAgIGRvbmVGaWxlcz86IG51bWJlcjtcbiAgICB0b3RhbEZpbGVzPzogbnVtYmVyO1xuICAgIGRvbmVCeXRlcz86IG51bWJlcjtcbiAgICB0b3RhbEJ5dGVzPzogbnVtYmVyO1xufTtcblxuZXhwb3J0IHR5cGUgQXJjaGl2ZXNDb25maWcgPSB7XG4gICAgLy8gV2hldGhlciBnZXRDaGFuZ2VzQWZ0ZXIyIGlzIG5hdGl2ZWx5IGluZGV4LWJhY2tlZCAoZmFzdCBjaGFuZ2UgcG9sbGluZzsgZXZlcnkgYmFja2VuZCBzdGlsbCBzZXJ2ZXMgaXQsIGJ1dCB0aGUgb3RoZXJzIGVtdWxhdGUgaXQgd2l0aCBhIGZ1bGwgbGlzdGluZylcbiAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcj86IGJvb2xlYW47XG4gICAgLy8gVGhlIGJ1Y2tldCdzIGZ1bGwgcm91dGluZyBjb25maWcgKFJPVVRJTkdfRklMRSkuIEFic2VudCBmb3Igc291cmNlcyB0aGF0IGRvbid0IGhhdmUgb25lIChhIGJhcmUgZGlzayBzb3VyY2UsIG9yIGEgYnVja2V0IHRoYXQgZG9lc24ndCBleGlzdCB5ZXQpLlxuICAgIHJlbW90ZUNvbmZpZz86IFJlbW90ZUNvbmZpZztcbiAgICAvLyBMaXZlIGluZGV4IHRvdGFscyAodG9tYnN0b25lcyBleGNsdWRlZCksIGtlcHQgdXAgdG8gZGF0ZSBpbiBtZW1vcnkgb24gZXZlcnkgbXV0YXRpb24gYW5kIHJlY29tcHV0ZWQgb24gbG9hZCAtIHNvIGFueSBkcmlmdCBoZWFscyBvbiByZXN0YXJ0XG4gICAgaW5kZXg/OiB7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9O1xuICAgIC8vIFRoZSBzYW1lIHRvdGFscyBicm9rZW4gZG93biBieSB3aGljaCBzb3VyY2UgY3VycmVudGx5IGhvbGRzIGVhY2ggZmlsZSdzIGJ5dGVzICh0aGUgZmlyc3QgZW50cnkgaXMgdGhlIHNlcnZlcidzIG93biBkaXNrKVxuICAgIGluZGV4U291cmNlcz86IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W107XG4gICAgLy8gVGhlIHNlcnZlcidzIGNvbmZpZ3VyZWQgcmVhZGVyRGlza0xpbWl0LCB3aGVuIGl0IHJ1bnMgYXMgYSBib3VuZGVkIHJlYWQgY2FjaGVcbiAgICByZWFkZXJEaXNrTGltaXQ/OiBudW1iZXI7XG4gICAgLy8gQmFja2dyb3VuZCBzeW5jaHJvbml6YXRpb24gY3VycmVudGx5IGluIHByb2dyZXNzIChlbXB0eSB3aGVuIGlkbGUpXG4gICAgc3luY2luZz86IFN5bmNBY3Rpdml0eVtdO1xufTtcblxuLy8gQSBzeW5jaHJvbml6YXRpb24gc291cmNlIG9mIGEgQmxvYlN0b3JlICh3aGljaCBzeW5jaHJvbml6ZXMgYW4gaW5kZXggKyBsb2NhbCBjYWNoZSBmcm9tIHRoZW0pXG5leHBvcnQgdHlwZSBBcmNoaXZlc1NvdXJjZSA9IHtcbiAgICBzb3VyY2U6IElBcmNoaXZlcztcbiAgICAvKiogVGhlIHBlcnNpc3RlbnQgaWRlbnRpdHkgb2YgdGhlIGVuZHBvaW50OiBpdHMgcm91dGluZyBVUkwgKGhvc3RlZC9iYWNrYmxhemUpLCBvciB0aGUgZGlzayBmb2xkZXIgcGF0aCBmb3IgdGhlIGJhc2UgZGlzayBzb3VyY2UuIFRoZSBzdG9yZSBwZXJzaXN0cyB0aGlzICh2aWEgaXRzIGFwcGVuZC1vbmx5IHNvdXJjZXMgbGlzdCkgYXMgSW5kZXhFbnRyeS5zb3VyY2VzTGlzdEluZGV4LCBzbyBpdCBtdXN0IG1lYW4gdGhlIHNhbWUgZW5kcG9pbnQgZm9yZXZlci4gKi9cbiAgICB1cmw6IHN0cmluZztcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWcuIFZhbHVlcyB3aXRoIHdyaXRlIHRpbWVzIG91dHNpZGUgdGhlIHdpbmRvdyBhcmUgaWdub3JlZCB3aGVuIHNjYW5uaW5nLCBhbmQgb25jZSBpdHMgZW5kIGlzIHBhc3QgKHNlZSB3aW5kb3dBY2NlcHRzV3JpdGVzKSB0aGUgc291cmNlIHN0b3BzIHJlY2VpdmluZyB3cml0ZXMgZW50aXJlbHkgLSBzdGlsbCBzY2FubmVkIChpdCBob2xkcyB0aGUgYXV0aG9yaXRhdGl2ZSBkYXRhIGZvciBpdHMgd2luZG93KSwgaXQganVzdCBzdG9wcyBncm93aW5nLlxuICAgIHZhbGlkV2luZG93OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIC8vIEZyb20gdGhlIHNvdXJjZSdzIENvbW1vbkNvbmZpZyAoaW50ZXJzZWN0ZWQgd2l0aCB0aGUgb3duaW5nIHN0b3JlJ3Mgb3duIHJvdXRlKTogb25seSBrZXlzIHJvdXRpbmcgaW50byBbc3RhcnQsIGVuZCkgYXJlIGFjY2VwdGVkIGZyb20gdGhpcyBzb3VyY2UncyBzY2FucyBhbmQgc2VudCB0byBpdCBpbiB3cml0ZXMvcmVjb25jaWxpYXRpb24uIFRoZSByb3V0aW5nIGZpbGUgaXMgZXhlbXB0IC0gY29uZmlnIGZsb3dzIGV2ZXJ5d2hlcmUuIEFic2VudCA9IGFsbCBrZXlzLlxuICAgIHJvdXRlPzogW251bWJlciwgbnVtYmVyXTtcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWc7IHNlZSB0aGVyZS5cbiAgICBub0Z1bGxTeW5jPzogYm9vbGVhbjtcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWc6IGEgZGVwbG95IHN3aXRjaG92ZXIncyB0ZW1wb3JhcnkgYWx0ZXJuYXRlLXBvcnQgZW50cnkuIE9uY2UgaXRzIHdpbmRvdyBpcyBwYXN0LCB0aGUgcG9ydCBpdCBwb2ludHMgYXQgaXMgZ29uZSBmb3IgZ29vZCAtIHNvIGl0IGlzIG5ldmVyIHNjYW5uZWQgdGhlbiwgYW5kIHNjYW4gZmFpbHVyZXMgYXJlIG5ldmVyIHJldHJpZWQuXG4gICAgaW50ZXJtZWRpYXRlPzogYm9vbGVhbjtcbiAgICAvLyBTdGFibGUgaWRlbnRpdHkgb2YgdGhlIHVuZGVybHlpbmcgZW5kcG9pbnQgKGl0cyBjb25maWcgd2l0aCB3aW5kb3dzL3JvdXRlcyBzdHJpcHBlZCkgLSBob3cgQmxvYlN0b3JlLnVwZGF0ZVNvdXJjZXMgcmVjb2duaXplcyBhIHNvdXJjZSBhY3Jvc3MgY29uZmlnIGNoYW5nZXMgc28gaXQgY2FuIHVwZGF0ZSBpdCBpbiBwbGFjZSBpbnN0ZWFkIG9mIHJlbW92aW5nIGFuZCByZS1hZGRpbmcgaXRcbiAgICBpZGVudGl0eT86IHN0cmluZztcbn07XG5cbi8vIEVycm9yIG1hcmtlciBhIHNlcnZlciBpbmNsdWRlcyB3aGVuIGEgZnJlc2hseS1zdGFtcGVkIHdyaXRlIHJlYWNoZXMgaXQgb3V0c2lkZSBpdHMgdmFsaWQgd2luZG93cyAodGhlIGNsaWVudCByZXNvbHZlZCBpdHMgdGFyZ2V0LCB0aGVuIHRpbWUgY3Jvc3NlZCBhIHdpbmRvdyBib3VuZGFyeSBiZWZvcmUgdGhlIHdyaXRlIGxhbmRlZCkuIENsaWVudHMgZGV0ZWN0IHRoaXMgbWFya2VyIGFuZCByZS1yZXNvbHZlIHRoZSBjdXJyZW50bHktdmFsaWQgc291cmNlLCByZXRyeWluZyBPTkNFIC0gYm91bmRhcmllcyBhcmUgZmFyIGFwYXJ0LCBzbyBoaXR0aW5nIGl0IHR3aWNlIGluIG9uZSBhdHRlbXB0IG1lYW5zIHNvbWV0aGluZyBpcyBhY3R1YWxseSB3cm9uZy5cbmV4cG9ydCBjb25zdCBTVE9SQUdFX1dST05HX1ZBTElEX1dJTkRPVyA9IFwiUkVNT1RFX1NUT1JBR0VfV1JPTkdfVkFMSURfV0lORE9XX2E3YzFmMDRlXCI7XG5cbi8vIEVycm9yIG1hcmtlciBhIHNlcnZlciBpbmNsdWRlcyB3aGVuIGEgZnJlc2hseS1zdGFtcGVkIHdyaXRlJ3Mga2V5IHJvdXRlcyBvdXRzaWRlIHRoZSBzaGFyZHMgdGhpcyBzZXJ2ZXIgaGFuZGxlcyAodGhlIGNsaWVudCdzIGNvbmZpZyBkaXNhZ3JlZXMgd2l0aCB0aGUgc2VydmVyJ3MgLSBjbGllbnRzIHJlLXJlc29sdmUgb25jZSlcbmV4cG9ydCBjb25zdCBTVE9SQUdFX1dST05HX1JPVVRFID0gXCJSRU1PVEVfU1RPUkFHRV9XUk9OR19ST1VURV9jOTRkMmUxN1wiO1xuXG5leHBvcnQgY29uc3QgRlVMTF9ST1VURTogW251bWJlciwgbnVtYmVyXSA9IFswLCAxXTtcblxuLy8gQSBrZXkgY29udGFpbmluZyB0aGlzIHNlbnRpbmVsIGRvZXNuJ3QgaGF2ZSBhIGZpeGVkIHNoYXJkOiBzZXRWYXJpYWJsZVNoYXJkIHBpY2tzIHRoZSAobG93ZXN0IGxhdGVuY3ksIHVwKSB3cml0ZSBzaGFyZCwgYXBwZW5kcyBcIl88dmFsdWUgaW4gdGhlIHNoYXJkJ3Mgcm91dGU+XCIgZGlyZWN0bHkgYWZ0ZXIgdGhlIHNlbnRpbmVsLCBhbmQgcmV0dXJucyB0aGUgbWF0ZXJpYWxpemVkIGtleS4gZ2V0Um91dGUgdHJlYXRzIHRoYXQgc3VmZml4IGFzIGEgY29tcGxldGUgcm91dGUgb3ZlcnJpZGUuXG5leHBvcnQgY29uc3QgVkFSSUFCTEVfU0hBUkQgPSBcIlZBUklBQkxFX1NIQVJEX2YwMjM0amZhaDA4Zmd5aGZneXNzZGRzODNubXBcIjtcbi8vIE5vIGdyYWNlIHBhc3QgdGhlIGVuZDogYSB3aW5kb3cgYm91bmRhcnkgaXMgYSBoYXJkIGhhbmRvZmYgKGNsaWVudHMgcmV0cnkgYSByZWplY3RlZCB3cml0ZSBhZ2FpbnN0IHRoZSBuZXdseS12YWxpZCBzb3VyY2UsIHNvIGxlbmllbmN5IGhlcmUgd291bGQgb25seSBkZXN5bmNocm9uaXplIHRoZSBoYW5kb2ZmKVxuZXhwb3J0IGZ1bmN0aW9uIHdpbmRvd0FjY2VwdHNXcml0ZXModmFsaWRXaW5kb3c6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkV2luZG93KSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gdmFsaWRXaW5kb3dbMV0gPiBEYXRlLm5vdygpO1xufVxuXG5jb25zdCBMQVJHRV9DT1BZX1RIUkVTSE9MRCA9IDY0ICogMTAyNCAqIDEwMjQ7XG5jb25zdCBMQVJHRV9DT1BZX0NIVU5LID0gMzIgKiAxMDI0ICogMTAyNDtcblxuLyoqIENvcGllcyBvbmUgZmlsZSBiZXR3ZWVuIHR3byBhcmNoaXZlcy4gU21hbGwgZmlsZXMgZ28gYXMgYSBzaW5nbGUgZ2V0MitzZXQ7IHBhc3QgTEFSR0VfQ09QWV9USFJFU0hPTEQgdGhlIGNvcHkgc3RyZWFtcyB0aHJvdWdoIHNldExhcmdlRmlsZSBpbiBMQVJHRV9DT1BZX0NIVU5LIHJhbmdlZCByZWFkcywgc28gdGhlIHdob2xlIGZpbGUgaXMgbmV2ZXIgaW4gbWVtb3J5LiBzaXplL3dyaXRlVGltZSB1c3VhbGx5IGNvbWUgZnJvbSB0aGUgY2FsbGVyJ3MgbWV0YWRhdGEgc2Nhbjsgd2hlbiBlaXRoZXIgaXMgb21pdHRlZCwgZ2V0SW5mbyBmaWxscyB0aGVtIGluLiBSZXR1cm5zIHRoZSBjb3BpZWQgZmlsZSdzIGluZm8sIG9yIHVuZGVmaW5lZCB3aGVuIHRoZSBzb3VyY2UgZG9lc24ndCBoYXZlIHRoZSBmaWxlLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvcHlBcmNoaXZlRmlsZShjb25maWc6IHtcbiAgICBmcm9tOiBJQXJjaGl2ZXM7XG4gICAgdG86IElBcmNoaXZlcztcbiAgICBwYXRoOiBzdHJpbmc7XG4gICAgc2l6ZT86IG51bWJlcjtcbiAgICB3cml0ZVRpbWU/OiBudW1iZXI7XG4gICAgZm9yY2VTZXRJbW11dGFibGU/OiBib29sZWFuO1xuICAgIG5vQ2hlY2tzPzogYm9vbGVhbjtcbn0pOiBQcm9taXNlPHsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgbGV0IHsgZnJvbSwgdG8sIHBhdGggfSA9IGNvbmZpZztcbiAgICBsZXQgc2l6ZSA9IGNvbmZpZy5zaXplO1xuICAgIGxldCB3cml0ZVRpbWUgPSBjb25maWcud3JpdGVUaW1lO1xuICAgIGlmIChzaXplID09PSB1bmRlZmluZWQgfHwgd3JpdGVUaW1lID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGV0IGluZm8gPSBhd2FpdCBmcm9tLmdldEluZm8ocGF0aCk7XG4gICAgICAgIGlmICghaW5mbykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgc2l6ZSA9IGluZm8uc2l6ZTtcbiAgICAgICAgd3JpdGVUaW1lID0gaW5mby53cml0ZVRpbWU7XG4gICAgfVxuICAgIGlmIChzaXplIDw9IExBUkdFX0NPUFlfVEhSRVNIT0xEKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBmcm9tLmdldDIocGF0aCk7XG4gICAgICAgIGlmICghcmVzdWx0KSByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICBhd2FpdCB0by5zZXQocGF0aCwgcmVzdWx0LmRhdGEsIHsgbGFzdE1vZGlmaWVkOiByZXN1bHQud3JpdGVUaW1lLCBmb3JjZVNldEltbXV0YWJsZTogY29uZmlnLmZvcmNlU2V0SW1tdXRhYmxlLCBub0NoZWNrczogY29uZmlnLm5vQ2hlY2tzIH0pO1xuICAgICAgICByZXR1cm4geyB3cml0ZVRpbWU6IHJlc3VsdC53cml0ZVRpbWUsIHNpemU6IHJlc3VsdC5kYXRhLmxlbmd0aCB9O1xuICAgIH1cbiAgICAvLyBDb25zdHMgc28gdGhlIGNsb3N1cmUga2VlcHMgdGhlIG5hcnJvd2VkIHR5cGVzXG4gICAgY29uc3QgdG90YWxTaXplID0gc2l6ZTtcbiAgICBjb25zdCBmaW5hbFdyaXRlVGltZSA9IHdyaXRlVGltZTtcbiAgICBsZXQgb2Zmc2V0ID0gMDtcbiAgICBhd2FpdCB0by5zZXRMYXJnZUZpbGUoe1xuICAgICAgICBwYXRoLFxuICAgICAgICBsYXN0TW9kaWZpZWQ6IGZpbmFsV3JpdGVUaW1lLFxuICAgICAgICBnZXROZXh0RGF0YTogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgaWYgKG9mZnNldCA+PSB0b3RhbFNpemUpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBsZXQgZW5kID0gTWF0aC5taW4ob2Zmc2V0ICsgTEFSR0VfQ09QWV9DSFVOSywgdG90YWxTaXplKTtcbiAgICAgICAgICAgIGxldCBkYXRhID0gYXdhaXQgZnJvbS5nZXQocGF0aCwgeyByYW5nZTogeyBzdGFydDogb2Zmc2V0LCBlbmQgfSB9KTtcbiAgICAgICAgICAgIGlmICghZGF0YSB8fCAhZGF0YS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJhbmdlZCByZWFkIG9mICR7SlNPTi5zdHJpbmdpZnkocGF0aCl9IGZyb20gJHtmcm9tLmdldERlYnVnTmFtZSgpfSByZXR1cm5lZCAke2RhdGEgJiYgZGF0YS5sZW5ndGggfHwgXCJub3RoaW5nXCJ9IGF0ICR7b2Zmc2V0fS0ke2VuZH0gKGV4cGVjdGVkICR7ZW5kIC0gb2Zmc2V0fSBieXRlcyBvZiBhICR7dG90YWxTaXplfSBieXRlIGZpbGUgLSBpdCBjaGFuZ2VkIG9yIHZhbmlzaGVkIG1pZC1jb3B5KWApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgb2Zmc2V0ICs9IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHsgd3JpdGVUaW1lOiBmaW5hbFdyaXRlVGltZSwgc2l6ZTogdG90YWxTaXplIH07XG59XG5cbmV4cG9ydCB0eXBlIEFyY2hpdmVzU3luY1NvdXJjZVN0YXR1cyA9IHtcbiAgICBkZWJ1Z05hbWU6IHN0cmluZztcbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICByb3V0ZT86IFtudW1iZXIsIG51bWJlcl07XG4gICAgbm9GdWxsU3luYz86IGJvb2xlYW47XG4gICAgc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI6IGJvb2xlYW47XG4gICAgaW5pdGlhbFNjYW5Db21wbGV0ZTogYm9vbGVhbjtcbiAgICAvLyBGaWxlcyBzZWVuIGluIHRoaXMgc291cmNlJ3Mgc2NhbnMgLyBjaGFuZ2UgcG9sbHMgc28gZmFyXG4gICAgc2Nhbm5lZENvdW50OiBudW1iZXI7XG59O1xuZXhwb3J0IHR5cGUgQXJjaGl2ZXNTeW5jU3RhdHVzID0ge1xuICAgIGFsbFNjYW5zQ29tcGxldGU6IGJvb2xlYW47XG4gICAgLy8gTnVtYmVyIG9mIGZpbGVzIGluIHRoZSBpbmRleFxuICAgIGluZGV4U2l6ZTogbnVtYmVyO1xuICAgIHNvdXJjZXM6IEFyY2hpdmVzU3luY1NvdXJjZVN0YXR1c1tdO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBJQXJjaGl2ZXMge1xuICAgIGdldERlYnVnTmFtZSgpOiBzdHJpbmc7XG4gICAgLyoqIFdoZXRoZXIgd3JpdGVzIHdvdWxkIGJlIGFjY2VwdGVkIChjcmVkZW50aWFscyBleGlzdCwgdGhlIGFjY291bnQgdHJ1c3RzIHRoaXMgbWFjaGluZSwgZXRjKS4gQ2hlY2tlZCB3aXRob3V0IHdyaXRpbmcgYW55dGhpbmcuICovXG4gICAgaGFzV3JpdGVBY2Nlc3MoKTogUHJvbWlzZTxib29sZWFuPjtcbiAgICAvKipcbiAgICAgKiBSZWFkcyBhdXRvbWF0aWNhbGx5IGZhbGwgYmFjayBhY3Jvc3MgdGhlIHJlZHVuZGFudCBzb3VyY2VzIHVubGVzcyBjb25maWcubm9GYWxsYmFja3MgaXMgc2V0LlxuICAgICAqIEEgZmFsbGJhY2sgY29weSBjYW4gbGFnIHRoZSB3cml0ZSB0YXJnZXQsIHNvIGEgY2FsbGVyIHJlYWRpbmcgc3RhdGUgaW4gb3JkZXIgdG8gbXV0YXRlIGl0XG4gICAgICogKGUuZy4geCsrKSwgd2hlcmUgYWN0aW5nIG9uIHByZXZpb3VzIHN0YXRlIHdvdWxkIGNhdXNlIGJpZyBpc3N1ZXMsIHNob3VsZCBwYXNzIG5vRmFsbGJhY2tzIC1cbiAgICAgKiBhbmQgdHJ5L2NhdGNoIHRoZSByZWFkLCBoYW5kbGluZyB0aGUgY2F0Y2ggY2FzZSAoYSBkb3duIHByaW1hcnkgaXMgcmV0cmllZCBmb3IgYSB3aGlsZSwgdGhlblxuICAgICAqIHRocm93cyBpbnN0ZWFkIG9mIGRlZ3JhZGluZyB0byBhIHN0YWxlIGNvcHkpLlxuICAgICAqL1xuICAgIGdldChmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiBHZXRDb25maWcpOiBQcm9taXNlPEJ1ZmZlciB8IHVuZGVmaW5lZD47XG4gICAgLyoqIFNlZSBnZXQgZm9yIHRoZSBmYWxsYmFjayBzZW1hbnRpY3MgKGFuZCB3aGVuIHRvIHBhc3Mgbm9GYWxsYmFja3MpLiB1cmwgaXMgdGhlIGNvbmZpZyBVUkwgb2YgdGhlIHNvdXJjZSB0aGF0IHNlcnZlZCB0aGUgdmFsdWUgLSBzZXQgYnkgbXVsdGktc291cmNlIGltcGxlbWVudGF0aW9ucyAoQXJjaGl2ZXNDaGFpbiksIGFic2VudCBmcm9tIHNpbmdsZS1zb3VyY2UgYmFja2VuZHMuICovXG4gICAgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiBHZXRDb25maWcpOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyOyB1cmw/OiBzdHJpbmcgfSB8IHVuZGVmaW5lZD47XG4gICAgLyoqXG4gICAgICogbGFzdE1vZGlmaWVkIHN0YW1wcyB0aGUgd3JpdGUgd2l0aCB0aGF0IGxhc3Qtd3JpdGUgdGltZSBpbnN0ZWFkIG9mIG5vdy4gSWYgaXQgaXMgT0xERVIgdGhhblxuICAgICAqIHRoZSBmaWxlJ3MgY3VycmVudCBsYXN0LXdyaXRlIHRpbWUgdGhlIHdyaXRlIG5vLW9wcyAoc28gZGVsYXllZCAvIHN5bmNocm9uaXplZCB3cml0ZXMgY2FuXG4gICAgICogbmV2ZXIgY2xvYmJlciBuZXdlciBkYXRhKS4gVGltZXMgbW9yZSB0aGFuIDE1IG1pbnV0ZXMgaW4gdGhlIGZ1dHVyZSBhcmUgcmVqZWN0ZWQuXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIHRoZSBmdWxsIGtleSBhY3R1YWxseSB3cml0dGVuIC0gaWRlbnRpY2FsIHRvIGZpbGVOYW1lLCBFWENFUFQgZm9yIGtleXMgY29udGFpbmluZ1xuICAgICAqIFZBUklBQkxFX1NIQVJELCB3aGVyZSB0aGUgc2hhcmQgdmFsdWUgaXMgbWF0ZXJpYWxpemVkIGludG8gdGhlIGtleSAocGlja2VkIGJ5IHNoYXJkIGxhdGVuY3ksXG4gICAgICogc2VlIEFyY2hpdmVzQ2hhaW4pIGFuZCB0aGUgY2FsbGVyIG5lZWRzIHRoZSByZXR1cm5lZCBrZXkgdG8gZXZlciByZWFkIHRoZSB2YWx1ZSBiYWNrLlxuICAgICAqL1xuICAgIHNldChmaWxlTmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IFNldENvbmZpZyk6IFByb21pc2U8c3RyaW5nPjtcbiAgICBkZWwoZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gICAgLyoqIFN0cmVhbXMgYSBmaWxlIHRvbyBsYXJnZSB0byBob2xkIGluIG1lbW9yeS4gZ2V0TmV4dERhdGEgcmV0dXJucyB1bmRlZmluZWQgd2hlbiBkb25lLiBsYXN0TW9kaWZpZWQgc3RhbXBzIHRoZSBmaW5pc2hlZCBmaWxlIGxpa2Ugc2V0J3MgKHN5bmNocm9uaXplZCBjb3BpZXMgbmVlZCBpdCB0byBrZWVwIHdyaXRlIG9yZGVyaW5nKTsgYmFja2VuZHMgdGhhdCBzdGFtcCB0aGVpciBvd24gdGltZXMgKGJhY2tibGF6ZSkgYWNjZXB0IGFuZCBpZ25vcmUgaXQuICovXG4gICAgc2V0TGFyZ2VGaWxlKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGxhc3RNb2RpZmllZD86IG51bWJlcjsgZ2V0TmV4dERhdGEoKTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+IH0pOiBQcm9taXNlPHZvaWQ+O1xuICAgIC8qKiB3cml0ZVRpbWUgaXMgdGhlIGxhc3Qtd3JpdGUgdGltZSDigJQgc2VlIEFyY2hpdmVGaWxlSW5mby5jcmVhdGVUaW1lLCB3aGljaCBpcyB0aGUgc2FtZSB2YWx1ZS4gdXJsIGFzIGluIGdldDIuICovXG4gICAgZ2V0SW5mbyhmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXI7IHVybD86IHN0cmluZyB9IHwgdW5kZWZpbmVkPjtcbiAgICBmaW5kKHByZWZpeDogc3RyaW5nLCBjb25maWc/OiB7IHNoYWxsb3c/OiBib29sZWFuOyB0eXBlOiBcImZpbGVzXCIgfCBcImZvbGRlcnNcIiB9KTogUHJvbWlzZTxzdHJpbmdbXT47XG4gICAgZmluZEluZm8ocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPjtcbiAgICAvKiogT25seSB3b3JrcyBmb3IgcHVibGljIGJ1Y2tldHMgKHByaXZhdGUgYnVja2V0cyBhcmUgQVBJLWFjY2VzcyBvbmx5KS4gKi9cbiAgICBnZXRVUkwocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+O1xuICAgIC8qKiBUaGUgYnVja2V0J3MgY29uZmlndXJhdGlvbiwgd2hpY2ggdGVsbHMgd2hldGhlciB0aGUgb3B0aW9uYWwgZnVuY3Rpb25zIGFyZSBzdXBwb3J0ZWQuICovXG4gICAgZ2V0Q29uZmlnKCk6IFByb21pc2U8QXJjaGl2ZXNDb25maWc+O1xuICAgIC8qKlxuICAgICAqIEFsbCBmaWxlcyBjaGFuZ2VkIGFmdGVyIGNvbmZpZy50aW1lLCBvcHRpb25hbGx5IHJlc3RyaWN0ZWQgdG8ga2V5cyByb3V0aW5nIGludG8gb25lIG9mXG4gICAgICogY29uZmlnLnJvdXRlcyAodXNlZCBieSBzY2FubmluZywgc28gcGFydGlhbGx5LW92ZXJsYXBwaW5nIHNoYXJkcyBvbmx5IHJlY2VpdmUgdGhlaXIgc2xpY2UpLlxuICAgICAqIFdoZW4gZ2V0Q29uZmlnKCkuc3VwcG9ydHNDaGFuZ2VzQWZ0ZXIsIHRoaXMgaXMgYmFja2VkIGJ5IGFuIGluZGV4IChmYXN0LCBhbmQgZGVsZXRpb25zIEFSRVxuICAgICAqIHJlcG9ydGVkLCBhcyBzaXplLTAgdG9tYnN0b25lIGVudHJpZXMpLiBFdmVyeSBvdGhlciBiYWNrZW5kIGVtdWxhdGVzIGl0OiBhIGZ1bGwgZmluZEluZm9cbiAgICAgKiBsaXN0aW5nIGZpbHRlcmVkIGluIG1lbW9yeSAtIGNvcnJlY3QsIGJ1dCBubyBjaGVhcGVyIHRoYW4gdGhlIGxpc3RpbmcgaXRzZWxmLlxuICAgICAqL1xuICAgIGdldENoYW5nZXNBZnRlcjIoY29uZmlnOiBDaGFuZ2VzQWZ0ZXJDb25maWcpOiBQcm9taXNlPEFyY2hpdmVGaWxlSW5mb1tdPjtcbiAgICAvKiogU3luY2hyb25pemF0aW9uIGludHJvc3BlY3Rpb24sIGZvciBiYWNrZW5kcyB0aGF0IHN5bmNocm9uaXplIGZyb20gc291cmNlcyAoc2VlIEJsb2JTdG9yZSkuICovXG4gICAgZ2V0U3luY1N0YXR1cz8oKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+O1xufVxuIl19
75
+ /* _JS_SOURCE_HASH = "320a7b817049e8b773e490e5931702a705700cd30252c53a4274c4dde2dd4674"; */
@@ -60,6 +60,7 @@ export type BlobSourceSpec = {
60
60
  validWindow: [number, number];
61
61
  route?: [number, number];
62
62
  noFullSync?: boolean;
63
+ intermediate?: boolean;
63
64
  create: () => IArchives;
64
65
  };
65
66
  export declare class BlobStore implements IBucketStore {
@@ -138,6 +139,7 @@ export declare class BlobStore implements IBucketStore {
138
139
  }>;
139
140
  private flushIndex;
140
141
  private runSourceSync;
142
+ private isDeadIntermediate;
141
143
  private scanSource;
142
144
  private reconcileSource;
143
145
  private updateScanIndex;
@@ -126,6 +126,8 @@ export type BlobSourceSpec = {
126
126
  validWindow: [number, number];
127
127
  route?: [number, number];
128
128
  noFullSync?: boolean;
129
+ // See ArchivesSource.intermediate
130
+ intermediate?: boolean;
129
131
  // Only called for sources that don't match an existing live slot
130
132
  create: () => IArchives;
131
133
  };
@@ -359,7 +361,7 @@ export class BlobStore implements IBucketStore {
359
361
  continue;
360
362
  }
361
363
  let source = spec.create();
362
- this.sources.push({ source, url: spec.url, validWindow: spec.validWindow, route: spec.route, noFullSync: spec.noFullSync, identity: spec.identity });
364
+ this.sources.push({ source, url: spec.url, validWindow: spec.validWindow, route: spec.route, noFullSync: spec.noFullSync, intermediate: spec.intermediate, identity: spec.identity });
363
365
  this.sourceStates.push(newSourceState());
364
366
  this.sourceFileCounts.push(0);
365
367
  this.sourceByteCounts.push(0);
@@ -525,14 +527,23 @@ export class BlobStore implements IBucketStore {
525
527
  let state = this.sourceStates[sourceIndex];
526
528
  // Read live for every pass, not captured - updateSources can change it while loops run
527
529
  let noFullSync = () => this.sources[sourceIndex].noFullSync;
530
+ let intermediate = this.sources[sourceIndex].intermediate;
528
531
  let listing: Map<string, number> | undefined;
529
532
  while (!this.stopped.stop && !state.stopped.stop) {
533
+ if (this.isDeadIntermediate(sourceIndex)) {
534
+ console.log(`Not scanning sync source ${source.getDebugName()} (store ${this.folder}): it is an intermediate whose window already ended`);
535
+ break;
536
+ }
530
537
  try {
531
538
  let config = await source.getConfig();
532
539
  state.supportsChangesAfter = !!config.supportsChangesAfter;
533
540
  listing = await this.scanSource(sourceIndex);
534
541
  break;
535
542
  } catch (e) {
543
+ if (intermediate) {
544
+ console.error(`Initial scan of intermediate sync source ${source.getDebugName()} (store ${this.folder}) failed; not retrying (intermediates are temporary switchover ports): ${(e as Error).stack ?? e}`);
545
+ break;
546
+ }
536
547
  console.error(`Initial scan of sync source ${source.getDebugName()} failed, retrying:`, e);
537
548
  await delay(SCAN_RETRY_DELAY);
538
549
  }
@@ -540,6 +551,8 @@ export class BlobStore implements IBucketStore {
540
551
  state.scanComplete = true;
541
552
  state.initialScan.resolve(undefined);
542
553
  if (this.stopped.stop || state.stopped.stop) return;
554
+ // An intermediate that never produced a listing is dead or dying - polling and copying from it would only log errors
555
+ if (intermediate && !listing) return;
543
556
  if (listing) {
544
557
  await this.reconcileSource(sourceIndex, listing);
545
558
  }
@@ -552,16 +565,19 @@ export class BlobStore implements IBucketStore {
552
565
  }
553
566
  if (state.supportsChangesAfter) {
554
567
  runInfinitePoll(CHANGES_POLL_INTERVAL, async () => {
568
+ if (this.isDeadIntermediate(sourceIndex)) return;
555
569
  await this.pollChanges(sourceIndex);
556
570
  if (!noFullSync()) await this.copySourceFiles(sourceIndex);
557
571
  }, state.stopped);
558
572
  // Change polls only show what the source HAS, never what it's missing, so pushes run on the full-rescan cadence (findInfo on an index-backed source is cheap)
559
573
  runInfinitePoll(FULL_RESCAN_INTERVAL, async () => {
574
+ if (this.isDeadIntermediate(sourceIndex)) return;
560
575
  let files = await source.findInfo("");
561
576
  await this.reconcileSource(sourceIndex, new Map(files.map(x => [x.path, x.createTime])));
562
577
  }, state.stopped);
563
578
  } else {
564
579
  runInfinitePoll(FULL_RESCAN_UNINDEXED_INTERVAL, async () => {
580
+ if (this.isDeadIntermediate(sourceIndex)) return;
565
581
  let rescan = await this.scanSource(sourceIndex);
566
582
  await this.reconcileSource(sourceIndex, rescan);
567
583
  if (!noFullSync()) await this.copySourceFiles(sourceIndex);
@@ -569,6 +585,12 @@ export class BlobStore implements IBucketStore {
569
585
  }
570
586
  }
571
587
 
588
+ // An intermediate is a deploy switchover's temporary alternate port: once its window is past, the port is gone for good, so scanning it (or retrying a failed scan) can never succeed - it would just log errors forever
589
+ private isDeadIntermediate(sourceIndex: number): boolean {
590
+ let { intermediate, validWindow } = this.sources[sourceIndex];
591
+ return !!intermediate && validWindow[1] <= Date.now();
592
+ }
593
+
572
594
  // Full metadata scan (size, writeTime, path) of one source, applied to the index. Returns the source's listing (path -> write time), which reconcileSource uses for the push direction.
573
595
  private async scanSource(sourceIndex: number): Promise<Map<string, number>> {
574
596
  let { source, validWindow, route } = this.sources[sourceIndex];
@@ -76,6 +76,9 @@ export declare class ArchivesChain implements IArchives {
76
76
  set(fileName: string, data: Buffer, config?: SetConfig): Promise<string>;
77
77
  private setRoutingConfig;
78
78
  del(fileName: string): Promise<void>;
79
+ private getVariableShardTargets;
80
+ /** The key setVariableShard would materialize for this VARIABLE_SHARD key (a value in the preferred shard's route range), without writing anything. */
81
+ getShardKey(key: string): Promise<string>;
79
82
  private setVariableShard;
80
83
  setLargeFile(config: {
81
84
  path: string;
@@ -83,7 +86,7 @@ export declare class ArchivesChain implements IArchives {
83
86
  getNextData(): Promise<Buffer | undefined>;
84
87
  }): Promise<void>;
85
88
  getURL(path: string): Promise<string>;
86
- /** Every URL that could serve this path, in source order. Empty when no public source covers the path's route. */
89
+ /** Every URL that could serve this path, in source order: public sources matching both the path's route and the current valid window. Empty when none qualify. */
87
90
  getURLs(path: string): Promise<string[]>;
88
91
  dispose(): void;
89
92
  }
@@ -63,6 +63,11 @@ function configAcceptsWrites(config: HostedConfig | BackblazeConfig): boolean {
63
63
  return configWindowCurrent(config);
64
64
  }
65
65
 
66
+ function materializeShardKey(key: string, target: SourceWrapper): string {
67
+ let [start, end] = target.config.route || FULL_ROUTE;
68
+ return key.replace(VARIABLE_SHARD, VARIABLE_SHARD + "_" + (start + Math.random() * (end - start)));
69
+ }
70
+
66
71
  /** The fewest sources whose routes span the whole key space, or undefined when they leave a gap. */
67
72
  function coverRoutes(candidates: SourceWrapper[]): SourceWrapper[] | undefined {
68
73
  let chosen: SourceWrapper[] = [];
@@ -536,6 +541,8 @@ export class ArchivesChain implements IArchives {
536
541
  public async waitingForAccess(): Promise<{ link: string; machineId: string; ip: string } | undefined> {
537
542
  let state = await this.getState();
538
543
  for (let source of state.sources) {
544
+ // A source whose window has passed is never read or written again, so its access state is irrelevant - and asking a dead intermediate would just hang or throw. Future windows DO matter: access should be granted before their window starts.
545
+ if (source.config.validWindow[1] <= Date.now()) continue;
539
546
  if (source.api instanceof ArchivesRemote) {
540
547
  let waiting = await source.api.waitingForAccess();
541
548
  if (waiting) return waiting;
@@ -696,24 +703,48 @@ export class ArchivesChain implements IArchives {
696
703
  await this.request({ write: true, route: getRoute(fileName) }, archives => archives.del(fileName));
697
704
  }
698
705
 
706
+ // One write target per route range, lowest latency first. Within a shard the target is ALWAYS the first source in config order (see runWrite - writes must stay on the same node): connectivity only decides which SHARD we pick, never which node within it, so a shard whose node is disconnected is dropped entirely when connectedOnly is set.
707
+ private getVariableShardTargets(state: ChainState, config: { connectedOnly: boolean }): SourceWrapper[] {
708
+ let targetsByRoute = new Map<string, SourceWrapper>();
709
+ for (let source of state.sources) {
710
+ if (!configAcceptsWrites(source.config)) continue;
711
+ let routeKey = JSON.stringify(source.config.route || FULL_ROUTE);
712
+ if (!targetsByRoute.has(routeKey)) {
713
+ targetsByRoute.set(routeKey, source);
714
+ }
715
+ }
716
+ let targets = [...targetsByRoute.values()];
717
+ if (config.connectedOnly) {
718
+ targets = targets.filter(x => x.isConnected());
719
+ }
720
+ sort(targets, x => x.getLatency());
721
+ return targets;
722
+ }
723
+
724
+ /** The key setVariableShard would materialize for this VARIABLE_SHARD key (a value in the preferred shard's route range), without writing anything. */
725
+ public async getShardKey(key: string): Promise<string> {
726
+ if (!key.includes(VARIABLE_SHARD) || parseVariableRoute(key) !== undefined) {
727
+ throw new Error(`getShardKey requires a key containing an unmaterialized ${JSON.stringify(VARIABLE_SHARD)}, got ${JSON.stringify(key)}`);
728
+ }
729
+ let state = await this.getState();
730
+ let target = this.getVariableShardTargets(state, { connectedOnly: true })[0]
731
+ || this.getVariableShardTargets(state, { connectedOnly: false })[0];
732
+ if (!target) {
733
+ throw new Error(`No source accepts writes for ${this.getDebugName()}, so there is no shard to materialize ${JSON.stringify(key)} into`);
734
+ }
735
+ return materializeShardKey(key, target);
736
+ }
737
+
699
738
  private async setVariableShard(key: string, data: Buffer, config?: SetConfig): Promise<string> {
700
739
  let recheckedAvailability = false;
740
+ // There's no point talking to a shard whose node was fast but is now disconnected - only when no connected shard works do we recheck availability and try every shard
741
+ let connectedOnly = true;
701
742
  while (true) {
702
743
  let state = await this.getState();
703
- let targetsByRoute = new Map<string, SourceWrapper>();
704
- for (let source of state.sources) {
705
- if (!configAcceptsWrites(source.config)) continue;
706
- let routeKey = JSON.stringify(source.config.route || FULL_ROUTE);
707
- if (!targetsByRoute.has(routeKey)) {
708
- targetsByRoute.set(routeKey, source);
709
- }
710
- }
711
- let targets = [...targetsByRoute.values()];
712
- sort(targets, x => x.getLatency());
744
+ let targets = this.getVariableShardTargets(state, { connectedOnly });
713
745
  let errors: string[] = [];
714
746
  for (let target of targets) {
715
- let [start, end] = target.config.route || FULL_ROUTE;
716
- let fullKey = key.replace(VARIABLE_SHARD, VARIABLE_SHARD + "_" + (start + Math.random() * (end - start)));
747
+ let fullKey = materializeShardKey(key, target);
717
748
  try {
718
749
  await target.write(archives => archives.set(fullKey, data, config));
719
750
  return fullKey;
@@ -726,6 +757,7 @@ export class ArchivesChain implements IArchives {
726
757
  }
727
758
  if (!recheckedAvailability) {
728
759
  recheckedAvailability = true;
760
+ connectedOnly = false;
729
761
  await this.recheckAvailability();
730
762
  continue;
731
763
  }
@@ -770,7 +802,7 @@ export class ArchivesChain implements IArchives {
770
802
  return urls[0];
771
803
  }
772
804
 
773
- /** Every URL that could serve this path, in source order. Empty when no public source covers the path's route. */
805
+ /** Every URL that could serve this path, in source order: public sources matching both the path's route and the current valid window. Empty when none qualify. */
774
806
  public async getURLs(path: string): Promise<string[]> {
775
807
  let state = await this.getState();
776
808
  let route = getRoute(path);
@@ -778,6 +810,7 @@ export class ArchivesChain implements IArchives {
778
810
  for (let source of state.sources) {
779
811
  if (!(source.config.public ?? true)) continue;
780
812
  if (!routeContains(source.config.route, route)) continue;
813
+ if (!configWindowCurrent(source.config)) continue;
781
814
  let provider = source.url || source.api;
782
815
  if (!provider) continue;
783
816
  providers.push(provider);