UNPKG

faastjs

Version:

Serverless batch computing made simple.

170 lines 52.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.filterMessages = exports.FunctionExecutionMetrics = exports.FunctionStats = exports.CleanupOptionDefaults = exports.commonDefaults = void 0; const shared_1 = require("./shared"); exports.commonDefaults = { childProcess: true, childProcessMemoryMb: 0, concurrency: 100, description: "", exclude: [], include: [], rate: 0, env: {}, gc: "auto", maxRetries: 2, memorySize: 1024, mode: "auto", packageJson: "", useDependencyCaching: true, retentionInDays: 1, speculativeRetryThreshold: 3, timeout: 60, webpackOptions: {}, validateSerialization: true, debugOptions: {} }; exports.CleanupOptionDefaults = { deleteResources: true, deleteCaches: false, gcTimeout: 10 }; /** * Summary statistics for function invocations. * @remarks * ``` * localStartLatency remoteStartLatency executionTime * ◀──────────────────▶◁ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▷◀──────────▶ * * ┌───────────────────────────────────┬──────────────────────────────────────┐ * │ │ │ * │ Local │ Cloud Provider │ * │ │ │ * │ ┌─────────┐ │ ┌──────────┐ ┌──────────┐ │ * │ │ │ │ │ │ │ │ │ * │ │ local │ │ │ request │ │ │ │ * │ invoke ────────▶│ queue │────┼──▶│ queue ├────────▶│ │ │ * │ │ │ │ │ │ │ │ │ * │ └─────────┘ │ └──────────┘ │ cloud │ │ * │ │ │ function │ │ * │ ┌─────────┐ │ ┌──────────┐ │ │ │ * │ │ │ │ │ │ │ │ │ * │ result ◀────────│ local │◀───┼───│ response │◀────────│ │ │ * │ │ polling │ │ │ queue │ │ │ │ * │ │ │ │ │ │ │ │ │ * │ └─────────┘ │ └──────────┘ └──────────┘ │ * │ │ │ * └───────────────────────────────────┴──────────────────────────────────────┘ * * ◁ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▷ * returnLatency ◀───────▶ * sendResponseLatency * ``` * * `localStartLatency` and `executionTime` are measured on one machine and are * free of clock skew. `remoteStartLatency` and `returnLatency` are measured as * time differences between machines and are subject to much more uncertainty, * and effects like clock skew. * * All times are in milliseconds. * * @public */ class FunctionStats { constructor() { /** * Statistics for how long invocations stay in the local queue before being * sent to the cloud provider. */ this.localStartLatency = new shared_1.Statistics(); /** * Statistics for how long requests take to start execution after being sent * to the cloud provider. This typically includes remote queueing and cold * start times. Because this measurement requires comparing timestamps from * different machines, it is subject to clock skew and other effects, and * should not be considered highly accurate. It can be useful for detecting * excessively high latency problems. Faast.js attempt to correct for clock * skew heuristically. */ this.remoteStartLatency = new shared_1.Statistics(); /** * Statistics for function execution time in milliseconds. This is measured * as wall clock time inside the cloud function, and does not include the * time taken to send the response to the response queue. Note that most * cloud providers round up to the next 100ms for pricing. */ this.executionTime = new shared_1.Statistics(); /** * Statistics for how long it takes to send the response to the response * queue. */ this.sendResponseLatency = new shared_1.Statistics(); /** * Statistics for how long it takes to return a response from the end of * execution time to the receipt of the response locally. This measurement * requires comparing timestamps from different machines, and is subject to * clock skew and other effects. It should not be considered highly * accurate. It can be useful for detecting excessively high latency * problems. Faast.js attempts to correct for clock skew heuristically. */ this.returnLatency = new shared_1.Statistics(); /** * Statistics for amount of time billed. This is similar to * {@link FunctionStats.executionTime} except each sampled time is rounded * up to the next 100ms. */ this.estimatedBilledTime = new shared_1.Statistics(); /** * The number of invocations attempted. If an invocation is retried, this * only counts the invocation once. */ this.invocations = 0; /** * The number of invocations that were successfully completed. */ this.completed = 0; /** * The number of invocation retries attempted. This counts retries * attempted by faast.js to recover from transient errors, but does not * count retries by the cloud provider. */ this.retries = 0; /** * The number of invocations that resulted in an error. If an invocation is * retried, an error is only counted once, no matter how many retries were * attempted. */ this.errors = 0; } /** * Summarize the function stats as a string. * @returns a string showing the value of completed, retries, errors, and * mean execution time. This string excludes invocations by default because * it is often fixed. */ toString() { return `completed: ${this.completed}, retries: ${this.retries}, errors: ${this.errors}, executionTime.mean: ${this.executionTime.mean}ms`; } /** @internal */ clone() { const rv = Object.assign(Object.create(Object.getPrototypeOf(this)), this); for (const key of (0, shared_1.keysOf)(rv)) { if (typeof rv[key] !== "number") { rv[key] = rv[key].clone(); } } return rv; } } exports.FunctionStats = FunctionStats; class FunctionExecutionMetrics { constructor() { this.secondMetrics = []; } } exports.FunctionExecutionMetrics = FunctionExecutionMetrics; function filterMessages(messages, kind) { return messages.filter((msg) => msg.kind === kind); } exports.filterMessages = filterMessages; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEscUNBQThDO0FBK1pqQyxRQUFBLGNBQWMsR0FBNEI7SUFDbkQsWUFBWSxFQUFFLElBQUk7SUFDbEIsb0JBQW9CLEVBQUUsQ0FBQztJQUN2QixXQUFXLEVBQUUsR0FBRztJQUNoQixXQUFXLEVBQUUsRUFBRTtJQUNmLE9BQU8sRUFBRSxFQUFFO0lBQ1gsT0FBTyxFQUFFLEVBQUU7SUFDWCxJQUFJLEVBQUUsQ0FBQztJQUNQLEdBQUcsRUFBRSxFQUFFO0lBQ1AsRUFBRSxFQUFFLE1BQU07SUFDVixVQUFVLEVBQUUsQ0FBQztJQUNiLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLElBQUksRUFBRSxNQUFNO0lBQ1osV0FBVyxFQUFFLEVBQUU7SUFDZixvQkFBb0IsRUFBRSxJQUFJO0lBQzFCLGVBQWUsRUFBRSxDQUFDO0lBQ2xCLHlCQUF5QixFQUFFLENBQUM7SUFDNUIsT0FBTyxFQUFFLEVBQUU7SUFDWCxjQUFjLEVBQUUsRUFBRTtJQUNsQixxQkFBcUIsRUFBRSxJQUFJO0lBQzNCLFlBQVksRUFBRSxFQUFFO0NBQ25CLENBQUM7QUFnRFcsUUFBQSxxQkFBcUIsR0FBNkI7SUFDM0QsZUFBZSxFQUFFLElBQUk7SUFDckIsWUFBWSxFQUFFLEtBQUs7SUFDbkIsU0FBUyxFQUFFLEVBQUU7Q0FDaEIsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0NHO0FBQ0gsTUFBYSxhQUFhO0lBQTFCO1FBQ0k7OztXQUdHO1FBQ0gsc0JBQWlCLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDckM7Ozs7Ozs7O1dBUUc7UUFDSCx1QkFBa0IsR0FBRyxJQUFJLG1CQUFVLEVBQUUsQ0FBQztRQUN0Qzs7Ozs7V0FLRztRQUNILGtCQUFhLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDakM7OztXQUdHO1FBQ0gsd0JBQW1CLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDdkM7Ozs7Ozs7V0FPRztRQUNILGtCQUFhLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDakM7Ozs7V0FJRztRQUNILHdCQUFtQixHQUFHLElBQUksbUJBQVUsRUFBRSxDQUFDO1FBQ3ZDOzs7V0FHRztRQUNILGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCOztXQUVHO1FBQ0gsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkOzs7O1dBSUc7UUFDSCxZQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ1o7Ozs7V0FJRztRQUNILFdBQU0sR0FBRyxDQUFDLENBQUM7SUFvQmYsQ0FBQztJQW5CRzs7Ozs7T0FLRztJQUNILFFBQVE7UUFDSixPQUFPLGNBQWMsSUFBSSxDQUFDLFNBQVMsY0FBYyxJQUFJLENBQUMsT0FBTyxhQUFhLElBQUksQ0FBQyxNQUFNLHlCQUF5QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxDQUFDO0lBQzlJLENBQUM7SUFDRCxnQkFBZ0I7SUFDaEIsS0FBSztRQUNELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0UsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFBLGVBQU0sRUFBQyxFQUFFLENBQUMsRUFBRTtZQUMxQixJQUFJLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsRUFBRTtnQkFDN0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUM3QjtTQUNKO1FBQ0QsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0NBQ0o7QUFuRkQsc0NBbUZDO0FBRUQsTUFBYSx3QkFBd0I7SUFBckM7UUFDSSxrQkFBYSxHQUFpQixFQUFFLENBQUM7SUFDckMsQ0FBQztDQUFBO0FBRkQsNERBRUM7QUFvREQsU0FBZ0IsY0FBYyxDQUFpQixRQUFtQixFQUFFLElBQU87SUFDdkUsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUNsQixDQUFDLEdBQVksRUFBd0MsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUM1RSxDQUFDO0FBQ04sQ0FBQztBQUpELHdDQUlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHdlYnBhY2sgZnJvbSBcIndlYnBhY2tcIjtcbmltcG9ydCB7IENvc3RTbmFwc2hvdCB9IGZyb20gXCIuL2Nvc3RcIjtcbmltcG9ydCB7IGtleXNPZiwgU3RhdGlzdGljcyB9IGZyb20gXCIuL3NoYXJlZFwiO1xuaW1wb3J0IHsgQ3B1TWVhc3VyZW1lbnQsIEZ1bmN0aW9uQ2FsbCB9IGZyb20gXCIuL3dyYXBwZXJcIjtcblxuLyoqXG4gKiBUaGUgdHlwZSBvZiBhbGwgc3VwcG9ydGVkIGNsb3VkIHByb3ZpZGVycy5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IHR5cGUgUHJvdmlkZXIgPSBcImF3c1wiIHwgXCJsb2NhbFwiO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSB7QGxpbmsgQ29tbW9uT3B0aW9ucy5pbmNsdWRlfSBvcHRpb24uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5jbHVkZU9wdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSBvciBnbG9iIHRvIGFkZCB0byB0aGUgY2xvdWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgcGF0aDogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFRoZSB3b3JraW5nIGRpcmVjdG9yeSBpZiBgcGF0aGAgaXMgcmVsYXRpdmUuIERlZmF1bHRzIHRvIGBwcm9jZXNzLmN3ZCgpYC5cbiAgICAgKiBGb3IgZXhhbXBsZSwgaWYgYGN3ZGAgaXMgYFwiZm9vXCJgIGFuZCBgcGF0aGAgaXMgYFwiYmFyXCJgLCB0aGVuIHRoZVxuICAgICAqIGNvbnRlbnRzIG9mIHRoZSBkaXJlY3RvcnkgYGZvby9iYXIvYCB3aWxsIGJlIGFkZGVkIHRvIHRoZSByZW1vdGVcbiAgICAgKiBmdW5jdGlvbiB1bmRlciB0aGUgcGF0aCBgYmFyL2AuXG4gICAgICovXG4gICAgY3dkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgY29tbW9uIGFjcm9zcyBhbGwgZmFhc3QuanMgcHJvdmlkZXJzLiBVc2VkIGFzIGFyZ3VtZW50IHRvIHtAbGluayBmYWFzdH0uXG4gKiBAcmVtYXJrc1xuICogVGhlcmUgYXJlIGFsc28gbW9yZSBzcGVjaWZpYyBvcHRpb25zIGZvciBlYWNoIHByb3ZpZGVyLiBTZWVcbiAqIHtAbGluayBBd3NPcHRpb25zfSBhbmQge0BsaW5rIExvY2FsT3B0aW9uc30uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tbW9uT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogSWYgdHJ1ZSwgY3JlYXRlIGEgY2hpbGQgcHJvY2VzcyB0byBpc29sYXRlIHVzZXIgY29kZSBmcm9tIGZhYXN0XG4gICAgICogc2NhZmZvbGRpbmcuIERlZmF1bHQ6IHRydWUuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBJZiBhIGNoaWxkIHByb2Nlc3MgaXMgbm90IGNyZWF0ZWQsIGZhYXN0IHJ1bnMgaW4gdGhlIHNhbWUgbm9kZSBpbnN0YW5jZVxuICAgICAqIGFzIHRoZSB1c2VyIGNvZGUgYW5kIG1heSBub3QgZXhlY3V0ZSBpbiBhIHRpbWVseSBmYXNoaW9uIGJlY2F1c2UgdXNlclxuICAgICAqIGNvZGUgbWF5XG4gICAgICoge0BsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9lbi9kb2NzL2d1aWRlcy9kb250LWJsb2NrLXRoZS1ldmVudC1sb29wLyB8IGJsb2NrIHRoZSBldmVudCBsb29wfS5cbiAgICAgKiBDcmVhdGluZyBhIGNoaWxkIHByb2Nlc3MgZm9yIHVzZXIgY29kZSBhbGxvd3MgZmFhc3QuanMgdG8gY29udGludWVcbiAgICAgKiBleGVjdXRpbmcgZXZlbiBpZiB1c2VyIGNvZGUgbmV2ZXIgeWllbGRzLiBUaGlzIHByb3ZpZGVzIGJldHRlclxuICAgICAqIHJlbGlhYmlsaXR5IGFuZCBmdW5jdGlvbmFsaXR5OlxuICAgICAqXG4gICAgICogLSBEZXRlY3QgdGltZW91dCBlcnJvcnMgbW9yZSByZWxpYWJseSwgZXZlbiBpZiB0aGUgZnVuY3Rpb24gZG9lc24ndFxuICAgICAqICAgcmVsaW5xdWlzaCB0aGUgQ1BVLiBOb3QgYXBwbGljYWJsZSB0byBBV1MsIHdoaWNoIHNlbmRzIHNlcGFyYXRlIGZhaWx1cmVcbiAgICAgKiAgIG1lc3NhZ2VzIGluIGNhc2Ugb2YgdGltZW91dC4gU2VlIHtAbGluayBDb21tb25PcHRpb25zLnRpbWVvdXR9LlxuICAgICAqXG4gICAgICogLSBDUFUgbWV0cmljcyB1c2VkIGZvciBkZXRlY3RpbmcgaW52b2NhdGlvbnMgd2l0aCBoaWdoIGxhdGVuY3ksIHdoaWNoIGNhblxuICAgICAqICAgYmUgdXNlZCBmb3IgYXV0b21hdGljYWxseSByZXRyeWluZyBjYWxscyB0byByZWR1Y2UgdGFpbCBsYXRlbmN5LlxuICAgICAqXG4gICAgICogVGhlIGNvc3Qgb2YgY3JlYXRpbmcgYSBjaGlsZCBwcm9jZXNzIGlzIG1haW5seSBpbiB0aGUgbWVtb3J5IG92ZXJoZWFkIG9mXG4gICAgICogY3JlYXRpbmcgYW5vdGhlciBub2RlIHByb2Nlc3MuXG4gICAgICovXG4gICAgY2hpbGRQcm9jZXNzPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZW4gY2hpbGRQcm9jZXNzIGlzIHRydWUsIHRoZSBjaGlsZCBwcm9jZXNzIHdpbGwgYmUgc3Bhd25lZCB3aXRoIHRoZVxuICAgICAqIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgYXMgdGhlIHNldHRpbmcgZm9yIC0tbWF4LW9sZC1zcGFjZS1zaXplLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogVGhpcyBpcyB1c2VmdWwgaWYgYSBmdW5jdGlvbiByZXF1aXJlcyB0aGUgbm9kZSBwcm9jZXNzIHRvIGxpbWl0IGl0c1xuICAgICAqIG1lbW9yeSBzbyB0aGF0IGFub3RoZXIgc3Bhd25lZCBwcm9jZXNzIChlLmcuIGEgYnJvd3NlciBpbnN0YW5jZSkgY2FuIHVzZVxuICAgICAqIHRoZSByZXN0LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKi9cbiAgICBjaGlsZFByb2Nlc3NNZW1vcnlNYj86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgY29uY3VycmVudCBpbnZvY2F0aW9ucyB0byBhbGxvdy4gRGVmYXVsdDogMTAwLFxuICAgICAqIGV4Y2VwdCBmb3IgdGhlIGBsb2NhbGAgcHJvdmlkZXIsIHdoZXJlIHRoZSBkZWZhdWx0IGlzIDEwLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogVGhlIGNvbmN1cnJlbmN5IGxpbWl0IGFwcGxpZXMgdG8gYWxsIGludm9jYXRpb25zIG9mIGFsbCBvZiB0aGUgZmFhc3RcbiAgICAgKiBmdW5jdGlvbnMgc3VtbWVkIHRvZ2V0aGVyLiBJdCBpcyBub3QgYSBwZXItZnVuY3Rpb24gbGltaXQuIFRvIGFwcGx5IGFcbiAgICAgKiBwZXItZnVuY3Rpb24gbGltaXQsIHVzZSB7QGxpbmsgdGhyb3R0bGV9LiBBIHZhbHVlIG9mIDAgaXMgZXF1aXZhbGVudCB0b1xuICAgICAqIEluZmluaXR5LiBBIHZhbHVlIG9mIDEgZW5zdXJlcyBtdXR1YWxseSBleGNsdXNpdmUgaW52b2NhdGlvbnMuXG4gICAgICovXG4gICAgY29uY3VycmVuY3k/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogQSB1c2VyLXN1cHBsaWVkIGRlc2NyaXB0aW9uIGZvciB0aGlzIGZ1bmN0aW9uLCB3aGljaCBtYXkgbWFrZSBpdCBlYXNpZXJcbiAgICAgKiB0byB0cmFjayBkaWZmZXJlbnQgZnVuY3Rpb25zIHdoZW4gbXVsdGlwbGUgZnVuY3Rpb25zIGFyZSBjcmVhdGVkLlxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEV4Y2x1ZGUgYSBzdWJzZXQgb2YgZmlsZXMgaW5jbHVkZWQgYnkge0BsaW5rIENvbW1vbk9wdGlvbnMuaW5jbHVkZX0uXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBUaGUgZXhjbHVzaW9uIGNhbiBiZSBhIGRpcmVjdG9yeSBvciBnbG9iLiBFeGNsdXNpb25zIGFwcGx5IHRvIGFsbCBpbmNsdWRlZFxuICAgICAqIGVudHJpZXMuXG4gICAgICovXG4gICAgZXhjbHVkZT86IHN0cmluZ1tdO1xuICAgIC8qKlxuICAgICAqIFJhdGUgbGltaXQgaW52b2NhdGlvbnMgKGludm9jYXRpb25zL3NlYykuIERlZmF1bHQ6IG5vIHJhdGUgbGltaXQuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBTb21lIHNlcnZpY2VzIGNhbm5vdCBoYW5kbGUgbW9yZSB0aGFuIGEgY2VydGFpbiBudW1iZXIgb2YgcmVxdWVzdHMgcGVyXG4gICAgICogc2Vjb25kLCBhbmQgaXQgaXMgZWFzeSB0byBvdmVyd2hlbG0gdGhlbSB3aXRoIGEgbGFyZ2UgbnVtYmVyIG9mIGNsb3VkXG4gICAgICogZnVuY3Rpb25zLiBTcGVjaWZ5IGEgcmF0ZSBsaW1pdCBpbiBpbnZvY2F0aW9uL3NlY29uZCB0byByZXN0cmljdCBob3dcbiAgICAgKiBmYWFzdC5qcyBpc3N1ZXMgcmVxdWVzdHMuXG4gICAgICovXG4gICAgcmF0ZT86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgYXZhaWxhYmxlIGR1cmluZyBzZXJ2ZXJsZXNzIGZ1bmN0aW9uIGV4ZWN1dGlvbi5cbiAgICAgKiBEZWZhdWx0OiBcXHtcXH0uXG4gICAgICovXG4gICAgZW52PzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcbiAgICAvKipcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3RvciBtb2RlLiBEZWZhdWx0OiBgXCJhdXRvXCJgLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogR2FyYmFnZSBjb2xsZWN0aW9uIGRlbGV0ZXMgcmVzb3VyY2VzIHRoYXQgd2VyZSBjcmVhdGVkIGJ5IHByZXZpb3VzXG4gICAgICogaW5zdGFudGlhdGlvbnMgb2YgZmFhc3QgdGhhdCB3ZXJlIG5vdCBjbGVhbmVkIHVwIGJ5XG4gICAgICoge0BsaW5rIEZhYXN0TW9kdWxlLmNsZWFudXB9LCBlaXRoZXIgYmVjYXVzZSBpdCB3YXMgbm90IGNhbGxlZCBvciBiZWNhdXNlXG4gICAgICogdGhlIHByb2Nlc3MgdGVybWluYXRlZCBhbmQgZGlkIG5vdCBleGVjdXRlIHRoaXMgY2xlYW51cCBzdGVwLiBJbiBgXCJhdXRvXCJgXG4gICAgICogbW9kZSwgZ2FyYmFnZSBjb2xsZWN0aW9uIG1heSBiZSB0aHJvdHRsZWQgdG8gcnVuIHVwIHRvIG9uY2UgcGVyIGhvdXIgbm9cbiAgICAgKiBtYXR0ZXIgaG93IG1hbnkgZmFhc3QuanMgaW5zdGFuY2VzIGFyZSBjcmVhdGVkLiBJbiBgXCJmb3JjZVwiYCBtb2RlLFxuICAgICAqIGdhcmJhZ2UgY29sbGVjdGlvbiBpcyBydW4gd2l0aG91dCByZWdhcmQgdG8gd2hldGhlciBhbm90aGVyIGdjIGhhc1xuICAgICAqIGFscmVhZHkgYmVlbiBwZXJmb3JtZWQgcmVjZW50bHkuIEluIGBcIm9mZlwiYCBtb2RlLCBnYXJiYWdlIGNvbGxlY3Rpb24gaXNcbiAgICAgKiBza2lwcGVkIGVudGlyZWx5LiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBlcmZvcm1hbmNlLXNlbnNpdGl2ZSB0ZXN0cywgb3JcbiAgICAgKiBmb3IgbW9yZSBjb250cm9sIG92ZXIgd2hlbiBnYyBpcyBwZXJmb3JtZWQuXG4gICAgICpcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3Rpb24gaXMgY2xvdWQtc3BlY2lmaWMsIGJ1dCBpbiBnZW5lcmFsIGdhcmJhZ2UgY29sbGVjdGlvblxuICAgICAqIHNob3VsZCBub3QgaW50ZXJmZXJlIHdpdGggdGhlIGJlaGF2aW9yIG9yIHBlcmZvcm1hbmNlIG9mIGZhYXN0IGNsb3VkXG4gICAgICogZnVuY3Rpb25zLiBXaGVuIHtAbGluayBGYWFzdE1vZHVsZS5jbGVhbnVwfSBydW5zLCBpdCB3YWl0cyBmb3IgZ2FyYmFnZVxuICAgICAqIGNvbGxlY3Rpb24gdG8gY29tcGxldGUuIFRoZXJlZm9yZSB0aGUgY2xlYW51cCBzdGVwIGNhbiBpbiBzb21lXG4gICAgICogY2lyY3Vtc3RhbmNlcyB0YWtlIGEgc2lnbmlmaWNhbnQgYW1vdW50IG9mIHRpbWUgZXZlbiBhZnRlciBhbGxcbiAgICAgKiBpbnZvY2F0aW9ucyBoYXZlIHJldHVybmVkLlxuICAgICAqXG4gICAgICogSXQgaXMgZ2VuZXJhbGx5IHJlY29tbWVuZGVkIHRvIGxlYXZlIGdhcmJhZ2UgY29sbGVjdGlvbiBpbiBgXCJhdXRvXCJgIG1vZGUsXG4gICAgICogb3RoZXJ3aXNlIGdhcmJhZ2UgcmVzb3VyY2VzIG1heSBhY2N1bXVsYXRlIG92ZXIgdGltZSBhbmQgeW91IHdpbGxcbiAgICAgKiBldmVudHVhbGx5IGhpdCByZXNvdXJjZSBsaW1pdHMgb24geW91ciBhY2NvdW50LlxuICAgICAqXG4gICAgICogQWxzbyBzZWUge0BsaW5rIENvbW1vbk9wdGlvbnMucmV0ZW50aW9uSW5EYXlzfS5cbiAgICAgKi9cbiAgICBnYz86IFwiYXV0b1wiIHwgXCJmb3JjZVwiIHwgXCJvZmZcIjtcbiAgICAvKipcbiAgICAgKiBJbmNsdWRlIGZpbGVzIHRvIG1ha2UgYXZhaWxhYmxlIGluIHRoZSByZW1vdGUgZnVuY3Rpb24uIFNlZVxuICAgICAqIHtAbGluayBJbmNsdWRlT3B0aW9ufS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEVhY2ggaW5jbHVkZSBlbnRyeSBpcyBhIGRpcmVjdG9yeSBvciBnbG9iIHBhdHRlcm4uIFBhdGhzIGNhbiBiZSBzcGVjaWZpZWRcbiAgICAgKiBhcyByZWxhdGl2ZSBvciBhYnNvbHV0ZSBwYXRocy4gUmVsYXRpdmUgcGF0aHMgYXJlIHJlc29sdmVkIHJlbGF0aXZlIHRvXG4gICAgICogdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnksIG9yIHJlbGF0aXZlIHRvIHRoZSBgY3dkYCBvcHRpb24uXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaW5jbHVkZSBlbnRyeSBpcyBhIGRpcmVjdG9yeSBgXCJmb28vYmFyXCJgLCB0aGUgZGlyZWN0b3J5XG4gICAgICogYFwiLi9mb28vYmFyXCJgIHdpbGwgYmUgYXZhaWxhYmxlIGluIHRoZSBjbG91ZCBmdW5jdGlvbi4gRGlyZWN0b3JpZXMgYXJlXG4gICAgICogcmVjdXJzaXZlbHkgYWRkZWQuXG4gICAgICpcbiAgICAgKiBHbG9iIHBhdHRlcm5zIHVzZSB0aGUgc3ludGF4IG9mXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3Mvbm9kZS1nbG9iIHwgbm9kZSBnbG9ifS5cbiAgICAgKlxuICAgICAqIEFsc28gc2VlIHtAbGluayBDb21tb25PcHRpb25zLmV4Y2x1ZGV9IGZvciBmaWxlIGV4Y2x1c2lvbnMuXG4gICAgICovXG4gICAgaW5jbHVkZT86IChzdHJpbmcgfCBJbmNsdWRlT3B0aW9uKVtdO1xuICAgIC8qKlxuICAgICAqIE1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoYXQgZmFhc3Qgd2lsbCByZXRyeSBlYWNoIGludm9jYXRpb24uIERlZmF1bHQ6IDJcbiAgICAgKiAoaW52b2NhdGlvbnMgY2FuIHRoZXJlZm9yZSBiZSBhdHRlbXBlZCAzIHRpbWVzIGluIHRvdGFsKS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFJldHJpZXMgYXJlIGF1dG9tYXRpY2FsbHkgYXR0ZW1wdGVkIGZvciB0cmFuc2llbnQgaW5mcmFzdHJ1Y3R1cmUtbGV2ZWxcbiAgICAgKiBmYWlsdXJlcyBzdWNoIGFzIHJhdGUgbGltaXRzIG9yIG5ldG93cmsgZmFpbHVyZXMuIFVzZXItbGV2ZWwgZXhjZXB0aW9uc1xuICAgICAqIGFyZSBub3QgcmV0cmllZCBhdXRvbWF0aWNhbGx5LiBJbiBhZGRpdGlvbiB0byByZXRyaWVzIHBlcmZvcm1lZCBieSBmYWFzdCxcbiAgICAgKiBzb21lIHByb3ZpZGVycyBhdXRvbWF0aWNhbGx5IGF0dGVtcHQgcmV0cmllcy4gVGhlc2UgYXJlIG5vdCBjb250cm9sbGFibGVcbiAgICAgKiBieSBmYWFzdC4gQnV0IGFzIGEgcmVzdWx0LCB5b3VyIGZ1bmN0aW9uIG1heSBiZSByZXRyaWVkIG1hbnkgbW9yZSB0aW1lc1xuICAgICAqIHRoYW4gdGhpcyBzZXR0aW5nIHN1Z2dlc3RzLlxuICAgICAqL1xuICAgIG1heFJldHJpZXM/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogTWVtb3J5IGxpbWl0IGZvciBlYWNoIGZ1bmN0aW9uIGluIE1CLiBUaGlzIHNldHRpbmcgaGFzIGFuIGVmZmVjdCBvblxuICAgICAqIHByaWNpbmcuIERlZmF1bHQgdmFyaWVzIGJ5IHByb3ZpZGVyLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogRWFjaCBwcm92aWRlciBoYXMgZGlmZmVyZW50IHNldHRpbmdzIGZvciBtZW1vcnkgc2l6ZSwgYW5kIHBlcmZvcm1hbmNlXG4gICAgICogdmFyaWVzIGRlcGVuZGluZyBvbiB0aGUgc2V0dGluZy4gQnkgZGVmYXVsdCBmYWFzdCBwaWNrcyBhIGxpa2VseSBvcHRpbWFsXG4gICAgICogdmFsdWUgZm9yIGVhY2ggcHJvdmlkZXIuXG4gICAgICpcbiAgICAgKiAtIGF3czogMTcyOE1CXG4gICAgICpcbiAgICAgKiAtIGxvY2FsOiA1MTJNQiAoaG93ZXZlciwgbWVtb3J5IHNpemUgbGltaXRzIGFyZW4ndCByZWxpYWJsZSBpbiBsb2NhbCBtb2RlLilcbiAgICAgKi9cbiAgICBtZW1vcnlTaXplPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgaW52b2NhdGlvbiBtb2RlLiBEZWZhdWx0OiBgXCJhdXRvXCJgLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogTW9kZXMgc3BlY2lmeSBob3cgaW52b2NhdGlvbnMgYXJlIHRyaWdnZXJlZC4gSW4gaHR0cHMgbW9kZSwgdGhlIGZ1bmN0aW9uc1xuICAgICAqIGFyZSBpbnZva2VkIHRocm91Z2ggYW4gaHR0cHMgcmVxdWVzdCBvciB0aGUgcHJvdmlkZXIncyBBUEkuIEluIHF1ZXVlXG4gICAgICogbW9kZSwgYSBwcm92aWRlci1zcGVjaWZpYyBxdWV1ZSBpcyB1c2VkIHRvIGludm9rZSBmdW5jdGlvbnMuIFF1ZXVlIG1vZGVcbiAgICAgKiBhZGRzIGFkZGl0aW9uYWwgbGF0ZW5jeSBhbmQgKHVzdWFsbHkgbmVnbGlnaWJsZSkgY29zdCwgYnV0IG1heSBzY2FsZVxuICAgICAqIGJldHRlciBmb3Igc29tZSBwcm92aWRlcnMuIEluIGF1dG8gbW9kZSB0aGUgYmVzdCBkZWZhdWx0IGlzIGNob3NlbiBmb3JcbiAgICAgKiBlYWNoIHByb3ZpZGVyIGRlcGVuZGluZyBvbiBpdHMgcGFydGljdWxhciBwZXJmb3JtYW5jZSBjaGFyYWN0ZXJpc3RpY3MuXG4gICAgICpcbiAgICAgKiBUaGUgZGVmYXVsdHMgYXJlOlxuICAgICAqXG4gICAgICogLSBhd3M6IGBcImF1dG9cImAgaXMgYFwiaHR0cHNcImAuIEluIGh0dHBzIG1vZGUsIHRoZSBBV1MgU0RLIGFwaVxuICAgICAqICAgaXMgdXNlZCB0byBpbnZva2UgZnVuY3Rpb25zLiBJbiBxdWV1ZSBtb2RlLCBhbiBBV1MgU05TIHRvcGljIGlzIGNyZWF0ZWRcbiAgICAgKiAgIGFuZCB0cmlnZ2VycyBpbnZvY2F0aW9ucy4gVGhlIEFXUyBBUEkgR2F0ZXdheSBzZXJ2aWNlIGlzIG5ldmVyIHVzZWQgYnlcbiAgICAgKiAgIGZhYXN0LCBhcyBpdCBpbmN1cnMgYSBoaWdoZXIgY29zdCBhbmQgaXMgbm90IG5lZWRlZCB0byB0cmlnZ2VyXG4gICAgICogICBpbnZvY2F0aW9ucy5cbiAgICAgKlxuICAgICAqIC0gbG9jYWw6IFRoZSBsb2NhbCBwcm92aWRlciBpZ25vcmVzIHRoZSBtb2RlIHNldHRpbmcgYW5kIGFsd2F5cyB1c2VzIGFuXG4gICAgICogICBpbnRlcm5hbCBhc3luY2hyb25vdXMgcXVldWUgdG8gc2NoZWR1bGUgY2FsbHMuXG4gICAgICpcbiAgICAgKiBTaXplIGxpbWl0cyBhcmUgYWZmZWN0ZWQgYnkgdGhlIGNob2ljZSBvZiBtb2RlLiBPbiBBV1MgdGhlIGxpbWl0IGlzIDI1NmtiXG4gICAgICogZm9yIGFyZ3VtZW50cyBhbmQgcmV0dXJuIHZhbHVlcyBpbiBgXCJxdWV1ZVwiYCBtb2RlLCBhbmQgNk1CIGZvciBgXCJodHRwc1wiYFxuICAgICAqIG1vZGUuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoYXQgbm8gbWF0dGVyIHdoaWNoIG1vZGUgaXMgc2VsZWN0ZWQsIGZhYXN0LmpzIGFsd2F5cyBjcmVhdGVzIGFcbiAgICAgKiBxdWV1ZSBmb3Igc2VuZGluZyBiYWNrIGludGVybWVkaWF0ZSByZXN1bHRzIGZvciBib29rZWVwaW5nIGFuZFxuICAgICAqIHBlcmZvcm1hbmNlIG1vbml0b3JpbmcuXG4gICAgICovXG4gICAgbW9kZT86IFwiaHR0cHNcIiB8IFwicXVldWVcIiB8IFwiYXV0b1wiO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgYSBwYWNrYWdlLmpzb24gZmlsZSB0byBpbmNsdWRlIHdpdGggdGhlIGNvZGUgcGFja2FnZS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEJ5IGRlZmF1bHQsIGZhYXN0LmpzIHdpbGwgdXNlIHdlYnBhY2sgdG8gYnVuZGxlIGRlcGVuZGVuY2llcyB5b3VyIHJlbW90ZVxuICAgICAqIG1vZHVsZSBpbXBvcnRzLiBJbiBub3JtYWwgdXNhZ2UgdGhlcmUgaXMgbm8gbmVlZCB0byBzcGVjaWZ5IGEgc2VwYXJhdGVcbiAgICAgKiBwYWNrYWdlLmpzb24sIGFzIHdlYnBhY2sgd2lsbCBzdGF0aWNhbGx5IGFuYWx5emUgeW91ciBpbXBvcnRzIGFuZFxuICAgICAqIGRldGVybWluZSB3aGljaCBmaWxlcyB0byBidW5kbGUuXG4gICAgICpcbiAgICAgKiBIb3dldmVyLCB0aGVyZSBhcmUgc29tZSB1c2UgY2FzZXMgd2hlcmUgdGhpcyBpcyBub3QgZW5vdWdoLiBGb3IgZXhhbXBsZSxcbiAgICAgKiBzb21lIGRlcGVuZGVuY2llcyBjb250YWluIG5hdGl2ZSBjb2RlIGNvbXBpbGVkIGR1cmluZyBpbnN0YWxsYXRpb24sIGFuZFxuICAgICAqIHdlYnBhY2sgY2Fubm90IGJ1bmRsZSB0aGVzZSBuYXRpdmUgbW9kdWxlcy4gc3VjaCBhcyBkZXBlbmRlbmNpZXMgd2l0aFxuICAgICAqIG5hdGl2ZSBjb2RlLiAgb3IgYXJlIHNwZWNpZmljYWxseSBub3QgZGVzaWduZWQgdG8gd29yayB3aXRoIHdlYnBhY2suIEluXG4gICAgICogdGhlc2UgY2FzZXMsIHlvdSBjYW4gY3JlYXRlIGEgc2VwYXJhdGUgYHBhY2thZ2UuanNvbmAgZm9yIHRoZXNlXG4gICAgICogZGVwZW5kZW5jaWVzIGFuZCBwYXNzIHRoZSBmaWxlbmFtZSBhcyB0aGUgYHBhY2thZ2VKc29uYCBvcHRpb24uIElmXG4gICAgICogYHBhY2thZ2VKc29uYCBpcyBhbiBgb2JqZWN0YCwgaXQgaXMgYXNzdW1lZCB0byBiZSBhIHBhcnNlZCBKU09OIG9iamVjdFxuICAgICAqIHdpdGggdGhlIHNhbWUgc3RydWN0dXJlIGFzIGEgcGFja2FnZS5qc29uIGZpbGUgKHVzZWZ1bCBmb3Igc3BlY2lmeWluZyBhXG4gICAgICogc3ludGhldGljIGBwYWNrYWdlLmpzb25gIGRpcmVjdGx5IGluIGNvZGUpLlxuICAgICAqXG4gICAgICogVGhlIHdheSB0aGUgYHBhY2thZ2VKc29uYCBpcyBoYW5kbGVkIHZhcmllcyBieSBwcm92aWRlcjpcbiAgICAgKlxuICAgICAqIC0gbG9jYWw6IFJ1bnMgYG5wbSBpbnN0YWxsYCBpbiBhIHRlbXBvcmFyeSBkaXJlY3RvcnkgaXQgcHJlcGFyZXMgZm9yIHRoZVxuICAgICAqICAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAtIGF3czogUmVjdXJzaXZlbHkgY2FsbHMgZmFhc3QuanMgdG8gcnVuIGBucG0gaW5zdGFsbGAgaW5zaWRlIGEgc2VwYXJhdGVcbiAgICAgKiAgIGxhbWJkYSBmdW5jdGlvbiBzcGVjaWZpY2FsbHkgY3JlYXRlZCBmb3IgdGhpcyBwdXJwb3NlLiBGYWFzdC5qcyB1c2VzXG4gICAgICogICBsYW1iZGEgdG8gaW5zdGFsbCBkZXBlbmRlbmNpZXMgdG8gZW5zdXJlIHRoYXQgbmF0aXZlIGRlcGVuZGVuY2llcyBhcmVcbiAgICAgKiAgIGNvbXBpbGVkIGluIGFuIGVudmlyb25tZW50IHRoYXQgY2FuIHByb2R1Y2UgYmluYXJpZXMgbGlua2VkIGFnYWluc3RcbiAgICAgKiAgIGxhbWJkYSdzXG4gICAgICogICB7QGxpbmsgaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9ibG9ncy9jb21wdXRlL3J1bm5pbmctZXhlY3V0YWJsZXMtaW4tYXdzLWxhbWJkYS8gfCBleGVjdXRpb24gZW52aXJvbm1lbnR9LlxuICAgICAqICAgUGFja2FnZXMgYXJlIHNhdmVkIGluIGEgTGFtYmRhIExheWVyLlxuICAgICAqXG4gICAgICogRm9yIEFXUywgaWYge0BsaW5rIENvbW1vbk9wdGlvbnMudXNlRGVwZW5kZW5jeUNhY2hpbmd9IGlzIGB0cnVlYCAod2hpY2hcbiAgICAgKiBpcyB0aGUgZGVmYXVsdCksIHRoZW4gdGhlIExhbWJkYSBMYXllciBjcmVhdGVkIHdpbGwgYmUgcmV1c2VkIGluIGZ1dHVyZVxuICAgICAqIGZ1bmN0aW9uIGNyZWF0aW9uIHJlcXVlc3RzIGlmIHRoZSBjb250ZW50cyBvZiBgcGFja2FnZUpzb25gIGFyZSB0aGUgc2FtZS5cbiAgICAgKlxuICAgICAqIFRoZSBgRkFBU1RfUEFDS0FHRV9ESVJgIGVudmlyb25tZW50IHZhcmlhYmxlIGNhbiBiZSB1c2VmdWwgZm9yIGRlYnVnZ2luZ1xuICAgICAqIGBwYWNrYWdlSnNvbmAgaXNzdWVzLlxuICAgICAqL1xuICAgIHBhY2thZ2VKc29uPzogc3RyaW5nIHwgb2JqZWN0O1xuICAgIC8qKlxuICAgICAqIENhY2hlIGluc3RhbGxlZCBkZXBlbmRlbmNpZXMgZnJvbSB7QGxpbmsgQ29tbW9uT3B0aW9ucy5wYWNrYWdlSnNvbn0uIE9ubHlcbiAgICAgKiBhcHBsaWVzIHRvIEFXUy4gRGVmYXVsdDogdHJ1ZS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIElmIGB1c2VEZXBlbmRlbmN5Q2FjaGluZ2AgaXMgYHRydWVgLCBUaGUgcmVzdWx0aW5nIGBub2RlX21vZHVsZXNgIGZvbGRlclxuICAgICAqIGlzIGNhY2hlZCBpbiBhIExhbWJkYSBMYXllciB3aXRoIHRoZSBuYW1lIGBmYWFzdC0ke2tleX1gLCB3aGVyZSBga2V5YCBpc1xuICAgICAqIHRoZSBTSEExIGhhc2ggb2YgdGhlIGBwYWNrYWdlSnNvbmAgY29udGVudHMuIFRoZXNlIGNhY2hlIGVudHJpZXMgYXJlXG4gICAgICogcmVtb3ZlZCBieSBnYXJiYWdlIGNvbGxlY3Rpb24sIGJ5IGRlZmF1bHQgYWZ0ZXIgMjRoLiBVc2luZyBjYWNoaW5nXG4gICAgICogcmVkdWNlcyB0aGUgbmVlZCB0byBpbnN0YWxsIGFuZCB1cGxvYWQgZGVwZW5kZW5jaWVzIGV2ZXJ5IHRpbWUgYSBmdW5jdGlvblxuICAgICAqIGlzIGNyZWF0ZWQuIFRoaXMgaXMgaW1wb3J0YW50IGZvciBBV1MgYmVjYXVzZSBpdCBjcmVhdGVzIGFuIGVudGlyZWx5XG4gICAgICogc2VwYXJhdGUgbGFtYmRhIGZ1bmN0aW9uIHRvIGluc3RhbGwgZGVwZW5kZW5jaWVzIHJlbW90ZWx5LCB3aGljaCBjYW5cbiAgICAgKiBzdWJzdGFudGlhbGx5IGluY3JlYXNlIGZ1bmN0aW9uIGRlcGxveW1lbnQgdGltZS5cbiAgICAgKlxuICAgICAqIElmIGB1c2VEZXBlbmRlbmN5Q2FjaGluZ2AgaXMgZmFsc2UsIHRoZSBsYW1iZGEgbGF5ZXIgaXMgY3JlYXRlZCB3aXRoIHRoZVxuICAgICAqIHNhbWUgbmFtZSBhcyB0aGUgbGFtYmRhIGZ1bmN0aW9uLCBhbmQgdGhlbiBpcyBkZWxldGVkIHdoZW4gY2xlYW51cCBpc1xuICAgICAqIHJ1bi5cbiAgICAgKi9cbiAgICB1c2VEZXBlbmRlbmN5Q2FjaGluZz86IGJvb2xlYW47XG4gICAgLyoqXG4gICAgICogU3BlY2lmeSBob3cgbWFueSBkYXlzIHRvIHdhaXQgYmVmb3JlIHJlY2xhaW1pbmcgY2xvdWQgZ2FyYmFnZS4gRGVmYXVsdDpcbiAgICAgKiAxLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogR2FyYmFnZSBjb2xsZWN0aW9uIG9ubHkgZGVsZXRlcyByZXNvdXJjZXMgYWZ0ZXIgdGhleSBhZ2UgYmV5b25kIGEgY2VydGFpblxuICAgICAqIG51bWJlciBvZiBkYXlzLiBUaGlzIG9wdGlvbiBzcGVjaWZpZXMgaG93IG1hbnkgZGF5cyBvbGQgYSByZXNvdXJjZSBuZWVkc1xuICAgICAqIHRvIGJlIGJlZm9yZSBiZWluZyBjb25zaWRlcmVkIGdhcmJhZ2UgYnkgdGhlIGNvbGxlY3Rvci4gTm90ZSB0aGF0IHRoaXNcbiAgICAgKiBzZXR0aW5nIGlzIG5vdCByZWNvcmRlZCB3aGVuIHRoZSByZXNvdXJjZXMgYXJlIGNyZWF0ZWQuIEZvciBleGFtcGxlLFxuICAgICAqIHN1cHBvc2UgdGhpcyBpcyB0aGUgc2VxdWVuY2Ugb2YgZXZlbnRzOlxuICAgICAqXG4gICAgICogLSBEYXkgMDogYGZhYXN0KClgIGlzIGNhbGxlZCB3aXRoIGByZXRlbnRpb25JbkRheXNgIHNldCB0byA1LiBUaGVuLCB0aGVcbiAgICAgKiAgIGZ1bmN0aW9uIGNyYXNoZXMgKG9yIG9taXRzIHRoZSBjYWxsIHRvIHtAbGluayBGYWFzdE1vZHVsZS5jbGVhbnVwfSkuXG4gICAgICpcbiAgICAgKiAtIERheSAxOiBgZmFhc3QoKWAgaXMgY2FsbGVkIHdpdGggYHJldGVudGlvbkluRGF5c2Agc2V0IHRvIDEuXG4gICAgICpcbiAgICAgKiBJbiB0aGlzIHNlcXVlbmNlIG9mIGV2ZW50cywgb24gRGF5IDAgdGhlIGdhcmJhZ2UgY29sbGVjdG9yIHJ1bnMgYW5kXG4gICAgICogcmVtb3ZlcyByZXNvdXJjZXMgd2l0aCBhZ2Ugb2xkZXIgdGhhbiA1IGRheXMuIFRoZW4gdGhlIGZ1bmN0aW9uIGxlYXZlc1xuICAgICAqIG5ldyBnYXJiYWdlIGJlaGluZCBiZWNhdXNlIGl0IGNyYXNoZWQgb3IgZGlkIG5vdCBjb21wbGV0ZSBjbGVhbnVwLiBPbiBEYXlcbiAgICAgKiAxLCB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgcnVucyBhbmQgZGVsZXRlcyByZXNvdXJjZXMgYXQgbGVhc3QgMSBkYXkgb2xkLFxuICAgICAqIHdoaWNoIGluY2x1ZGVzIGdhcmJhZ2UgbGVmdCBiZWhpbmQgZnJvbSBEYXkgMCAoYmFzZWQgb24gdGhlIGNyZWF0aW9uXG4gICAgICogdGltZXN0YW1wIG9mIHRoZSByZXNvdXJjZXMpLiBUaGlzIGRlbGV0aW9uIG9jY3VycyBldmVuIHRob3VnaCByZXRlbnRpb25cbiAgICAgKiB3YXMgc2V0IHRvIDUgZGF5cyB3aGVuIHJlc291cmNlcyB3ZXJlIGNyZWF0ZWQgb24gRGF5IDAuXG4gICAgICpcbiAgICAgKiBOb3RlIHRoYXQgaWYgYHJldGVudGlvbkluRGF5c2AgaXMgc2V0IHRvIDAsIGdhcmJhZ2UgY29sbGVjdGlvbiB3aWxsXG4gICAgICogcmVtb3ZlIGFsbCByZXNvdXJjZXMsIGV2ZW4gb25lcyB0aGF0IG1heSBiZSBpbiB1c2UgYnkgb3RoZXIgcnVubmluZyBmYWFzdFxuICAgICAqIGluc3RhbmNlcy4gTm90IHJlY29tbWVuZGVkLlxuICAgICAqXG4gICAgICogU2VlIHtAbGluayBDb21tb25PcHRpb25zLmdjfS5cbiAgICAgKi9cbiAgICByZXRlbnRpb25JbkRheXM/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogUmVkdWNlIHRhaWwgbGF0ZW5jeSBieSByZXRyeWluZyBpbnZvY2F0aW9ucyB0aGF0IHRha2Ugc3Vic3RhbnRpYWxseVxuICAgICAqIGxvbmdlciB0aGFuIG90aGVyIGludm9jYXRpb25zIG9mIHRoZSBzYW1lIGZ1bmN0aW9uLiBEZWZhdWx0OiAzLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogZmFhc3QuanMgYXV0b21hdGljYWxseSBtZWFzdXJlcyB0aGUgbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uICjPgykgb2ZcbiAgICAgKiB0aGUgdGltZSB0YWtlbiBieSBpbnZvY2F0aW9ucyBvZiBlYWNoIGZ1bmN0aW9uLiBSZXRyaWVzIGFyZSBhdHRlbXB0ZWRcbiAgICAgKiB3aGVuIHRoZSB0aW1lIGZvciBhbiBpbnZvY2F0aW9uIGV4Y2VlZHMgdGhlIG1lYW4gdGltZSBieSBhIGNlcnRhaW5cbiAgICAgKiB0aHJlc2hvbGQuIGBzcGVjdWxhdGl2ZVJldHJ5VGhyZXNob2xkYCBzcGVjaWZpZXMgaG93IG1hbnkgbXVsdGlwbGVzIG9mIM+DXG4gICAgICogYW4gaW52b2NhdGlvbiBuZWVkcyB0byBleGNlZWQgdGhlIG1lYW4gZm9yIGEgZ2l2ZW4gZnVuY3Rpb24gYmVmb3JlIHJldHJ5XG4gICAgICogaXMgYXR0ZW1wdGVkLlxuICAgICAqXG4gICAgICogVGhlIGRlZmF1bHQgdmFsdWUgb2Ygz4MgaXMgMy4gVGhpcyBtZWFucyBhIGNhbGwgdG8gYSBmdW5jdGlvbiBpcyByZXRyaWVkXG4gICAgICogd2hlbiB0aGUgdGltZSB0byBleGVjdXRlIGV4Y2VlZHMgdGhyZWUgc3RhbmRhcmQgZGV2aWF0aW9ucyBmcm9tIHRoZSBtZWFuXG4gICAgICogb2YgYWxsIHByaW9yIGV4ZWN1dGlvbnMgb2YgdGhlIHNhbWUgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiBUaGlzIGZlYXR1cmUgaXMgZXhwZXJpbWVudGFsLlxuICAgICAqIEBiZXRhXG4gICAgICovXG4gICAgc3BlY3VsYXRpdmVSZXRyeVRocmVzaG9sZD86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBFeGVjdXRpb24gdGltZSBsaW1pdCBmb3IgZWFjaCBpbnZvY2F0aW9uLCBpbiBzZWNvbmRzLiBEZWZhdWx0OiA2MC5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEVhY2ggcHJvdmlkZXIgaGFzIGEgbWF4aW11bSB0aW1lIGxpbWl0IGZvciBob3cgbG9uZyBpbnZvY2F0aW9ucyBjYW4gcnVuXG4gICAgICogYmVmb3JlIGJlaW5nIGF1dG9tYXRpY2FsbHkgdGVybWluYXRlZCAob3IgZnJvemVuKS4gVGhlIGZvbGxvd2luZyBhcmUgdGhlXG4gICAgICogbWF4aW11bSB0aW1lIGxpbWl0cyBhcyBvZiBGZWJydWFyeSAyMDE5OlxuICAgICAqXG4gICAgICogLSBhd3M6XG4gICAgICogICB7QGxpbmsgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2xhbWJkYS9sYXRlc3QvZGcvbGltaXRzLmh0bWwgfCAxNSBtaW51dGVzfVxuICAgICAqXG4gICAgICogLSBsb2NhbDogdW5saW1pdGVkXG4gICAgICpcbiAgICAgKiBGYWFzdC5qcyBoYXMgYSBwcm9hY3RpdmUgdGltZW91dCBkZXRlY3Rpb24gZmVhdHVyZS4gSXQgYXV0b21hdGljYWxseVxuICAgICAqIGF0dGVtcHRzIHRvIGRldGVjdCB3aGVuIHRoZSB0aW1lIGxpbWl0IGlzIGFib3V0IHRvIGJlIHJlYWNoZWQgYW5kXG4gICAgICogcHJvYWN0aXZlbHkgc2VuZHMgYSB0aW1lb3V0IGV4Y2VwdGlvbi4gRmFhc3QgZG9lcyB0aGlzIGJlY2F1c2Ugbm90IGFsbFxuICAgICAqIHByb3ZpZGVycyByZWxpYWJseSBzZW5kIHRpbWVseSBmZWVkYmFjayB3aGVuIHRpbWVvdXRzIG9jY3VyLCBsZWF2aW5nXG4gICAgICogZGV2ZWxvcGVycyB0byBsb29rIHRocm91Z2ggY2xvdWQgbG9ncy4gSW4gZ2VuZXJhbCBmYWFzdC5qcycgdGltZW91dCB3aWxsXG4gICAgICogYmUgdXAgdG8gNXMgZWFybGllciB0aGFuIHRoZSB0aW1lb3V0IHNwZWNpZmllZCwgaW4gb3JkZXIgdG8gZ2l2ZSB0aW1lIHRvXG4gICAgICogYWxsb3cgZmFhc3QuanMgdG8gc2VuZCBhIHRpbWVvdXQgbWVzc2FnZS4gUHJvYWN0aXZlIHRpbWVvdXQgZGV0ZWN0aW9uXG4gICAgICogb25seSB3b3JrcyB3aXRoIHtAbGluayBDb21tb25PcHRpb25zLmNoaWxkUHJvY2Vzc30gc2V0IHRvIGB0cnVlYCAodGhlXG4gICAgICogZGVmYXVsdCkuXG4gICAgICovXG4gICAgdGltZW91dD86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBFeHRyYSB3ZWJwYWNrIG9wdGlvbnMgdG8gdXNlIHRvIGJ1bmRsZSB0aGUgY29kZSBwYWNrYWdlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogQnkgZGVmYXVsdCwgZmFhc3QuanMgdXNlcyB3ZWJwYWNrIHRvIGJ1bmRsZSB0aGUgY29kZSBwYWNrYWdlLiBXZWJwYWNrXG4gICAgICogYXV0b21hdGljYWxseSBoYW5kbGVzIGZpbmRpbmcgYW5kIGJ1bmRsaW5nIGRlcGVuZGVuY2llcywgYWRkaW5nIHNvdXJjZVxuICAgICAqIG1hcHBpbmdzLCBldGMuIElmIHlvdSBuZWVkIHNwZWNpYWxpemVkIGJ1bmRsaW5nLCB1c2UgdGhpcyBvcHRpb24gdG8gYWRkXG4gICAgICogb3Igb3ZlcnJpZGUgdGhlIGRlZmF1bHQgd2VicGFjayBjb25maWd1cmF0aW9uLiBUaGUgbGlicmFyeVxuICAgICAqIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vc3Vydml2ZWpzL3dlYnBhY2stbWVyZ2UgfCB3ZWJwYWNrLW1lcmdlfSBpc1xuICAgICAqIHVzZWQgdG8gY29tYmluZSBjb25maWd1cmF0aW9ucy5cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBjb25maWc6IHdlYnBhY2suQ29uZmlndXJhdGlvbiA9IG1lcmdlKHtcbiAgICAgKiAgICAgZW50cnksXG4gICAgICogICAgIG1vZGU6IFwiZGV2ZWxvcG1lbnRcIixcbiAgICAgKiAgICAgb3V0cHV0OiB7XG4gICAgICogICAgICAgICBwYXRoOiBcIi9cIixcbiAgICAgKiAgICAgICAgIGZpbGVuYW1lOiBvdXRwdXRGaWxlbmFtZSxcbiAgICAgKiAgICAgICAgIGxpYnJhcnlUYXJnZXQ6IFwiY29tbW9uanMyXCJcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdGFyZ2V0OiBcIm5vZGVcIixcbiAgICAgKiAgICAgcmVzb2x2ZUxvYWRlcjogeyBtb2R1bGVzOiBbX19kaXJuYW1lLCBgJHtfX2Rpcm5hbWV9L2Rpc3RgXSB9LFxuICAgICAqICAgICBub2RlOiB7IGdsb2JhbDogdHJ1ZSwgX19kaXJuYW1lOiBmYWxzZSwgX19maWxlbmFtZTogZmFsc2UgfVxuICAgICAqICAgfSxcbiAgICAgKiAgIHdlYnBhY2tPcHRpb25zKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIFRha2UgY2FyZSB3aGVuIHNldHRpbmcgdGhlIHZhbHVlcyBvZiBgZW50cnlgLCBgb3V0cHV0YCwgb3JcbiAgICAgKiBgcmVzb2x2ZUxvYWRlcmAuIElmIHRoZXNlIG9wdGlvbnMgYXJlIG92ZXJ3cml0dGVuLCBmYWFzdC5qcyBtYXkgZmFpbCB0b1xuICAgICAqIGJ1bmRsZSB5b3VyIGNvZGUuIEluIHBhcnRpY3VsYXIsIHNldHRpbmcgYGVudHJ5YCB0byBhbiBhcnJheSB2YWx1ZSB3aWxsXG4gICAgICogaGVscCBgd2VicGFjay1tZXJnZWAgdG8gY29uY2F0ZW5hdGUgaXRzIHZhbHVlIGluc3RlYWQgb2YgcmVwbGFjaW5nIHRoZVxuICAgICAqIHZhbHVlIHRoYXQgZmFhc3QuanMgaW5zZXJ0cyBmb3IgeW91LlxuICAgICAqXG4gICAgICogRGVmYXVsdDpcbiAgICAgKlxuICAgICAqIC0gYXdzOiBgeyBleHRlcm5hbHM6IFtuZXcgUmVnRXhwKFwiXmF3cy1zZGsvP1wiKV0gfWAuIEluIHRoZSBsYW1iZGFcbiAgICAgKiAgIGVudmlyb25tZW50IGBcImF3cy1zZGtcImAgaXMgYXZhaWxhYmxlIGluIHRoZSBhbWJpZW50IGVudmlyb25tZW50IGFuZFxuICAgICAqICAgZG9lcyBub3QgbmVlZCB0byBiZSBidW5kbGVkLlxuICAgICAqXG4gICAgICogLSBvdGhlciBwcm92aWRlcnM6IGB7fWBcbiAgICAgKlxuICAgICAqIFRoZSBgRkFBU1RfUEFDS0FHRV9ESVJgIGVudmlyb25tZW50IHZhcmlhYmxlIGNhbiBiZSB1c2VmdWwgZm9yIGRlYnVnZ2luZ1xuICAgICAqIHdlYnBhY2sgaXNzdWVzLlxuICAgICAqL1xuICAgIHdlYnBhY2tPcHRpb25zPzogd2VicGFjay5Db25maWd1cmF0aW9uO1xuICAgIC8qKlxuICAgICAqIENoZWNrIGFyZ3VtZW50cyBhbmQgcmV0dXJuIHZhbHVlcyBmcm9tIGNsb3VkIGZ1bmN0aW9ucyBhcmUgc2VyaWFsaXphYmxlXG4gICAgICogd2l0aG91dCBsb3NpbmcgaW5mb3JtYXRpb24uIERlZmF1bHQ6IHRydWUuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBBcmd1bWVudHMgdG8gY2xvdWQgZnVuY3Rpb25zIGFyZSBhdXRvbWF0aWNhbGx5IHNlcmlhbGl6ZWQgd2l0aFxuICAgICAqIGBKU09OLnN0cmluZ2lmeWAgd2l0aCBhIGN1c3RvbSByZXBsYWNlciB0aGF0IGhhbmRsZXMgYnVpbHQtaW4gSmF2YVNjcmlwdFxuICAgICAqIHR5cGVzIHN1Y2ggYXMgYERhdGVgIGFuZCBgQnVmZmVyYC4gUmV0dXJuIHZhbHVlcyBnbyB0aHJvdWdoIHRoZSBzYW1lXG4gICAgICogcHJvY2Vzcy4gU29tZSBKYXZhU2NyaXB0IG9iamVjdHMgY2Fubm90IGJlIHNlcmlhbGl6ZWQuIEJ5IGRlZmF1bHRcbiAgICAgKiBgdmFsaWRhdGVTZXJpYWxpemF0aW9uYCB3aWxsIHZlcmlmeSB0aGF0IGV2ZXJ5IGFyZ3VtZW50IGFuZCByZXR1cm4gdmFsdWVcbiAgICAgKiBjYW4gYmUgc2VyaWFsaXplZCBhbmQgZGVzZXJpYWxpemVkIHdpdGhvdXQgbG9zaW5nIGluZm9ybWF0aW9uLiBBXG4gICAgICogYEZhYXN0RXJyb3JgIHdpbGwgYmUgdGhyb3duIGlmIGZhYXN0LmpzIGRldGVjdHMgYSBwcm9ibGVtIGFjY29yZGluZyB0b1xuICAgICAqIHRoZSBmb2xsb3dpbmcgcHJvY2VkdXJlOlxuICAgICAqXG4gICAgICogMS4gU2VyaWFsaXplIGFyZ3VtZW50cyBhbmQgcmV0dXJuIHZhbHVlcyB3aXRoIGBKU09OLnN0cmluZ2lmeWAgdXNpbmcgYVxuICAgICAqICAgIHNwZWNpYWwgYHJlcGxhY2VyYCBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIDIuIERlc2VyaWFsaXplIHRoZSB2YWx1ZXMgd2l0aCBgSlNPTi5wYXJzZWAgd2l0aCBhIHNwZWNpYWwgYHJldml2ZXJgXG4gICAgICogICAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAzLiBVc2VcbiAgICAgKiAgICB7QGxpbmsgaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9hc3NlcnQuaHRtbCNhc3NlcnRfYXNzZXJ0X2RlZXBzdHJpY3RlcXVhbF9hY3R1YWxfZXhwZWN0ZWRfbWVzc2FnZSB8IGFzc2VydC5kZWVwU3RyaW5nRXF1YWx9XG4gICAgICogICAgdG8gY29tcGFyZSB0aGUgb3JpZ2luYWwgb2JqZWN0IHdpdGggdGhlIGRlc2VyaWFsaXplZCBvYmplY3QgZnJvbSBzdGVwXG4gICAgICogICAgMi5cbiAgICAgKlxuICAgICAqIFRoZXJlIGlzIHNvbWUgb3ZlcmhlYWQgdG8gdGhpcyBwcm9jZXNzIGJlY2F1c2UgZWFjaCBhcmd1bWVudCBpc1xuICAgICAqIHNlcmlhbGl6ZWQgYW5kIGRlc2VyaWFsaXplZCwgd2hpY2ggY2FuIGJlIGNvc3RseSBpZiBhcmd1bWVudHMgb3IgcmV0dXJuXG4gICAgICogdmFsdWVzIGFyZSBsYXJnZS5cbiAgICAgKi9cbiAgICB2YWxpZGF0ZVNlcmlhbGl6YXRpb24/OiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIERlYnVnZ2luZyBvdXRwdXQgb3B0aW9ucy5cbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBkZWJ1Z09wdGlvbnM/OiB7IFtrZXk6IHN0cmluZ106IGJvb2xlYW4gfTtcbn1cblxuZXhwb3J0IGNvbnN0IGNvbW1vbkRlZmF1bHRzOiBSZXF1aXJlZDxDb21tb25PcHRpb25zPiA9IHtcbiAgICBjaGlsZFByb2Nlc3M6IHRydWUsXG4gICAgY2hpbGRQcm9jZXNzTWVtb3J5TWI6IDAsXG4gICAgY29uY3VycmVuY3k6IDEwMCxcbiAgICBkZXNjcmlwdGlvbjogXCJcIixcbiAgICBleGNsdWRlOiBbXSxcbiAgICBpbmNsdWRlOiBbXSxcbiAgICByYXRlOiAwLFxuICAgIGVudjoge30sXG4gICAgZ2M6IFwiYXV0b1wiLFxuICAgIG1heFJldHJpZXM6IDIsXG4gICAgbWVtb3J5U2l6ZTogMTAyNCxcbiAgICBtb2RlOiBcImF1dG9cIixcbiAgICBwYWNrYWdlSnNvbjogXCJcIixcbiAgICB1c2VEZXBlbmRlbmN5Q2FjaGluZzogdHJ1ZSxcbiAgICByZXRlbnRpb25JbkRheXM6IDEsXG4gICAgc3BlY3VsYXRpdmVSZXRyeVRocmVzaG9sZDogMyxcbiAgICB0aW1lb3V0OiA2MCxcbiAgICB3ZWJwYWNrT3B0aW9uczoge30sXG4gICAgdmFsaWRhdGVTZXJpYWxpemF0aW9uOiB0cnVlLFxuICAgIGRlYnVnT3B0aW9uczoge31cbn07XG5cbi8qKlxuICogT3B0aW9ucyB0aGF0IGFwcGx5IHRvIHRoZSB7QGxpbmsgRmFhc3RNb2R1bGUuY2xlYW51cH0gbWV0aG9kLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgaW50ZXJmYWNlIENsZWFudXBPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBJZiB0cnVlLCBkZWxldGUgcHJvdmlkZXIgY2xvdWQgcmVzb3VyY2VzLiBEZWZhdWx0OiB0cnVlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogVGhlIGNsZWFudXAgb3BlcmF0aW9uIGhhcyB0d28gZnVuY3Rpb25zOiBzdG9wcGluZyB0aGUgZmFhc3QuanMgcnVudGltZVxuICAgICAqIGFuZCBkZWxldGluZyBjbG91ZCByZXNvdXJjZXMgdGhhdCB3ZXJlIGluc3RhbnRpYXRlZC4gSWYgYGRlbGV0ZVJlc291cmNlc2BcbiAgICAgKiBpcyBmYWxzZSwgdGhlbiBvbmx5IHRoZSBydW50aW1lIGlzIHN0b3BwZWQgYW5kIG5vIGNsb3VkIHJlc291cmNlcyBhcmVcbiAgICAgKiBkZWxldGVkLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIGRlYnVnZ2luZyBhbmQgZXhhbWluaW5nIHRoZSBzdGF0ZSBvZlxuICAgICAqIHJlc291cmNlcyBjcmVhdGVkIGJ5IGZhYXN0LmpzLlxuICAgICAqXG4gICAgICogSXQgaXMgc3VwcG9ydGVkIHRvIGNhbGwge0BsaW5rIEZhYXN0TW9kdWxlLmNsZWFudXB9IHR3aWNlOiBvbmNlIHdpdGhcbiAgICAgKiBgZGVsZXRlUmVzb3VyY2VzYCBzZXQgdG8gYGZhbHNlYCwgd2hpY2ggb25seSBzdG9wcyB0aGUgcnVudGltZSwgYW5kIHRoZW5cbiAgICAgKiBhZ2FpbiBzZXQgdG8gYHRydWVgIHRvIGRlbGV0ZSByZXNvdXJjZXMuIFRoaXMgY2FuIGJlIHVzZWZ1bCBmb3IgdGVzdGluZy5cbiAgICAgKi9cbiAgICBkZWxldGVSZXNvdXJjZXM/OiBib29sZWFuO1xuXG4gICAgLyoqXG4gICAgICogSWYgdHJ1ZSwgZGVsZXRlIGNhY2hlZCByZXNvdXJjZXMuIERlZmF1bHQ6IGZhbHNlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogU29tZSByZXNvdXJjZXMgYXJlIGNhY2hlZCBwZXJzaXN0ZW50bHkgYmV0d2VlbiBjYWxscyBmb3IgcGVyZm9ybWFuY2VcbiAgICAgKiByZWFzb25zLiBJZiB0aGlzIG9wdGlvbiBpcyBzZXQgdG8gdHJ1ZSwgdGhlc2UgY2FjaGVkIHJlc291cmNlcyBhcmVcbiAgICAgKiBkZWxldGVkIHdoZW4gY2xlYW51cCBvY2N1cnMsIGluc3RlYWQgb2YgYmVpbmcgbGVmdCBiZWhpbmQgZm9yIGZ1dHVyZSB1c2UuXG4gICAgICogRm9yIGV4YW1wbGUsIG9uIEFXUyB0aGlzIGluY2x1ZGVzIHRoZSBMYW1iZGEgTGF5ZXJzIHRoYXQgYXJlIGNyZWF0ZWQgZm9yXG4gICAgICoge0BsaW5rIENvbW1vbk9wdGlvbnMucGFja2FnZUpzb259IGRlcGVuZGVuY2llcy4gTm90ZSB0aGF0IG9ubHkgdGhlIGNhY2hlZFxuICAgICAqIHJlc291cmNlcyBjcmVhdGVkIGJ5IHRoaXMgaW5zdGFuY2Ugb2YgRmFhc3RNb2R1bGUgYXJlIGRlbGV0ZWQsIG5vdCBjYWNoZWRcbiAgICAgKiByZXNvdXJjZXMgZnJvbSBvdGhlciBGYWFzdE1vZHVsZXMuIFRoaXMgaXMgc2ltaWxhciB0byBzZXR0aW5nXG4gICAgICogYHVzZUNhY2hlZERlcGVuZGVuY2llc2AgdG8gYGZhbHNlYCBkdXJpbmcgZnVuY3Rpb24gY29uc3RydWN0aW9uLCBleGNlcHRcbiAgICAgKiBgZGVsZXRlQ2FjaGVzYCBjYW4gYmUgc2V0IGF0IGZ1bmN0aW9uIGNsZWFudXAgdGltZSwgYW5kIGFueSBvdGhlclxuICAgICAqIEZhYXN0TW9kdWxlcyBjcmVhdGVkIGJlZm9yZSBjbGVhbnVwIG1heSB1c2UgdGhlIGNhY2hlZCBMYXllcnMuXG4gICAgICovXG4gICAgZGVsZXRlQ2FjaGVzPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIE51bWJlciBvZiBzZWNvbmRzIHRvIHdhaXQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbi4gRGVmYXVsdDogMTAuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3Rpb24gY2FuIHN0aWxsIGJlIG9wZXJhdGluZyB3aGVuIGNsZWFudXAgaXMgY2FsbGVkOyB0aGlzXG4gICAgICogb3B0aW9uIGxpbWl0cyB0aGUgYW1vdW50IG9mIHRpbWUgZmFhc3Qgd2FpdHMgZm9yIHRoZSBnYXJiYWdlIGNvbGxlY3Rvci5cbiAgICAgKiBJZiBzZXQgdG8gMCwgdGhlIHdhaXQgaXMgdW5saW1pdGVkLlxuICAgICAqL1xuICAgIGdjVGltZW91dD86IG51bWJlcjtcbn1cblxuZXhwb3J0IGNvbnN0IENsZWFudXBPcHRpb25EZWZhdWx0czogUmVxdWlyZWQ8Q2xlYW51cE9wdGlvbnM+ID0ge1xuICAgIGRlbGV0ZVJlc291cmNlczogdHJ1ZSxcbiAgICBkZWxldGVDYWNoZXM6IGZhbHNlLFxuICAgIGdjVGltZW91dDogMTBcbn07XG5cbi8qKlxuICogU3VtbWFyeSBzdGF0aXN0aWNzIGZvciBmdW5jdGlvbiBpbnZvY2F0aW9ucy5cbiAqIEByZW1hcmtzXG4gKiBgYGBcbiAqICAgICAgICAgICAgICAgbG9jYWxTdGFydExhdGVuY3kgICAgICByZW1vdGVTdGFydExhdGVuY3kgICAgICBleGVjdXRpb25UaW1lXG4gKiAgICAgICAgICAgICDil4DilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilrbil4Eg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKWt+KXgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKWtlxuICpcbiAqIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUrOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkFxuICog4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxuICog4pSCICAgICAgICAgICAgICAgTG9jYWwgICAgICAgICAgICAgICDilIIgICAgICAgICAgICBDbG91ZCBQcm92aWRlciAgICAgICAgICAgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAgICAg4pSCICAg4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQICAgICAgICAg4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgIOKUgiAgIOKUgiAgICAgICAgICDilIIgICAgICAgICDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSCICBsb2NhbCAg4pSCICAgIOKUgiAgIOKUgiByZXF1ZXN0ICDilIIgICAgICAgICDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgIGludm9rZSAg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pa24pSCICBxdWV1ZSAg4pSC4pSA4pSA4pSA4pSA4pS84pSA4pSA4pa24pSCICBxdWV1ZSAgIOKUnOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKWtuKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICDilIIgICAg4pSCICAg4pSCICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilJggICAg4pSCICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYICAgICAgICAg4pSCICBjbG91ZCAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgIOKUgiBmdW5jdGlvbiDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilJAgICAg4pSCICAg4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQICAgICAgICAg4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICDilIIgICDilIIgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICByZXN1bHQgIOKXgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgiAgbG9jYWwgIOKUguKXgOKUgOKUgOKUgOKUvOKUgOKUgOKUgOKUgiByZXNwb25zZSDilILil4DilIDilIDilIDilIDilIDilIDilIDilIDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSCIHBvbGxpbmcg4pSCICAgIOKUgiAgIOKUgiAgcXVldWUgICDilIIgICAgICAgICDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgIOKUgiAgIOKUgiAgICAgICAgICDilIIgICAgICAgICDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYICAgIOKUgiAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmCAgICAgICAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmCAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCXG4gKiDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilLTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJhcbiAqXG4gKiAgICAgICAgICAgICDil4Eg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilrdcbiAqICAgICAgICAgICAgICAgICAgICAgIHJldHVybkxhdGVuY3kgICAgICAgICAgICAgICAgICDil4DilIDilIDilIDilIDilIDilIDilIDilrZcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZW5kUmVzcG9uc2VMYXRlbmN5XG4gKiBgYGBcbiAqXG4gKiBgbG9jYWxTdGFydExhdGVuY3lgIGFuZCBgZXhlY3V0aW9uVGltZWAgYXJlIG1lYXN1cmVkIG9uIG9uZSBtYWNoaW5lIGFuZCBhcmVcbiAqIGZyZWUgb2YgY2xvY2sgc2tldy4gYHJlbW90ZVN0YXJ0TGF0ZW5jeWAgYW5kIGByZXR1cm5MYXRlbmN5YCBhcmUgbWVhc3VyZWQgYXNcbiAqIHRpbWUgZGlmZmVyZW5jZXMgYmV0d2VlbiBtYWNoaW5lcyBhbmQgYXJlIHN1YmplY3QgdG8gbXVjaCBtb3JlIHVuY2VydGFpbnR5LFxuICogYW5kIGVmZmVjdHMgbGlrZSBjbG9jayBza2V3LlxuICpcbiAqIEFsbCB0aW1lcyBhcmUgaW4gbWlsbGlzZWNvbmRzLlxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uU3RhdHMge1xuICAgIC8qKlxuICAgICAqIFN0YXRpc3RpY3MgZm9yIGhvdyBsb25nIGludm9jYXRpb25zIHN0YXkgaW4gdGhlIGxvY2FsIHF1ZXVlIGJlZm9yZSBiZWluZ1xuICAgICAqIHNlbnQgdG8gdGhlIGNsb3VkIHByb3ZpZGVyLlxuICAgICAqL1xuICAgIGxvY2FsU3RhcnRMYXRlbmN5ID0gbmV3IFN0YXRpc3RpY3MoKTtcbiAgICAvKipcbiAgICAgKiBTdGF0aXN0aWNzIGZvciBob3cgbG9uZyByZXF1ZXN0cyB0YWtlIHRvIHN0YXJ0IGV4ZWN1dGlvbiBhZnRlciBiZWluZyBzZW50XG4gICAgICogdG8gdGhlIGNsb3VkIHByb3ZpZGVyLiBUaGlzIHR5cGljYWxseSBpbmNsdWRlcyByZW1vdGUgcXVldWVpbmcgYW5kIGNvbGRcbiAgICAgKiBzdGFydCB0aW1lcy4gQmVjYXVzZSB0aGlzIG1lYXN1cmVtZW50IHJlcXVpcmVzIGNvbXBhcmluZyB0aW1lc3RhbXBzIGZyb21cbiAgICAgKiBkaWZmZXJlbnQgbWFjaGluZXMsIGl0IGlzIHN1YmplY3QgdG8gY2xvY2sgc2tldyBhbmQgb3RoZXIgZWZmZWN0cywgYW5kXG4gICAgICogc2hvdWxkIG5vdCBiZSBjb25zaWRlcmVkIGhpZ2hseSBhY2N1cmF0ZS4gSXQgY2FuIGJlIHVzZWZ1bCBmb3IgZGV0ZWN0aW5nXG4gICAgICogZXhjZXNzaXZlbHkgaGlnaCBsYXRlbmN5IHByb2JsZW1zLiBGYWFzdC5qcyBhdHRlbXB0IHRvIGNvcnJlY3QgZm9yIGNsb2NrXG4gICAgICogc2tldyBoZXVyaXN0aWNhbGx5LlxuICAgICAqL1xuICAgIHJlbW90ZVN0YXJ0TGF0ZW5jeSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgLyoqXG4gICAgICogU3RhdGlzdGljcyBmb3IgZnVuY3Rpb24gZXhlY3V0aW9uIHRpbWUgaW4gbWlsbGlzZWNvbmRzLiAgVGhpcyBpcyBtZWFzdXJlZFxuICAgICAqIGFzIHdhbGwgY2xvY2sgdGltZSBpbnNpZGUgdGhlIGNsb3VkIGZ1bmN0aW9uLCBhbmQgZG9lcyBub3QgaW5jbHVkZSB0aGVcbiAgICAgKiB0aW1lIHRha2VuIHRvIHNlbmQgdGhlIHJlc3BvbnNlIHRvIHRoZSByZXNwb25zZSBxdWV1ZS4gTm90ZSB0aGF0IG1vc3RcbiAgICAgKiBjbG91ZCBwcm92aWRlcnMgcm91bmQgdXAgdG8gdGhlIG5leHQgMTAwbXMgZm9yIHByaWNpbmcuXG4gICAgICovXG4gICAgZXhlY3V0aW9uVGltZSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgLyoqXG4gICAgICogU3RhdGlzdGljcyBmb3IgaG93IGxvbmcgaXQgdGFrZXMgdG8gc2VuZCB0aGUgcmVzcG9uc2UgdG8gdGhlIHJlc3BvbnNlXG4gICAgICogcXVldWUuXG4gICAgICovXG4gICAgc2VuZFJlc3BvbnNlTGF0ZW5jeSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgLyoqXG4gICAgICogU3RhdGlzdGljcyBmb3IgaG93IGxvbmcgaXQgdGFrZXMgdG8gcmV0dXJuIGEgcmVzcG9uc2UgZnJvbSB0aGUgZW5kIG9mXG4gICAgICogZXhlY3V0aW9uIHRpbWUgdG8gdGhlIHJlY2VpcHQgb2YgdGhlIHJlc3BvbnNlIGxvY2FsbHkuIFRoaXMgbWVhc3VyZW1lbnRcbiAgICAgKiByZXF1aXJlcyBjb21wYXJpbmcgdGltZXN0YW1wcyBmcm9tIGRpZmZlcmVudCBtYWNoaW5lcywgYW5kIGlzIHN1YmplY3QgdG9cbiAgICAgKiBjbG9jayBza2V3IGFuZCBvdGhlciBlZmZlY3RzLiBJdCBzaG91bGQgbm90IGJlIGNvbnNpZGVyZWQgaGlnaGx5XG4gICAgICogYWNjdXJhdGUuIEl0IGNhbiBiZSB1c2VmdWwgZm9yIGRldGVjdGluZyBleGNlc3NpdmVseSBoaWdoIGxhdGVuY3lcbiAgICAgKiBwcm9ibGVtcy4gRmFhc3QuanMgYXR0ZW1wdHMgdG8gY29ycmVjdCBmb3IgY2xvY2sgc2tldyBoZXVyaXN0aWNhbGx5LlxuICAgICAqL1xuICAgIHJldHVybkxhdGVuY3kgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIC8qKlxuICAgICAqIFN0YXRpc3RpY3MgZm9yIGFtb3VudCBvZiB0aW1lIGJpbGxlZC4gVGhpcyBpcyBzaW1pbGFyIHRvXG4gICAgICoge0BsaW5rIEZ1bmN0aW9uU3RhdHMuZXhlY3V0aW9uVGltZX0gZXhjZXB0IGVhY2ggc2FtcGxlZCB0aW1lIGlzIHJvdW5kZWRcbiAgICAgKiB1cCB0byB0aGUgbmV4dCAxMDBtcy5cbiAgICAgKi9cbiAgICBlc3RpbWF0ZWRCaWxsZWRUaW1lID0gbmV3IFN0YXRpc3RpY3MoKTtcbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGludm9jYXRpb25zIGF0dGVtcHRlZC4gSWYgYW4gaW52b2NhdGlvbiBpcyByZXRyaWVkLCB0aGlzXG4gICAgICogb25seSBjb3VudHMgdGhlIGludm9jYXRpb24gb25jZS5cbiAgICAgKi9cbiAgICBpbnZvY2F0aW9ucyA9IDA7XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpbnZvY2F0aW9ucyB0aGF0IHdlcmUgc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZC5cbiAgICAgKi9cbiAgICBjb21wbGV0ZWQgPSAwO1xuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW52b2NhdGlvbiByZXRyaWVzIGF0dGVtcHRlZC4gVGhpcyBjb3VudHMgcmV0cmllc1xuICAgICAqIGF0dGVtcHRlZCBieSBmYWFzdC5qcyB0byByZWNvdmVyIGZyb20gdHJhbnNpZW50IGVycm9ycywgYnV0IGRvZXMgbm90XG4gICAgICogY291bnQgcmV0cmllcyBieSB0aGUgY2xvdWQgcHJvdmlkZXIuXG4gICAgICovXG4gICAgcmV0cmllcyA9IDA7XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpbnZvY2F0aW9ucyB0aGF0IHJlc3VsdGVkIGluIGFuIGVycm9yLiBJZiBhbiBpbnZvY2F0aW9uIGlzXG4gICAgICogcmV0cmllZCwgYW4gZXJyb3IgaXMgb25seSBjb3VudGVkIG9uY2UsIG5vIG1hdHRlciBob3cgbWFueSByZXRyaWVzIHdlcmVcbiAgICAgKiBhdHRlbXB0ZWQuXG4gICAgICovXG4gICAgZXJyb3JzID0gMDtcbiAgICAvKipcbiAgICAgKiBTdW1tYXJpemUgdGhlIGZ1bmN0aW9uIHN0YXRzIGFzIGEgc3RyaW5nLlxuICAgICAqIEByZXR1cm5zIGEgc3RyaW5nIHNob3dpbmcgdGhlIHZhbHVlIG9mIGNvbXBsZXRlZCwgcmV0cmllcywgZXJyb3JzLCBhbmRcbiAgICAgKiBtZWFuIGV4ZWN1dGlvbiB0aW1lLiBUaGlzIHN0cmluZyBleGNsdWRlcyBpbnZvY2F0aW9ucyBieSBkZWZhdWx0IGJlY2F1c2VcbiAgICAgKiBpdCBpcyBvZnRlbiBmaXhlZC5cbiAgICAgKi9cbiAgICB0b1N0cmluZygpIHtcbiAgICAgICAgcmV0dXJuIGBjb21wbGV0ZWQ6ICR7dGhpcy5jb21wbGV0ZWR9LCByZXRyaWVzOiAke3RoaXMucmV0cmllc30sIGVycm9yczogJHt0aGlzLmVycm9yc30sIGV4ZWN1dGlvblRpbWUubWVhbjogJHt0aGlzLmV4ZWN1dGlvblRpbWUubWVhbn1tc2A7XG4gICAgfVxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBjbG9uZSgpOiBGdW5jdGlvblN0YXRzIHtcbiAgICAgICAgY29uc3QgcnYgPSBPYmplY3QuYXNzaWduKE9iamVjdC5jcmVhdGUoT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpKSwgdGhpcyk7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXNPZihydikpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcnZba2V5XSAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICAgICAgICAgIHJ2W2tleV0gPSBydltrZXldLmNsb25lKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJ2O1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIEZ1bmN0aW9uRXhlY3V0aW9uTWV0cmljcyB7XG4gICAgc2Vjb25kTWV0cmljczogU3RhdGlzdGljc1tdID0gW107XG59XG5cbmV4cG9ydCB0eXBlIENhbGxJZCA9IHN0cmluZztcblxuZXhwb3J0IGludGVyZmFjZSBSZXNwb25zZUNvbnRleHQge1xuICAgIHR5cGU6IFwiZnVsZmlsbFwiIHwgXCJyZWplY3RcIjtcbiAgICB2YWx1ZTogc3RyaW5nO1xuICAgIGNhbGxJZDogQ2FsbElkO1xuICAgIGlzRXJyb3JPYmplY3Q/OiBib29sZWFuO1xuICAgIHJlbW90ZUV4ZWN1dGlvblN0YXJ0VGltZT86IG51bWJlcjtcbiAgICByZW1vdGVFeGVjdXRpb25FbmRUaW1lPzogbnVtYmVyO1xuICAgIGxvZ1VybD86IHN0cmluZztcbiAgICBpbnN0YW5jZUlkPzogc3RyaW5nO1xuICAgIGV4ZWN1dGlvbklkPzogc3RyaW5nO1xuICAgIG1lbW9yeVVzYWdlPzogTm9kZUpTLk1lbW9yeVVzYWdlO1xuICAgIHRpbWVzdGFtcD86IG51bWJlcjsgLy8gdGltZXN0YW1wIHdoZW4gcmVzcG9uc2UgbWVzc2FnZSB3YXMgc2VudCBhY2NvcmRpbmcgdG8gY2xvdWQgc2VydmljZSwgdGhpcyBpcyBvcHRpb25hbCBhbmQgdXNlZCB0byBwcm92aWRlIG1vcmUgYWNjdXJhdGUgbWV0cmljcy5cbn1cblxuZXhwb3J0IGludGVyZmFjZSBQcm9taXNlUmVzcG9uc2VNZXNzYWdlIGV4dGVuZHMgUmVzcG9uc2VDb250ZXh0IHtcbiAgICBraW5kOiBcInByb21pc2VcIjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJdGVyYXRvclJlc3BvbnNlTWVzc2FnZSBleHRlbmRzIFJlc3BvbnNlQ29udGV4dCB7XG4gICAga2luZDogXCJpdGVyYXRvclwiO1xuICAgIHNlcXVlbmNlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRnVuY3Rpb25TdGFydGVkTWVzc2FnZSB7XG4gICAga2luZDogXCJmdW5jdGlvbnN0YXJ0ZWRcIjtcbiAgICBjYWxsSWQ6IENhbGxJZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDcHVNZXRyaWNzTWVzc2FnZSB7XG4gICAga2luZDogXCJjcHVtZXRyaWNzXCI7XG