UNPKG

53.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.filterMessages = exports.FunctionExecutionMetrics = exports.FunctionStats = exports.CleanupOptionDefaults = exports.commonDefaults = void 0;
4const shared_1 = require("./shared");
5exports.commonDefaults = {
6 childProcess: true,
7 childProcessMemoryMb: 0,
8 concurrency: 100,
9 description: "",
10 exclude: [],
11 include: [],
12 rate: 0,
13 env: {},
14 gc: "auto",
15 maxRetries: 2,
16 memorySize: 1024,
17 mode: "auto",
18 packageJson: "",
19 useDependencyCaching: true,
20 retentionInDays: 1,
21 speculativeRetryThreshold: 3,
22 timeout: 60,
23 webpackOptions: {},
24 validateSerialization: true,
25 debugOptions: {}
26};
27exports.CleanupOptionDefaults = {
28 deleteResources: true,
29 deleteCaches: false,
30 gcTimeout: 10
31};
32/**
33 * Summary statistics for function invocations.
34 * @remarks
35 * ```
36 * localStartLatency remoteStartLatency executionTime
37 * ◀──────────────────▶◁ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▷◀──────────▶
38 *
39 * ┌───────────────────────────────────┬──────────────────────────────────────┐
40 * │ │ │
41 * │ Local │ Cloud Provider │
42 * │ │ │
43 * │ ┌─────────┐ │ ┌──────────┐ ┌──────────┐ │
44 * │ │ │ │ │ │ │ │ │
45 * │ │ local │ │ │ request │ │ │ │
46 * │ invoke ────────▶│ queue │────┼──▶│ queue ├────────▶│ │ │
47 * │ │ │ │ │ │ │ │ │
48 * │ └─────────┘ │ └──────────┘ │ cloud │ │
49 * │ │ │ function │ │
50 * │ ┌─────────┐ │ ┌──────────┐ │ │ │
51 * │ │ │ │ │ │ │ │ │
52 * │ result ◀────────│ local │◀───┼───│ response │◀────────│ │ │
53 * │ │ polling │ │ │ queue │ │ │ │
54 * │ │ │ │ │ │ │ │ │
55 * │ └─────────┘ │ └──────────┘ └──────────┘ │
56 * │ │ │
57 * └───────────────────────────────────┴──────────────────────────────────────┘
58 *
59 * ◁ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ▷
60 * returnLatency ◀───────▶
61 * sendResponseLatency
62 * ```
63 *
64 * `localStartLatency` and `executionTime` are measured on one machine and are
65 * free of clock skew. `remoteStartLatency` and `returnLatency` are measured as
66 * time differences between machines and are subject to much more uncertainty,
67 * and effects like clock skew.
68 *
69 * All times are in milliseconds.
70 *
71 * @public
72 */
73class FunctionStats {
74 constructor() {
75 /**
76 * Statistics for how long invocations stay in the local queue before being
77 * sent to the cloud provider.
78 */
79 this.localStartLatency = new shared_1.Statistics();
80 /**
81 * Statistics for how long requests take to start execution after being sent
82 * to the cloud provider. This typically includes remote queueing and cold
83 * start times. Because this measurement requires comparing timestamps from
84 * different machines, it is subject to clock skew and other effects, and
85 * should not be considered highly accurate. It can be useful for detecting
86 * excessively high latency problems. Faast.js attempt to correct for clock
87 * skew heuristically.
88 */
89 this.remoteStartLatency = new shared_1.Statistics();
90 /**
91 * Statistics for function execution time in milliseconds. This is measured
92 * as wall clock time inside the cloud function, and does not include the
93 * time taken to send the response to the response queue. Note that most
94 * cloud providers round up to the next 100ms for pricing.
95 */
96 this.executionTime = new shared_1.Statistics();
97 /**
98 * Statistics for how long it takes to send the response to the response
99 * queue.
100 */
101 this.sendResponseLatency = new shared_1.Statistics();
102 /**
103 * Statistics for how long it takes to return a response from the end of
104 * execution time to the receipt of the response locally. This measurement
105 * requires comparing timestamps from different machines, and is subject to
106 * clock skew and other effects. It should not be considered highly
107 * accurate. It can be useful for detecting excessively high latency
108 * problems. Faast.js attempts to correct for clock skew heuristically.
109 */
110 this.returnLatency = new shared_1.Statistics();
111 /**
112 * Statistics for amount of time billed. This is similar to
113 * {@link FunctionStats.executionTime} except each sampled time is rounded
114 * up to the next 100ms.
115 */
116 this.estimatedBilledTime = new shared_1.Statistics();
117 /**
118 * The number of invocations attempted. If an invocation is retried, this
119 * only counts the invocation once.
120 */
121 this.invocations = 0;
122 /**
123 * The number of invocations that were successfully completed.
124 */
125 this.completed = 0;
126 /**
127 * The number of invocation retries attempted. This counts retries
128 * attempted by faast.js to recover from transient errors, but does not
129 * count retries by the cloud provider.
130 */
131 this.retries = 0;
132 /**
133 * The number of invocations that resulted in an error. If an invocation is
134 * retried, an error is only counted once, no matter how many retries were
135 * attempted.
136 */
137 this.errors = 0;
138 }
139 /**
140 * Summarize the function stats as a string.
141 * @returns a string showing the value of completed, retries, errors, and
142 * mean execution time. This string excludes invocations by default because
143 * it is often fixed.
144 */
145 toString() {
146 return `completed: ${this.completed}, retries: ${this.retries}, errors: ${this.errors}, executionTime.mean: ${this.executionTime.mean}ms`;
147 }
148 /** @internal */
149 clone() {
150 const rv = Object.assign(Object.create(Object.getPrototypeOf(this)), this);
151 for (const key of (0, shared_1.keysOf)(rv)) {
152 if (typeof rv[key] !== "number") {
153 rv[key] = rv[key].clone();
154 }
155 }
156 return rv;
157 }
158}
159exports.FunctionStats = FunctionStats;
160class FunctionExecutionMetrics {
161 constructor() {
162 this.secondMetrics = [];
163 }
164}
165exports.FunctionExecutionMetrics = FunctionExecutionMetrics;
166function filterMessages(messages, kind) {
167 return messages.filter((msg) => msg.kind === kind);
168}
169exports.filterMessages = filterMessages;
170//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJvdmlkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEscUNBQThDO0FBOGFqQyxRQUFBLGNBQWMsR0FBNEI7SUFDbkQsWUFBWSxFQUFFLElBQUk7SUFDbEIsb0JBQW9CLEVBQUUsQ0FBQztJQUN2QixXQUFXLEVBQUUsR0FBRztJQUNoQixXQUFXLEVBQUUsRUFBRTtJQUNmLE9BQU8sRUFBRSxFQUFFO0lBQ1gsT0FBTyxFQUFFLEVBQUU7SUFDWCxJQUFJLEVBQUUsQ0FBQztJQUNQLEdBQUcsRUFBRSxFQUFFO0lBQ1AsRUFBRSxFQUFFLE1BQU07SUFDVixVQUFVLEVBQUUsQ0FBQztJQUNiLFVBQVUsRUFBRSxJQUFJO0lBQ2hCLElBQUksRUFBRSxNQUFNO0lBQ1osV0FBVyxFQUFFLEVBQUU7SUFDZixvQkFBb0IsRUFBRSxJQUFJO0lBQzFCLGVBQWUsRUFBRSxDQUFDO0lBQ2xCLHlCQUF5QixFQUFFLENBQUM7SUFDNUIsT0FBTyxFQUFFLEVBQUU7SUFDWCxjQUFjLEVBQUUsRUFBRTtJQUNsQixxQkFBcUIsRUFBRSxJQUFJO0lBQzNCLFlBQVksRUFBRSxFQUFFO0NBQ25CLENBQUM7QUFnRFcsUUFBQSxxQkFBcUIsR0FBNkI7SUFDM0QsZUFBZSxFQUFFLElBQUk7SUFDckIsWUFBWSxFQUFFLEtBQUs7SUFDbkIsU0FBUyxFQUFFLEVBQUU7Q0FDaEIsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0NHO0FBQ0gsTUFBYSxhQUFhO0lBQTFCO1FBQ0k7OztXQUdHO1FBQ0gsc0JBQWlCLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDckM7Ozs7Ozs7O1dBUUc7UUFDSCx1QkFBa0IsR0FBRyxJQUFJLG1CQUFVLEVBQUUsQ0FBQztRQUN0Qzs7Ozs7V0FLRztRQUNILGtCQUFhLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDakM7OztXQUdHO1FBQ0gsd0JBQW1CLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDdkM7Ozs7Ozs7V0FPRztRQUNILGtCQUFhLEdBQUcsSUFBSSxtQkFBVSxFQUFFLENBQUM7UUFDakM7Ozs7V0FJRztRQUNILHdCQUFtQixHQUFHLElBQUksbUJBQVUsRUFBRSxDQUFDO1FBQ3ZDOzs7V0FHRztRQUNILGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCOztXQUVHO1FBQ0gsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkOzs7O1dBSUc7UUFDSCxZQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ1o7Ozs7V0FJRztRQUNILFdBQU0sR0FBRyxDQUFDLENBQUM7SUFvQmYsQ0FBQztJQW5CRzs7Ozs7T0FLRztJQUNILFFBQVE7UUFDSixPQUFPLGNBQWMsSUFBSSxDQUFDLFNBQVMsY0FBYyxJQUFJLENBQUMsT0FBTyxhQUFhLElBQUksQ0FBQyxNQUFNLHlCQUF5QixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxDQUFDO0lBQzlJLENBQUM7SUFDRCxnQkFBZ0I7SUFDaEIsS0FBSztRQUNELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0UsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFBLGVBQU0sRUFBQyxFQUFFLENBQUMsRUFBRTtZQUMxQixJQUFJLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLFFBQVEsRUFBRTtnQkFDN0IsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQzthQUM3QjtTQUNKO1FBQ0QsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0NBQ0o7QUFuRkQsc0NBbUZDO0FBRUQsTUFBYSx3QkFBd0I7SUFBckM7UUFDSSxrQkFBYSxHQUFpQixFQUFFLENBQUM7SUFDckMsQ0FBQztDQUFBO0FBRkQsNERBRUM7QUFvREQsU0FBZ0IsY0FBYyxDQUFpQixRQUFtQixFQUFFLElBQU87SUFDdkUsT0FBTyxRQUFRLENBQUMsTUFBTSxDQUNsQixDQUFDLEdBQVksRUFBd0MsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUM1RSxDQUFDO0FBQ04sQ0FBQztBQUpELHdDQUlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgd2VicGFjayBmcm9tIFwid2VicGFja1wiO1xuaW1wb3J0IHsgQ29zdFNuYXBzaG90IH0gZnJvbSBcIi4vY29zdFwiO1xuaW1wb3J0IHsga2V5c09mLCBTdGF0aXN0aWNzIH0gZnJvbSBcIi4vc2hhcmVkXCI7XG5pbXBvcnQgeyBDcHVNZWFzdXJlbWVudCwgRnVuY3Rpb25DYWxsIH0gZnJvbSBcIi4vd3JhcHBlclwiO1xuXG4vKipcbiAqIFRoZSB0eXBlIG9mIGFsbCBzdXBwb3J0ZWQgY2xvdWQgcHJvdmlkZXJzLlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgdHlwZSBQcm92aWRlciA9IFwiYXdzXCIgfCBcImdvb2dsZVwiIHwgXCJsb2NhbFwiO1xuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSB7QGxpbmsgQ29tbW9uT3B0aW9ucy5pbmNsdWRlfSBvcHRpb24uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5jbHVkZU9wdGlvbiB7XG4gICAgLyoqXG4gICAgICogVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSBvciBnbG9iIHRvIGFkZCB0byB0aGUgY2xvdWQgZnVuY3Rpb24uXG4gICAgICovXG4gICAgcGF0aDogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIFRoZSB3b3JraW5nIGRpcmVjdG9yeSBpZiBgcGF0aGAgaXMgcmVsYXRpdmUuIERlZmF1bHRzIHRvIGBwcm9jZXNzLmN3ZCgpYC5cbiAgICAgKiBGb3IgZXhhbXBsZSwgaWYgYGN3ZGAgaXMgYFwiZm9vXCJgIGFuZCBgcGF0aGAgaXMgYFwiYmFyXCJgLCB0aGVuIHRoZVxuICAgICAqIGNvbnRlbnRzIG9mIHRoZSBkaXJlY3RvcnkgYGZvby9iYXIvYCB3aWxsIGJlIGFkZGVkIHRvIHRoZSByZW1vdGVcbiAgICAgKiBmdW5jdGlvbiB1bmRlciB0aGUgcGF0aCBgYmFyL2AuXG4gICAgICovXG4gICAgY3dkPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgY29tbW9uIGFjcm9zcyBhbGwgZmFhc3QuanMgcHJvdmlkZXJzLiBVc2VkIGFzIGFyZ3VtZW50IHRvIHtAbGluayBmYWFzdH0uXG4gKiBAcmVtYXJrc1xuICogVGhlcmUgYXJlIGFsc28gbW9yZSBzcGVjaWZpYyBvcHRpb25zIGZvciBlYWNoIHByb3ZpZGVyLiBTZWVcbiAqIHtAbGluayBBd3NPcHRpb25zfSwge0BsaW5rIEdvb2dsZU9wdGlvbnN9LCBhbmQge0BsaW5rIExvY2FsT3B0aW9uc30uXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29tbW9uT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogSWYgdHJ1ZSwgY3JlYXRlIGEgY2hpbGQgcHJvY2VzcyB0byBpc29sYXRlIHVzZXIgY29kZSBmcm9tIGZhYXN0XG4gICAgICogc2NhZmZvbGRpbmcuIERlZmF1bHQ6IHRydWUuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBJZiBhIGNoaWxkIHByb2Nlc3MgaXMgbm90IGNyZWF0ZWQsIGZhYXN0IHJ1bnMgaW4gdGhlIHNhbWUgbm9kZSBpbnN0YW5jZVxuICAgICAqIGFzIHRoZSB1c2VyIGNvZGUgYW5kIG1heSBub3QgZXhlY3V0ZSBpbiBhIHRpbWVseSBmYXNoaW9uIGJlY2F1c2UgdXNlclxuICAgICAqIGNvZGUgbWF5XG4gICAgICoge0BsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9lbi9kb2NzL2d1aWRlcy9kb250LWJsb2NrLXRoZS1ldmVudC1sb29wLyB8IGJsb2NrIHRoZSBldmVudCBsb29wfS5cbiAgICAgKiBDcmVhdGluZyBhIGNoaWxkIHByb2Nlc3MgZm9yIHVzZXIgY29kZSBhbGxvd3MgZmFhc3QuanMgdG8gY29udGludWVcbiAgICAgKiBleGVjdXRpbmcgZXZlbiBpZiB1c2VyIGNvZGUgbmV2ZXIgeWllbGRzLiBUaGlzIHByb3ZpZGVzIGJldHRlclxuICAgICAqIHJlbGlhYmlsaXR5IGFuZCBmdW5jdGlvbmFsaXR5OlxuICAgICAqXG4gICAgICogLSBEZXRlY3QgdGltZW91dCBlcnJvcnMgbW9yZSByZWxpYWJseSwgZXZlbiBpZiB0aGUgZnVuY3Rpb24gZG9lc24ndFxuICAgICAqICAgcmVsaW5xdWlzaCB0aGUgQ1BVLiBOb3QgYXBwbGljYWJsZSB0byBBV1MsIHdoaWNoIHNlbmRzIHNlcGFyYXRlIGZhaWx1cmVcbiAgICAgKiAgIG1lc3NhZ2VzIGluIGNhc2Ugb2YgdGltZW91dC4gU2VlIHtAbGluayBDb21tb25PcHRpb25zLnRpbWVvdXR9LlxuICAgICAqXG4gICAgICogLSBDUFUgbWV0cmljcyB1c2VkIGZvciBkZXRlY3RpbmcgaW52b2NhdGlvbnMgd2l0aCBoaWdoIGxhdGVuY3ksIHdoaWNoIGNhblxuICAgICAqICAgYmUgdXNlZCBmb3IgYXV0b21hdGljYWxseSByZXRyeWluZyBjYWxscyB0byByZWR1Y2UgdGFpbCBsYXRlbmN5LlxuICAgICAqXG4gICAgICogVGhlIGNvc3Qgb2YgY3JlYXRpbmcgYSBjaGlsZCBwcm9jZXNzIGlzIG1haW5seSBpbiB0aGUgbWVtb3J5IG92ZXJoZWFkIG9mXG4gICAgICogY3JlYXRpbmcgYW5vdGhlciBub2RlIHByb2Nlc3MuXG4gICAgICovXG4gICAgY2hpbGRQcm9jZXNzPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIFdoZW4gY2hpbGRQcm9jZXNzIGlzIHRydWUsIHRoZSBjaGlsZCBwcm9jZXNzIHdpbGwgYmUgc3Bhd25lZCB3aXRoIHRoZVxuICAgICAqIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgYXMgdGhlIHNldHRpbmcgZm9yIC0tbWF4LW9sZC1zcGFjZS1zaXplLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogVGhpcyBpcyB1c2VmdWwgaWYgYSBmdW5jdGlvbiByZXF1aXJlcyB0aGUgbm9kZSBwcm9jZXNzIHRvIGxpbWl0IGl0c1xuICAgICAqIG1lbW9yeSBzbyB0aGF0IGFub3RoZXIgc3Bhd25lZCBwcm9jZXNzIChlLmcuIGEgYnJvd3NlciBpbnN0YW5jZSkgY2FuIHVzZVxuICAgICAqIHRoZSByZXN0LlxuICAgICAqIEBwdWJsaWNcbiAgICAgKi9cbiAgICBjaGlsZFByb2Nlc3NNZW1vcnlNYj86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgY29uY3VycmVudCBpbnZvY2F0aW9ucyB0byBhbGxvdy4gRGVmYXVsdDogMTAwLFxuICAgICAqIGV4Y2VwdCBmb3IgdGhlIGBsb2NhbGAgcHJvdmlkZXIsIHdoZXJlIHRoZSBkZWZhdWx0IGlzIDEwLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogVGhlIGNvbmN1cnJlbmN5IGxpbWl0IGFwcGxpZXMgdG8gYWxsIGludm9jYXRpb25zIG9mIGFsbCBvZiB0aGUgZmFhc3RcbiAgICAgKiBmdW5jdGlvbnMgc3VtbWVkIHRvZ2V0aGVyLiBJdCBpcyBub3QgYSBwZXItZnVuY3Rpb24gbGltaXQuIFRvIGFwcGx5IGFcbiAgICAgKiBwZXItZnVuY3Rpb24gbGltaXQsIHVzZSB7QGxpbmsgdGhyb3R0bGV9LiBBIHZhbHVlIG9mIDAgaXMgZXF1aXZhbGVudCB0b1xuICAgICAqIEluZmluaXR5LiBBIHZhbHVlIG9mIDEgZW5zdXJlcyBtdXR1YWxseSBleGNsdXNpdmUgaW52b2NhdGlvbnMuXG4gICAgICovXG4gICAgY29uY3VycmVuY3k/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogQSB1c2VyLXN1cHBsaWVkIGRlc2NyaXB0aW9uIGZvciB0aGlzIGZ1bmN0aW9uLCB3aGljaCBtYXkgbWFrZSBpdCBlYXNpZXJcbiAgICAgKiB0byB0cmFjayBkaWZmZXJlbnQgZnVuY3Rpb25zIHdoZW4gbXVsdGlwbGUgZnVuY3Rpb25zIGFyZSBjcmVhdGVkLlxuICAgICAqL1xuICAgIGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuICAgIC8qKlxuICAgICAqIEV4Y2x1ZGUgYSBzdWJzZXQgb2YgZmlsZXMgaW5jbHVkZWQgYnkge0BsaW5rIENvbW1vbk9wdGlvbnMuaW5jbHVkZX0uXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBUaGUgZXhjbHVzaW9uIGNhbiBiZSBhIGRpcmVjdG9yeSBvciBnbG9iLiBFeGNsdXNpb25zIGFwcGx5IHRvIGFsbCBpbmNsdWRlZFxuICAgICAqIGVudHJpZXMuXG4gICAgICovXG4gICAgZXhjbHVkZT86IHN0cmluZ1tdO1xuICAgIC8qKlxuICAgICAqIFJhdGUgbGltaXQgaW52b2NhdGlvbnMgKGludm9jYXRpb25zL3NlYykuIERlZmF1bHQ6IG5vIHJhdGUgbGltaXQuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBTb21lIHNlcnZpY2VzIGNhbm5vdCBoYW5kbGUgbW9yZSB0aGFuIGEgY2VydGFpbiBudW1iZXIgb2YgcmVxdWVzdHMgcGVyXG4gICAgICogc2Vjb25kLCBhbmQgaXQgaXMgZWFzeSB0byBvdmVyd2hlbG0gdGhlbSB3aXRoIGEgbGFyZ2UgbnVtYmVyIG9mIGNsb3VkXG4gICAgICogZnVuY3Rpb25zLiBTcGVjaWZ5IGEgcmF0ZSBsaW1pdCBpbiBpbnZvY2F0aW9uL3NlY29uZCB0byByZXN0cmljdCBob3dcbiAgICAgKiBmYWFzdC5qcyBpc3N1ZXMgcmVxdWVzdHMuXG4gICAgICovXG4gICAgcmF0ZT86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBFbnZpcm9ubWVudCB2YXJpYWJsZXMgYXZhaWxhYmxlIGR1cmluZyBzZXJ2ZXJsZXNzIGZ1bmN0aW9uIGV4ZWN1dGlvbi5cbiAgICAgKiBEZWZhdWx0OiBcXHtcXH0uXG4gICAgICovXG4gICAgZW52PzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfTtcbiAgICAvKipcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3RvciBtb2RlLiBEZWZhdWx0OiBgXCJhdXRvXCJgLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogR2FyYmFnZSBjb2xsZWN0aW9uIGRlbGV0ZXMgcmVzb3VyY2VzIHRoYXQgd2VyZSBjcmVhdGVkIGJ5IHByZXZpb3VzXG4gICAgICogaW5zdGFudGlhdGlvbnMgb2YgZmFhc3QgdGhhdCB3ZXJlIG5vdCBjbGVhbmVkIHVwIGJ5XG4gICAgICoge0BsaW5rIEZhYXN0TW9kdWxlLmNsZWFudXB9LCBlaXRoZXIgYmVjYXVzZSBpdCB3YXMgbm90IGNhbGxlZCBvciBiZWNhdXNlXG4gICAgICogdGhlIHByb2Nlc3MgdGVybWluYXRlZCBhbmQgZGlkIG5vdCBleGVjdXRlIHRoaXMgY2xlYW51cCBzdGVwLiBJbiBgXCJhdXRvXCJgXG4gICAgICogbW9kZSwgZ2FyYmFnZSBjb2xsZWN0aW9uIG1heSBiZSB0aHJvdHRsZWQgdG8gcnVuIHVwIHRvIG9uY2UgcGVyIGhvdXIgbm9cbiAgICAgKiBtYXR0ZXIgaG93IG1hbnkgZmFhc3QuanMgaW5zdGFuY2VzIGFyZSBjcmVhdGVkLiBJbiBgXCJmb3JjZVwiYCBtb2RlLFxuICAgICAqIGdhcmJhZ2UgY29sbGVjdGlvbiBpcyBydW4gd2l0aG91dCByZWdhcmQgdG8gd2hldGhlciBhbm90aGVyIGdjIGhhc1xuICAgICAqIGFscmVhZHkgYmVlbiBwZXJmb3JtZWQgcmVjZW50bHkuIEluIGBcIm9mZlwiYCBtb2RlLCBnYXJiYWdlIGNvbGxlY3Rpb24gaXNcbiAgICAgKiBza2lwcGVkIGVudGlyZWx5LiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHBlcmZvcm1hbmNlLXNlbnNpdGl2ZSB0ZXN0cywgb3JcbiAgICAgKiBmb3IgbW9yZSBjb250cm9sIG92ZXIgd2hlbiBnYyBpcyBwZXJmb3JtZWQuXG4gICAgICpcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3Rpb24gaXMgY2xvdWQtc3BlY2lmaWMsIGJ1dCBpbiBnZW5lcmFsIGdhcmJhZ2UgY29sbGVjdGlvblxuICAgICAqIHNob3VsZCBub3QgaW50ZXJmZXJlIHdpdGggdGhlIGJlaGF2aW9yIG9yIHBlcmZvcm1hbmNlIG9mIGZhYXN0IGNsb3VkXG4gICAgICogZnVuY3Rpb25zLiBXaGVuIHtAbGluayBGYWFzdE1vZHVsZS5jbGVhbnVwfSBydW5zLCBpdCB3YWl0cyBmb3IgZ2FyYmFnZVxuICAgICAqIGNvbGxlY3Rpb24gdG8gY29tcGxldGUuIFRoZXJlZm9yZSB0aGUgY2xlYW51cCBzdGVwIGNhbiBpbiBzb21lXG4gICAgICogY2lyY3Vtc3RhbmNlcyB0YWtlIGEgc2lnbmlmaWNhbnQgYW1vdW50IG9mIHRpbWUgZXZlbiBhZnRlciBhbGxcbiAgICAgKiBpbnZvY2F0aW9ucyBoYXZlIHJldHVybmVkLlxuICAgICAqXG4gICAgICogSXQgaXMgZ2VuZXJhbGx5IHJlY29tbWVuZGVkIHRvIGxlYXZlIGdhcmJhZ2UgY29sbGVjdGlvbiBpbiBgXCJhdXRvXCJgIG1vZGUsXG4gICAgICogb3RoZXJ3aXNlIGdhcmJhZ2UgcmVzb3VyY2VzIG1heSBhY2N1bXVsYXRlIG92ZXIgdGltZSBhbmQgeW91IHdpbGxcbiAgICAgKiBldmVudHVhbGx5IGhpdCByZXNvdXJjZSBsaW1pdHMgb24geW91ciBhY2NvdW50LlxuICAgICAqXG4gICAgICogQWxzbyBzZWUge0BsaW5rIENvbW1vbk9wdGlvbnMucmV0ZW50aW9uSW5EYXlzfS5cbiAgICAgKi9cbiAgICBnYz86IFwiYXV0b1wiIHwgXCJmb3JjZVwiIHwgXCJvZmZcIjtcbiAgICAvKipcbiAgICAgKiBJbmNsdWRlIGZpbGVzIHRvIG1ha2UgYXZhaWxhYmxlIGluIHRoZSByZW1vdGUgZnVuY3Rpb24uIFNlZVxuICAgICAqIHtAbGluayBJbmNsdWRlT3B0aW9ufS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIEVhY2ggaW5jbHVkZSBlbnRyeSBpcyBhIGRpcmVjdG9yeSBvciBnbG9iIHBhdHRlcm4uIFBhdGhzIGNhbiBiZSBzcGVjaWZpZWRcbiAgICAgKiBhcyByZWxhdGl2ZSBvciBhYnNvbHV0ZSBwYXRocy4gUmVsYXRpdmUgcGF0aHMgYXJlIHJlc29sdmVkIHJlbGF0aXZlIHRvXG4gICAgICogdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnksIG9yIHJlbGF0aXZlIHRvIHRoZSBgY3dkYCBvcHRpb24uXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaW5jbHVkZSBlbnRyeSBpcyBhIGRpcmVjdG9yeSBgXCJmb28vYmFyXCJgLCB0aGUgZGlyZWN0b3J5XG4gICAgICogYFwiLi9mb28vYmFyXCJgIHdpbGwgYmUgYXZhaWxhYmxlIGluIHRoZSBjbG91ZCBmdW5jdGlvbi4gRGlyZWN0b3JpZXMgYXJlXG4gICAgICogcmVjdXJzaXZlbHkgYWRkZWQuXG4gICAgICpcbiAgICAgKiBHbG9iIHBhdHRlcm5zIHVzZSB0aGUgc3ludGF4IG9mXG4gICAgICoge0BsaW5rIGh0dHBzOi8vZ2l0aHViLmNvbS9pc2FhY3Mvbm9kZS1nbG9iIHwgbm9kZSBnbG9ifS5cbiAgICAgKlxuICAgICAqIEFsc28gc2VlIHtAbGluayBDb21tb25PcHRpb25zLmV4Y2x1ZGV9IGZvciBmaWxlIGV4Y2x1c2lvbnMuXG4gICAgICovXG4gICAgaW5jbHVkZT86IChzdHJpbmcgfCBJbmNsdWRlT3B0aW9uKVtdO1xuICAgIC8qKlxuICAgICAqIE1heGltdW0gbnVtYmVyIG9mIHRpbWVzIHRoYXQgZmFhc3Qgd2lsbCByZXRyeSBlYWNoIGludm9jYXRpb24uIERlZmF1bHQ6IDJcbiAgICAgKiAoaW52b2NhdGlvbnMgY2FuIHRoZXJlZm9yZSBiZSBhdHRlbXBlZCAzIHRpbWVzIGluIHRvdGFsKS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFJldHJpZXMgYXJlIGF1dG9tYXRpY2FsbHkgYXR0ZW1wdGVkIGZvciB0cmFuc2llbnQgaW5mcmFzdHJ1Y3R1cmUtbGV2ZWxcbiAgICAgKiBmYWlsdXJlcyBzdWNoIGFzIHJhdGUgbGltaXRzIG9yIG5ldG93cmsgZmFpbHVyZXMuIFVzZXItbGV2ZWwgZXhjZXB0aW9uc1xuICAgICAqIGFyZSBub3QgcmV0cmllZCBhdXRvbWF0aWNhbGx5LiBJbiBhZGRpdGlvbiB0byByZXRyaWVzIHBlcmZvcm1lZCBieSBmYWFzdCxcbiAgICAgKiBzb21lIHByb3ZpZGVycyBhdXRvbWF0aWNhbGx5IGF0dGVtcHQgcmV0cmllcy4gVGhlc2UgYXJlIG5vdCBjb250cm9sbGFibGVcbiAgICAgKiBieSBmYWFzdC4gQnV0IGFzIGEgcmVzdWx0LCB5b3VyIGZ1bmN0aW9uIG1heSBiZSByZXRyaWVkIG1hbnkgbW9yZSB0aW1lc1xuICAgICAqIHRoYW4gdGhpcyBzZXR0aW5nIHN1Z2dlc3RzLlxuICAgICAqL1xuICAgIG1heFJldHJpZXM/OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogTWVtb3J5IGxpbWl0IGZvciBlYWNoIGZ1bmN0aW9uIGluIE1CLiBUaGlzIHNldHRpbmcgaGFzIGFuIGVmZmVjdCBvblxuICAgICAqIHByaWNpbmcuIERlZmF1bHQgdmFyaWVzIGJ5IHByb3ZpZGVyLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogRWFjaCBwcm92aWRlciBoYXMgZGlmZmVyZW50IHNldHRpbmdzIGZvciBtZW1vcnkgc2l6ZSwgYW5kIHBlcmZvcm1hbmNlXG4gICAgICogdmFyaWVzIGRlcGVuZGluZyBvbiB0aGUgc2V0dGluZy4gQnkgZGVmYXVsdCBmYWFzdCBwaWNrcyBhIGxpa2VseSBvcHRpbWFsXG4gICAgICogdmFsdWUgZm9yIGVhY2ggcHJvdmlkZXIuXG4gICAgICpcbiAgICAgKiAtIGF3czogMTcyOE1CXG4gICAgICpcbiAgICAgKiAtIGdvb2dsZTogMTAyNE1CXG4gICAgICpcbiAgICAgKiAtIGxvY2FsOiA1MTJNQiAoaG93ZXZlciwgbWVtb3J5IHNpemUgbGltaXRzIGFyZW4ndCByZWxpYWJsZSBpbiBsb2NhbCBtb2RlLilcbiAgICAgKi9cbiAgICBtZW1vcnlTaXplPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIFNwZWNpZnkgaW52b2NhdGlvbiBtb2RlLiBEZWZhdWx0OiBgXCJhdXRvXCJgLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogTW9kZXMgc3BlY2lmeSBob3cgaW52b2NhdGlvbnMgYXJlIHRyaWdnZXJlZC4gSW4gaHR0cHMgbW9kZSwgdGhlIGZ1bmN0aW9uc1xuICAgICAqIGFyZSBpbnZva2VkIHRocm91Z2ggYW4gaHR0cHMgcmVxdWVzdCBvciB0aGUgcHJvdmlkZXIncyBBUEkuIEluIHF1ZXVlXG4gICAgICogbW9kZSwgYSBwcm92aWRlci1zcGVjaWZpYyBxdWV1ZSBpcyB1c2VkIHRvIGludm9rZSBmdW5jdGlvbnMuIFF1ZXVlIG1vZGVcbiAgICAgKiBhZGRzIGFkZGl0aW9uYWwgbGF0ZW5jeSBhbmQgKHVzdWFsbHkgbmVnbGlnaWJsZSkgY29zdCwgYnV0IG1heSBzY2FsZVxuICAgICAqIGJldHRlciBmb3Igc29tZSBwcm92aWRlcnMuIEluIGF1dG8gbW9kZSB0aGUgYmVzdCBkZWZhdWx0IGlzIGNob3NlbiBmb3JcbiAgICAgKiBlYWNoIHByb3ZpZGVyIGRlcGVuZGluZyBvbiBpdHMgcGFydGljdWxhciBwZXJmb3JtYW5jZSBjaGFyYWN0ZXJpc3RpY3MuXG4gICAgICpcbiAgICAgKiBUaGUgZGVmYXVsdHMgYXJlOlxuICAgICAqXG4gICAgICogLSBhd3M6IGBcImF1dG9cImAgaXMgYFwiaHR0cHNcImAuIEluIGh0dHBzIG1vZGUsIHRoZSBBV1MgU0RLIGFwaVxuICAgICAqICAgaXMgdXNlZCB0byBpbnZva2UgZnVuY3Rpb25zLiBJbiBxdWV1ZSBtb2RlLCBhbiBBV1MgU05TIHRvcGljIGlzIGNyZWF0ZWRcbiAgICAgKiAgIGFuZCB0cmlnZ2VycyBpbnZvY2F0aW9ucy4gVGhlIEFXUyBBUEkgR2F0ZXdheSBzZXJ2aWNlIGlzIG5ldmVyIHVzZWQgYnlcbiAgICAgKiAgIGZhYXN0LCBhcyBpdCBpbmN1cnMgYSBoaWdoZXIgY29zdCBhbmQgaXMgbm90IG5lZWRlZCB0byB0cmlnZ2VyXG4gICAgICogICBpbnZvY2F0aW9ucy5cbiAgICAgKlxuICAgICAqIC0gZ29vZ2xlOiBgXCJhdXRvXCJgIGlzIGBcImh0dHBzXCJgLiBJbiBodHRwcyBtb2RlLCBhIFBVVCByZXF1ZXN0IGlzIG1hZGUgdG9cbiAgICAgKiAgIGludm9rZSB0aGUgY2xvdWQgZnVuY3Rpb24uIEluIHF1ZXVlIG1vZGUsIGEgUHViU3ViIHRvcGljIGlzIGNyZWF0ZWQgdG9cbiAgICAgKiAgIGludm9rZSBmdW5jdGlvbnMuXG4gICAgICpcbiAgICAgKiAtIGxvY2FsOiBUaGUgbG9jYWwgcHJvdmlkZXIgaWdub3JlcyB0aGUgbW9kZSBzZXR0aW5nIGFuZCBhbHdheXMgdXNlcyBhblxuICAgICAqICAgaW50ZXJuYWwgYXN5bmNocm9ub3VzIHF1ZXVlIHRvIHNjaGVkdWxlIGNhbGxzLlxuICAgICAqXG4gICAgICogU2l6ZSBsaW1pdHMgYXJlIGFmZmVjdGVkIGJ5IHRoZSBjaG9pY2Ugb2YgbW9kZS4gT24gQVdTIHRoZSBsaW1pdCBpcyAyNTZrYlxuICAgICAqIGZvciBhcmd1bWVudHMgYW5kIHJldHVybiB2YWx1ZXMgaW4gYFwicXVldWVcImAgbW9kZSwgYW5kIDZNQiBmb3IgYFwiaHR0cHNcImBcbiAgICAgKiBtb2RlLiBGb3IgR29vZ2xlIHRoZSBsaW1pdCBpcyAxME1CIHJlZ2FyZGxlc3Mgb2YgbW9kZS4gSW4gTG9jYWwgbW9kZVxuICAgICAqIG1lc3NhZ2VzIGFyZSBzZW50IHZpYSBub2RlJ3MgSVBDIGFuZCBhcmUgc3ViamVjdCB0byBPUyBJUEMgbGltaXRzLlxuICAgICAqXG4gICAgICogTm90ZSB0aGF0IG5vIG1hdHRlciB3aGljaCBtb2RlIGlzIHNlbGVjdGVkLCBmYWFzdC5qcyBhbHdheXMgY3JlYXRlcyBhXG4gICAgICogcXVldWUgZm9yIHNlbmRpbmcgYmFjayBpbnRlcm1lZGlhdGUgcmVzdWx0cyBmb3IgYm9va2VlcGluZyBhbmRcbiAgICAgKiBwZXJmb3JtYW5jZSBtb25pdG9yaW5nLlxuICAgICAqL1xuICAgIG1vZGU/OiBcImh0dHBzXCIgfCBcInF1ZXVlXCIgfCBcImF1dG9cIjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IGEgcGFja2FnZS5qc29uIGZpbGUgdG8gaW5jbHVkZSB3aXRoIHRoZSBjb2RlIHBhY2thZ2UuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBCeSBkZWZhdWx0LCBmYWFzdC5qcyB3aWxsIHVzZSB3ZWJwYWNrIHRvIGJ1bmRsZSBkZXBlbmRlbmNpZXMgeW91ciByZW1vdGVcbiAgICAgKiBtb2R1bGUgaW1wb3J0cy4gSW4gbm9ybWFsIHVzYWdlIHRoZXJlIGlzIG5vIG5lZWQgdG8gc3BlY2lmeSBhIHNlcGFyYXRlXG4gICAgICogcGFja2FnZS5qc29uLCBhcyB3ZWJwYWNrIHdpbGwgc3RhdGljYWxseSBhbmFseXplIHlvdXIgaW1wb3J0cyBhbmRcbiAgICAgKiBkZXRlcm1pbmUgd2hpY2ggZmlsZXMgdG8gYnVuZGxlLlxuICAgICAqXG4gICAgICogSG93ZXZlciwgdGhlcmUgYXJlIHNvbWUgdXNlIGNhc2VzIHdoZXJlIHRoaXMgaXMgbm90IGVub3VnaC4gRm9yIGV4YW1wbGUsXG4gICAgICogc29tZSBkZXBlbmRlbmNpZXMgY29udGFpbiBuYXRpdmUgY29kZSBjb21waWxlZCBkdXJpbmcgaW5zdGFsbGF0aW9uLCBhbmRcbiAgICAgKiB3ZWJwYWNrIGNhbm5vdCBidW5kbGUgdGhlc2UgbmF0aXZlIG1vZHVsZXMuIHN1Y2ggYXMgZGVwZW5kZW5jaWVzIHdpdGhcbiAgICAgKiBuYXRpdmUgY29kZS4gIG9yIGFyZSBzcGVjaWZpY2FsbHkgbm90IGRlc2lnbmVkIHRvIHdvcmsgd2l0aCB3ZWJwYWNrLiBJblxuICAgICAqIHRoZXNlIGNhc2VzLCB5b3UgY2FuIGNyZWF0ZSBhIHNlcGFyYXRlIGBwYWNrYWdlLmpzb25gIGZvciB0aGVzZVxuICAgICAqIGRlcGVuZGVuY2llcyBhbmQgcGFzcyB0aGUgZmlsZW5hbWUgYXMgdGhlIGBwYWNrYWdlSnNvbmAgb3B0aW9uLiBJZlxuICAgICAqIGBwYWNrYWdlSnNvbmAgaXMgYW4gYG9iamVjdGAsIGl0IGlzIGFzc3VtZWQgdG8gYmUgYSBwYXJzZWQgSlNPTiBvYmplY3RcbiAgICAgKiB3aXRoIHRoZSBzYW1lIHN0cnVjdHVyZSBhcyBhIHBhY2thZ2UuanNvbiBmaWxlICh1c2VmdWwgZm9yIHNwZWNpZnlpbmcgYVxuICAgICAqIHN5bnRoZXRpYyBgcGFja2FnZS5qc29uYCBkaXJlY3RseSBpbiBjb2RlKS5cbiAgICAgKlxuICAgICAqIFRoZSB3YXkgdGhlIGBwYWNrYWdlSnNvbmAgaXMgaGFuZGxlZCB2YXJpZXMgYnkgcHJvdmlkZXI6XG4gICAgICpcbiAgICAgKiAtIGxvY2FsOiBSdW5zIGBucG0gaW5zdGFsbGAgaW4gYSB0ZW1wb3JhcnkgZGlyZWN0b3J5IGl0IHByZXBhcmVzIGZvciB0aGVcbiAgICAgKiAgIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogLSBnb29nbGU6IHVzZXMgR29vZ2xlIENsb3VkIEZ1bmN0aW9uJ3NcbiAgICAgKiAgIHtAbGluayBodHRwczovL2Nsb3VkLmdvb2dsZS5jb20vZnVuY3Rpb25zL2RvY3Mvd3JpdGluZy9zcGVjaWZ5aW5nLWRlcGVuZGVuY2llcy1ub2RlanMgfCBuYXRpdmUgc3VwcG9ydCBmb3IgcGFja2FnZS5qc29ufS5cbiAgICAgKlxuICAgICAqIC0gYXdzOiBSZWN1cnNpdmVseSBjYWxscyBmYWFzdC5qcyB0byBydW4gYG5wbSBpbnN0YWxsYCBpbnNpZGUgYSBzZXBhcmF0ZVxuICAgICAqICAgbGFtYmRhIGZ1bmN0aW9uIHNwZWNpZmljYWxseSBjcmVhdGVkIGZvciB0aGlzIHB1cnBvc2UuIEZhYXN0LmpzIHVzZXNcbiAgICAgKiAgIGxhbWJkYSB0byBpbnN0YWxsIGRlcGVuZGVuY2llcyB0byBlbnN1cmUgdGhhdCBuYXRpdmUgZGVwZW5kZW5jaWVzIGFyZVxuICAgICAqICAgY29tcGlsZWQgaW4gYW4gZW52aXJvbm1lbnQgdGhhdCBjYW4gcHJvZHVjZSBiaW5hcmllcyBsaW5rZWQgYWdhaW5zdFxuICAgICAqICAgbGFtYmRhJ3NcbiAgICAgKiAgIHtAbGluayBodHRwczovL2F3cy5hbWF6b24uY29tL2Jsb2dzL2NvbXB1dGUvcnVubmluZy1leGVjdXRhYmxlcy1pbi1hd3MtbGFtYmRhLyB8IGV4ZWN1dGlvbiBlbnZpcm9ubWVudH0uXG4gICAgICogICBQYWNrYWdlcyBhcmUgc2F2ZWQgaW4gYSBMYW1iZGEgTGF5ZXIuXG4gICAgICpcbiAgICAgKiBGb3IgQVdTLCBpZiB7QGxpbmsgQ29tbW9uT3B0aW9ucy51c2VEZXBlbmRlbmN5Q2FjaGluZ30gaXMgYHRydWVgICh3aGljaFxuICAgICAqIGlzIHRoZSBkZWZhdWx0KSwgdGhlbiB0aGUgTGFtYmRhIExheWVyIGNyZWF0ZWQgd2lsbCBiZSByZXVzZWQgaW4gZnV0dXJlXG4gICAgICogZnVuY3Rpb24gY3JlYXRpb24gcmVxdWVzdHMgaWYgdGhlIGNvbnRlbnRzIG9mIGBwYWNrYWdlSnNvbmAgYXJlIHRoZSBzYW1lLlxuICAgICAqXG4gICAgICogVGhlIGBGQUFTVF9QQUNLQUdFX0RJUmAgZW52aXJvbm1lbnQgdmFyaWFibGUgY2FuIGJlIHVzZWZ1bCBmb3IgZGVidWdnaW5nXG4gICAgICogYHBhY2thZ2VKc29uYCBpc3N1ZXMuXG4gICAgICovXG4gICAgcGFja2FnZUpzb24/OiBzdHJpbmcgfCBvYmplY3Q7XG4gICAgLyoqXG4gICAgICogQ2FjaGUgaW5zdGFsbGVkIGRlcGVuZGVuY2llcyBmcm9tIHtAbGluayBDb21tb25PcHRpb25zLnBhY2thZ2VKc29ufS4gT25seVxuICAgICAqIGFwcGxpZXMgdG8gQVdTLiBEZWZhdWx0OiB0cnVlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogSWYgYHVzZURlcGVuZGVuY3lDYWNoaW5nYCBpcyBgdHJ1ZWAsIFRoZSByZXN1bHRpbmcgYG5vZGVfbW9kdWxlc2AgZm9sZGVyXG4gICAgICogaXMgY2FjaGVkIGluIGEgTGFtYmRhIExheWVyIHdpdGggdGhlIG5hbWUgYGZhYXN0LSR7a2V5fWAsIHdoZXJlIGBrZXlgIGlzXG4gICAgICogdGhlIFNIQTEgaGFzaCBvZiB0aGUgYHBhY2thZ2VKc29uYCBjb250ZW50cy4gVGhlc2UgY2FjaGUgZW50cmllcyBhcmVcbiAgICAgKiByZW1vdmVkIGJ5IGdhcmJhZ2UgY29sbGVjdGlvbiwgYnkgZGVmYXVsdCBhZnRlciAyNGguIFVzaW5nIGNhY2hpbmdcbiAgICAgKiByZWR1Y2VzIHRoZSBuZWVkIHRvIGluc3RhbGwgYW5kIHVwbG9hZCBkZXBlbmRlbmNpZXMgZXZlcnkgdGltZSBhIGZ1bmN0aW9uXG4gICAgICogaXMgY3JlYXRlZC4gVGhpcyBpcyBpbXBvcnRhbnQgZm9yIEFXUyBiZWNhdXNlIGl0IGNyZWF0ZXMgYW4gZW50aXJlbHlcbiAgICAgKiBzZXBhcmF0ZSBsYW1iZGEgZnVuY3Rpb24gdG8gaW5zdGFsbCBkZXBlbmRlbmNpZXMgcmVtb3RlbHksIHdoaWNoIGNhblxuICAgICAqIHN1YnN0YW50aWFsbHkgaW5jcmVhc2UgZnVuY3Rpb24gZGVwbG95bWVudCB0aW1lLlxuICAgICAqXG4gICAgICogSWYgYHVzZURlcGVuZGVuY3lDYWNoaW5nYCBpcyBmYWxzZSwgdGhlIGxhbWJkYSBsYXllciBpcyBjcmVhdGVkIHdpdGggdGhlXG4gICAgICogc2FtZSBuYW1lIGFzIHRoZSBsYW1iZGEgZnVuY3Rpb24sIGFuZCB0aGVuIGlzIGRlbGV0ZWQgd2hlbiBjbGVhbnVwIGlzXG4gICAgICogcnVuLlxuICAgICAqL1xuICAgIHVzZURlcGVuZGVuY3lDYWNoaW5nPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBTcGVjaWZ5IGhvdyBtYW55IGRheXMgdG8gd2FpdCBiZWZvcmUgcmVjbGFpbWluZyBjbG91ZCBnYXJiYWdlLiBEZWZhdWx0OlxuICAgICAqIDEuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBHYXJiYWdlIGNvbGxlY3Rpb24gb25seSBkZWxldGVzIHJlc291cmNlcyBhZnRlciB0aGV5IGFnZSBiZXlvbmQgYSBjZXJ0YWluXG4gICAgICogbnVtYmVyIG9mIGRheXMuIFRoaXMgb3B0aW9uIHNwZWNpZmllcyBob3cgbWFueSBkYXlzIG9sZCBhIHJlc291cmNlIG5lZWRzXG4gICAgICogdG8gYmUgYmVmb3JlIGJlaW5nIGNvbnNpZGVyZWQgZ2FyYmFnZSBieSB0aGUgY29sbGVjdG9yLiBOb3RlIHRoYXQgdGhpc1xuICAgICAqIHNldHRpbmcgaXMgbm90IHJlY29yZGVkIHdoZW4gdGhlIHJlc291cmNlcyBhcmUgY3JlYXRlZC4gRm9yIGV4YW1wbGUsXG4gICAgICogc3VwcG9zZSB0aGlzIGlzIHRoZSBzZXF1ZW5jZSBvZiBldmVudHM6XG4gICAgICpcbiAgICAgKiAtIERheSAwOiBgZmFhc3QoKWAgaXMgY2FsbGVkIHdpdGggYHJldGVudGlvbkluRGF5c2Agc2V0IHRvIDUuIFRoZW4sIHRoZVxuICAgICAqICAgZnVuY3Rpb24gY3Jhc2hlcyAob3Igb21pdHMgdGhlIGNhbGwgdG8ge0BsaW5rIEZhYXN0TW9kdWxlLmNsZWFudXB9KS5cbiAgICAgKlxuICAgICAqIC0gRGF5IDE6IGBmYWFzdCgpYCBpcyBjYWxsZWQgd2l0aCBgcmV0ZW50aW9uSW5EYXlzYCBzZXQgdG8gMS5cbiAgICAgKlxuICAgICAqIEluIHRoaXMgc2VxdWVuY2Ugb2YgZXZlbnRzLCBvbiBEYXkgMCB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IgcnVucyBhbmRcbiAgICAgKiByZW1vdmVzIHJlc291cmNlcyB3aXRoIGFnZSBvbGRlciB0aGFuIDUgZGF5cy4gVGhlbiB0aGUgZnVuY3Rpb24gbGVhdmVzXG4gICAgICogbmV3IGdhcmJhZ2UgYmVoaW5kIGJlY2F1c2UgaXQgY3Jhc2hlZCBvciBkaWQgbm90IGNvbXBsZXRlIGNsZWFudXAuIE9uIERheVxuICAgICAqIDEsIHRoZSBnYXJiYWdlIGNvbGxlY3RvciBydW5zIGFuZCBkZWxldGVzIHJlc291cmNlcyBhdCBsZWFzdCAxIGRheSBvbGQsXG4gICAgICogd2hpY2ggaW5jbHVkZXMgZ2FyYmFnZSBsZWZ0IGJlaGluZCBmcm9tIERheSAwIChiYXNlZCBvbiB0aGUgY3JlYXRpb25cbiAgICAgKiB0aW1lc3RhbXAgb2YgdGhlIHJlc291cmNlcykuIFRoaXMgZGVsZXRpb24gb2NjdXJzIGV2ZW4gdGhvdWdoIHJldGVudGlvblxuICAgICAqIHdhcyBzZXQgdG8gNSBkYXlzIHdoZW4gcmVzb3VyY2VzIHdlcmUgY3JlYXRlZCBvbiBEYXkgMC5cbiAgICAgKlxuICAgICAqIE9uIEdvb2dsZSwgbG9ncyBhcmUgcmV0YWluZWQgYWNjb3JkaW5nIHRvIEdvb2dsZSdzIGRlZmF1bHQgZXhwaXJhdGlvblxuICAgICAqIHBvbGljeSAoMzAgZGF5cykgaW5zdGVhZCBvZiBiZWluZyBkZWxldGVkIGJ5IGdhcmJhZ2UgY29sbGVjdGlvbi5cbiAgICAgKlxuICAgICAqIE5vdGUgdGhhdCBpZiBgcmV0ZW50aW9uSW5EYXlzYCBpcyBzZXQgdG8gMCwgZ2FyYmFnZSBjb2xsZWN0aW9uIHdpbGxcbiAgICAgKiByZW1vdmUgYWxsIHJlc291cmNlcywgZXZlbiBvbmVzIHRoYXQgbWF5IGJlIGluIHVzZSBieSBvdGhlciBydW5uaW5nIGZhYXN0XG4gICAgICogaW5zdGFuY2VzLiBOb3QgcmVjb21tZW5kZWQuXG4gICAgICpcbiAgICAgKiBTZWUge0BsaW5rIENvbW1vbk9wdGlvbnMuZ2N9LlxuICAgICAqL1xuICAgIHJldGVudGlvbkluRGF5cz86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBSZWR1Y2UgdGFpbCBsYXRlbmN5IGJ5IHJldHJ5aW5nIGludm9jYXRpb25zIHRoYXQgdGFrZSBzdWJzdGFudGlhbGx5XG4gICAgICogbG9uZ2VyIHRoYW4gb3RoZXIgaW52b2NhdGlvbnMgb2YgdGhlIHNhbWUgZnVuY3Rpb24uIERlZmF1bHQ6IDMuXG4gICAgICogQHJlbWFya3NcbiAgICAgKiBmYWFzdC5qcyBhdXRvbWF0aWNhbGx5IG1lYXN1cmVzIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gKM+DKSBvZlxuICAgICAqIHRoZSB0aW1lIHRha2VuIGJ5IGludm9jYXRpb25zIG9mIGVhY2ggZnVuY3Rpb24uIFJldHJpZXMgYXJlIGF0dGVtcHRlZFxuICAgICAqIHdoZW4gdGhlIHRpbWUgZm9yIGFuIGludm9jYXRpb24gZXhjZWVkcyB0aGUgbWVhbiB0aW1lIGJ5IGEgY2VydGFpblxuICAgICAqIHRocmVzaG9sZC4gYHNwZWN1bGF0aXZlUmV0cnlUaHJlc2hvbGRgIHNwZWNpZmllcyBob3cgbWFueSBtdWx0aXBsZXMgb2Ygz4NcbiAgICAgKiBhbiBpbnZvY2F0aW9uIG5lZWRzIHRvIGV4Y2VlZCB0aGUgbWVhbiBmb3IgYSBnaXZlbiBmdW5jdGlvbiBiZWZvcmUgcmV0cnlcbiAgICAgKiBpcyBhdHRlbXB0ZWQuXG4gICAgICpcbiAgICAgKiBUaGUgZGVmYXVsdCB2YWx1ZSBvZiDPgyBpcyAzLiBUaGlzIG1lYW5zIGEgY2FsbCB0byBhIGZ1bmN0aW9uIGlzIHJldHJpZWRcbiAgICAgKiB3aGVuIHRoZSB0aW1lIHRvIGV4ZWN1dGUgZXhjZWVkcyB0aHJlZSBzdGFuZGFyZCBkZXZpYXRpb25zIGZyb20gdGhlIG1lYW5cbiAgICAgKiBvZiBhbGwgcHJpb3IgZXhlY3V0aW9ucyBvZiB0aGUgc2FtZSBmdW5jdGlvbi5cbiAgICAgKlxuICAgICAqIFRoaXMgZmVhdHVyZSBpcyBleHBlcmltZW50YWwuXG4gICAgICogQGJldGFcbiAgICAgKi9cbiAgICBzcGVjdWxhdGl2ZVJldHJ5VGhyZXNob2xkPzogbnVtYmVyO1xuICAgIC8qKlxuICAgICAqIEV4ZWN1dGlvbiB0aW1lIGxpbWl0IGZvciBlYWNoIGludm9jYXRpb24sIGluIHNlY29uZHMuIERlZmF1bHQ6IDYwLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogRWFjaCBwcm92aWRlciBoYXMgYSBtYXhpbXVtIHRpbWUgbGltaXQgZm9yIGhvdyBsb25nIGludm9jYXRpb25zIGNhbiBydW5cbiAgICAgKiBiZWZvcmUgYmVpbmcgYXV0b21hdGljYWxseSB0ZXJtaW5hdGVkIChvciBmcm96ZW4pLiBUaGUgZm9sbG93aW5nIGFyZSB0aGVcbiAgICAgKiBtYXhpbXVtIHRpbWUgbGltaXRzIGFzIG9mIEZlYnJ1YXJ5IDIwMTk6XG4gICAgICpcbiAgICAgKiAtIGF3czpcbiAgICAgKiAgIHtAbGluayBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vbGFtYmRhL2xhdGVzdC9kZy9saW1pdHMuaHRtbCB8IDE1IG1pbnV0ZXN9XG4gICAgICpcbiAgICAgKiAtIGdvb2dsZToge0BsaW5rIGh0dHBzOi8vY2xvdWQuZ29vZ2xlLmNvbS9mdW5jdGlvbnMvcXVvdGFzIHwgOSBtaW51dGVzfVxuICAgICAqXG4gICAgICogLSBsb2NhbDogdW5saW1pdGVkXG4gICAgICpcbiAgICAgKiBGYWFzdC5qcyBoYXMgYSBwcm9hY3RpdmUgdGltZW91dCBkZXRlY3Rpb24gZmVhdHVyZS4gSXQgYXV0b21hdGljYWxseVxuICAgICAqIGF0dGVtcHRzIHRvIGRldGVjdCB3aGVuIHRoZSB0aW1lIGxpbWl0IGlzIGFib3V0IHRvIGJlIHJlYWNoZWQgYW5kXG4gICAgICogcHJvYWN0aXZlbHkgc2VuZHMgYSB0aW1lb3V0IGV4Y2VwdGlvbi4gRmFhc3QgZG9lcyB0aGlzIGJlY2F1c2Ugbm90IGFsbFxuICAgICAqIHByb3ZpZGVycyByZWxpYWJseSBzZW5kIHRpbWVseSBmZWVkYmFjayB3aGVuIHRpbWVvdXRzIG9jY3VyLCBsZWF2aW5nXG4gICAgICogZGV2ZWxvcGVycyB0byBsb29rIHRocm91Z2ggY2xvdWQgbG9ncy4gSW4gZ2VuZXJhbCBmYWFzdC5qcycgdGltZW91dCB3aWxsXG4gICAgICogYmUgdXAgdG8gNXMgZWFybGllciB0aGFuIHRoZSB0aW1lb3V0IHNwZWNpZmllZCwgaW4gb3JkZXIgdG8gZ2l2ZSB0aW1lIHRvXG4gICAgICogYWxsb3cgZmFhc3QuanMgdG8gc2VuZCBhIHRpbWVvdXQgbWVzc2FnZS4gUHJvYWN0aXZlIHRpbWVvdXQgZGV0ZWN0aW9uXG4gICAgICogb25seSB3b3JrcyB3aXRoIHtAbGluayBDb21tb25PcHRpb25zLmNoaWxkUHJvY2Vzc30gc2V0IHRvIGB0cnVlYCAodGhlXG4gICAgICogZGVmYXVsdCkuXG4gICAgICovXG4gICAgdGltZW91dD86IG51bWJlcjtcbiAgICAvKipcbiAgICAgKiBFeHRyYSB3ZWJwYWNrIG9wdGlvbnMgdG8gdXNlIHRvIGJ1bmRsZSB0aGUgY29kZSBwYWNrYWdlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogQnkgZGVmYXVsdCwgZmFhc3QuanMgdXNlcyB3ZWJwYWNrIHRvIGJ1bmRsZSB0aGUgY29kZSBwYWNrYWdlLiBXZWJwYWNrXG4gICAgICogYXV0b21hdGljYWxseSBoYW5kbGVzIGZpbmRpbmcgYW5kIGJ1bmRsaW5nIGRlcGVuZGVuY2llcywgYWRkaW5nIHNvdXJjZVxuICAgICAqIG1hcHBpbmdzLCBldGMuIElmIHlvdSBuZWVkIHNwZWNpYWxpemVkIGJ1bmRsaW5nLCB1c2UgdGhpcyBvcHRpb24gdG8gYWRkXG4gICAgICogb3Igb3ZlcnJpZGUgdGhlIGRlZmF1bHQgd2VicGFjayBjb25maWd1cmF0aW9uLiBUaGUgbGlicmFyeVxuICAgICAqIHtAbGluayBodHRwczovL2dpdGh1Yi5jb20vc3Vydml2ZWpzL3dlYnBhY2stbWVyZ2UgfCB3ZWJwYWNrLW1lcmdlfSBpc1xuICAgICAqIHVzZWQgdG8gY29tYmluZSBjb25maWd1cmF0aW9ucy5cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBjb25zdCBjb25maWc6IHdlYnBhY2suQ29uZmlndXJhdGlvbiA9IG1lcmdlKHtcbiAgICAgKiAgICAgZW50cnksXG4gICAgICogICAgIG1vZGU6IFwiZGV2ZWxvcG1lbnRcIixcbiAgICAgKiAgICAgb3V0cHV0OiB7XG4gICAgICogICAgICAgICBwYXRoOiBcIi9cIixcbiAgICAgKiAgICAgICAgIGZpbGVuYW1lOiBvdXRwdXRGaWxlbmFtZSxcbiAgICAgKiAgICAgICAgIGxpYnJhcnlUYXJnZXQ6IFwiY29tbW9uanMyXCJcbiAgICAgKiAgICAgfSxcbiAgICAgKiAgICAgdGFyZ2V0OiBcIm5vZGVcIixcbiAgICAgKiAgICAgcmVzb2x2ZUxvYWRlcjogeyBtb2R1bGVzOiBbX19kaXJuYW1lLCBgJHtfX2Rpcm5hbWV9L2Rpc3R9YF0gfSxcbiAgICAgKiAgICAgbm9kZTogeyBnbG9iYWw6IHRydWUsIF9fZGlybmFtZTogZmFsc2UsIF9fZmlsZW5hbWU6IGZhbHNlIH1cbiAgICAgKiAgIH0sXG4gICAgICogICB3ZWJwYWNrT3B0aW9ucyk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBUYWtlIGNhcmUgd2hlbiBzZXR0aW5nIHRoZSB2YWx1ZXMgb2YgYGVudHJ5YCwgYG91dHB1dGAsIG9yXG4gICAgICogYHJlc29sdmVMb2FkZXJgLiBJZiB0aGVzZSBvcHRpb25zIGFyZSBvdmVyd3JpdHRlbiwgZmFhc3QuanMgbWF5IGZhaWwgdG9cbiAgICAgKiBidW5kbGUgeW91ciBjb2RlLiBJbiBwYXJ0aWN1bGFyLCBzZXR0aW5nIGBlbnRyeWAgdG8gYW4gYXJyYXkgdmFsdWUgd2lsbFxuICAgICAqIGhlbHAgYHdlYnBhY2stbWVyZ2VgIHRvIGNvbmNhdGVuYXRlIGl0cyB2YWx1ZSBpbnN0ZWFkIG9mIHJlcGxhY2luZyB0aGVcbiAgICAgKiB2YWx1ZSB0aGF0IGZhYXN0LmpzIGluc2VydHMgZm9yIHlvdS5cbiAgICAgKlxuICAgICAqIERlZmF1bHQ6XG4gICAgICpcbiAgICAgKiAtIGF3czogYHsgZXh0ZXJuYWxzOiBbbmV3IFJlZ0V4cChcIl5hd3Mtc2RrLz9cIildIH1gLiBJbiB0aGUgbGFtYmRhXG4gICAgICogICBlbnZpcm9ubWVudCBgXCJhd3Mtc2RrXCJgIGlzIGF2YWlsYWJsZSBpbiB0aGUgYW1iaWVudCBlbnZpcm9ubWVudCBhbmRcbiAgICAgKiAgIGRvZXMgbm90IG5lZWQgdG8gYmUgYnVuZGxlZC5cbiAgICAgKlxuICAgICAqIC0gb3RoZXIgcHJvdmlkZXJzOiBge31gXG4gICAgICpcbiAgICAgKiBUaGUgYEZBQVNUX1BBQ0tBR0VfRElSYCBlbnZpcm9ubWVudCB2YXJpYWJsZSBjYW4gYmUgdXNlZnVsIGZvciBkZWJ1Z2dpbmdcbiAgICAgKiB3ZWJwYWNrIGlzc3Vlcy5cbiAgICAgKi9cbiAgICB3ZWJwYWNrT3B0aW9ucz86IHdlYnBhY2suQ29uZmlndXJhdGlvbjtcbiAgICAvKipcbiAgICAgKiBDaGVjayBhcmd1bWVudHMgYW5kIHJldHVybiB2YWx1ZXMgZnJvbSBjbG91ZCBmdW5jdGlvbnMgYXJlIHNlcmlhbGl6YWJsZVxuICAgICAqIHdpdGhvdXQgbG9zaW5nIGluZm9ybWF0aW9uLiBEZWZhdWx0OiB0cnVlLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogQXJndW1lbnRzIHRvIGNsb3VkIGZ1bmN0aW9ucyBhcmUgYXV0b21hdGljYWxseSBzZXJpYWxpemVkIHdpdGhcbiAgICAgKiBgSlNPTi5zdHJpbmdpZnlgIHdpdGggYSBjdXN0b20gcmVwbGFjZXIgdGhhdCBoYW5kbGVzIGJ1aWx0LWluIEphdmFTY3JpcHRcbiAgICAgKiB0eXBlcyBzdWNoIGFzIGBEYXRlYCBhbmQgYEJ1ZmZlcmAuIFJldHVybiB2YWx1ZXMgZ28gdGhyb3VnaCB0aGUgc2FtZVxuICAgICAqIHByb2Nlc3MuIFNvbWUgSmF2YVNjcmlwdCBvYmplY3RzIGNhbm5vdCBiZSBzZXJpYWxpemVkLiBCeSBkZWZhdWx0XG4gICAgICogYHZhbGlkYXRlU2VyaWFsaXphdGlvbmAgd2lsbCB2ZXJpZnkgdGhhdCBldmVyeSBhcmd1bWVudCBhbmQgcmV0dXJuIHZhbHVlXG4gICAgICogY2FuIGJlIHNlcmlhbGl6ZWQgYW5kIGRlc2VyaWFsaXplZCB3aXRob3V0IGxvc2luZyBpbmZvcm1hdGlvbi4gQVxuICAgICAqIGBGYWFzdEVycm9yYCB3aWxsIGJlIHRocm93biBpZiBmYWFzdC5qcyBkZXRlY3RzIGEgcHJvYmxlbSBhY2NvcmRpbmcgdG9cbiAgICAgKiB0aGUgZm9sbG93aW5nIHByb2NlZHVyZTpcbiAgICAgKlxuICAgICAqIDEuIFNlcmlhbGl6ZSBhcmd1bWVudHMgYW5kIHJldHVybiB2YWx1ZXMgd2l0aCBgSlNPTi5zdHJpbmdpZnlgIHVzaW5nIGFcbiAgICAgKiAgICBzcGVjaWFsIGByZXBsYWNlcmAgZnVuY3Rpb24uXG4gICAgICpcbiAgICAgKiAyLiBEZXNlcmlhbGl6ZSB0aGUgdmFsdWVzIHdpdGggYEpTT04ucGFyc2VgIHdpdGggYSBzcGVjaWFsIGByZXZpdmVyYFxuICAgICAqICAgIGZ1bmN0aW9uLlxuICAgICAqXG4gICAgICogMy4gVXNlXG4gICAgICogICAge0BsaW5rIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvYXNzZXJ0Lmh0bWwjYXNzZXJ0X2Fzc2VydF9kZWVwc3RyaWN0ZXF1YWxfYWN0dWFsX2V4cGVjdGVkX21lc3NhZ2UgfCBhc3NlcnQuZGVlcFN0cmluZ0VxdWFsfVxuICAgICAqICAgIHRvIGNvbXBhcmUgdGhlIG9yaWdpbmFsIG9iamVjdCB3aXRoIHRoZSBkZXNlcmlhbGl6ZWQgb2JqZWN0IGZyb20gc3RlcFxuICAgICAqICAgIDIuXG4gICAgICpcbiAgICAgKiBUaGVyZSBpcyBzb21lIG92ZXJoZWFkIHRvIHRoaXMgcHJvY2VzcyBiZWNhdXNlIGVhY2ggYXJndW1lbnQgaXNcbiAgICAgKiBzZXJpYWxpemVkIGFuZCBkZXNlcmlhbGl6ZWQsIHdoaWNoIGNhbiBiZSBjb3N0bHkgaWYgYXJndW1lbnRzIG9yIHJldHVyblxuICAgICAqIHZhbHVlcyBhcmUgbGFyZ2UuXG4gICAgICovXG4gICAgdmFsaWRhdGVTZXJpYWxpemF0aW9uPzogYm9vbGVhbjtcbiAgICAvKipcbiAgICAgKiBEZWJ1Z2dpbmcgb3V0cHV0IG9wdGlvbnMuXG4gICAgICogQGludGVybmFsXG4gICAgICovXG4gICAgZGVidWdPcHRpb25zPzogeyBba2V5OiBzdHJpbmddOiBib29sZWFuIH07XG59XG5cbmV4cG9ydCBjb25zdCBjb21tb25EZWZhdWx0czogUmVxdWlyZWQ8Q29tbW9uT3B0aW9ucz4gPSB7XG4gICAgY2hpbGRQcm9jZXNzOiB0cnVlLFxuICAgIGNoaWxkUHJvY2Vzc01lbW9yeU1iOiAwLFxuICAgIGNvbmN1cnJlbmN5OiAxMDAsXG4gICAgZGVzY3JpcHRpb246IFwiXCIsXG4gICAgZXhjbHVkZTogW10sXG4gICAgaW5jbHVkZTogW10sXG4gICAgcmF0ZTogMCxcbiAgICBlbnY6IHt9LFxuICAgIGdjOiBcImF1dG9cIixcbiAgICBtYXhSZXRyaWVzOiAyLFxuICAgIG1lbW9yeVNpemU6IDEwMjQsXG4gICAgbW9kZTogXCJhdXRvXCIsXG4gICAgcGFja2FnZUpzb246IFwiXCIsXG4gICAgdXNlRGVwZW5kZW5jeUNhY2hpbmc6IHRydWUsXG4gICAgcmV0ZW50aW9uSW5EYXlzOiAxLFxuICAgIHNwZWN1bGF0aXZlUmV0cnlUaHJlc2hvbGQ6IDMsXG4gICAgdGltZW91dDogNjAsXG4gICAgd2VicGFja09wdGlvbnM6IHt9LFxuICAgIHZhbGlkYXRlU2VyaWFsaXphdGlvbjogdHJ1ZSxcbiAgICBkZWJ1Z09wdGlvbnM6IHt9XG59O1xuXG4vKipcbiAqIE9wdGlvbnMgdGhhdCBhcHBseSB0byB0aGUge0BsaW5rIEZhYXN0TW9kdWxlLmNsZWFudXB9IG1ldGhvZC5cbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDbGVhbnVwT3B0aW9ucyB7XG4gICAgLyoqXG4gICAgICogSWYgdHJ1ZSwgZGVsZXRlIHByb3ZpZGVyIGNsb3VkIHJlc291cmNlcy4gRGVmYXVsdDogdHJ1ZS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFRoZSBjbGVhbnVwIG9wZXJhdGlvbiBoYXMgdHdvIGZ1bmN0aW9uczogc3RvcHBpbmcgdGhlIGZhYXN0LmpzIHJ1bnRpbWVcbiAgICAgKiBhbmQgZGVsZXRpbmcgY2xvdWQgcmVzb3VyY2VzIHRoYXQgd2VyZSBpbnN0YW50aWF0ZWQuIElmIGBkZWxldGVSZXNvdXJjZXNgXG4gICAgICogaXMgZmFsc2UsIHRoZW4gb25seSB0aGUgcnVudGltZSBpcyBzdG9wcGVkIGFuZCBubyBjbG91ZCByZXNvdXJjZXMgYXJlXG4gICAgICogZGVsZXRlZC4gVGhpcyBjYW4gYmUgdXNlZnVsIGZvciBkZWJ1Z2dpbmcgYW5kIGV4YW1pbmluZyB0aGUgc3RhdGUgb2ZcbiAgICAgKiByZXNvdXJjZXMgY3JlYXRlZCBieSBmYWFzdC5qcy5cbiAgICAgKlxuICAgICAqIEl0IGlzIHN1cHBvcnRlZCB0byBjYWxsIHtAbGluayBGYWFzdE1vZHVsZS5jbGVhbnVwfSB0d2ljZTogb25jZSB3aXRoXG4gICAgICogYGRlbGV0ZVJlc291cmNlc2Agc2V0IHRvIGBmYWxzZWAsIHdoaWNoIG9ubHkgc3RvcHMgdGhlIHJ1bnRpbWUsIGFuZCB0aGVuXG4gICAgICogYWdhaW4gc2V0IHRvIGB0cnVlYCB0byBkZWxldGUgcmVzb3VyY2VzLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIHRlc3RpbmcuXG4gICAgICovXG4gICAgZGVsZXRlUmVzb3VyY2VzPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIElmIHRydWUsIGRlbGV0ZSBjYWNoZWQgcmVzb3VyY2VzLiBEZWZhdWx0OiBmYWxzZS5cbiAgICAgKiBAcmVtYXJrc1xuICAgICAqIFNvbWUgcmVzb3VyY2VzIGFyZSBjYWNoZWQgcGVyc2lzdGVudGx5IGJldHdlZW4gY2FsbHMgZm9yIHBlcmZvcm1hbmNlXG4gICAgICogcmVhc29ucy4gSWYgdGhpcyBvcHRpb24gaXMgc2V0IHRvIHRydWUsIHRoZXNlIGNhY2hlZCByZXNvdXJjZXMgYXJlXG4gICAgICogZGVsZXRlZCB3aGVuIGNsZWFudXAgb2NjdXJzLCBpbnN0ZWFkIG9mIGJlaW5nIGxlZnQgYmVoaW5kIGZvciBmdXR1cmUgdXNlLlxuICAgICAqIEZvciBleGFtcGxlLCBvbiBBV1MgdGhpcyBpbmNsdWRlcyB0aGUgTGFtYmRhIExheWVycyB0aGF0IGFyZSBjcmVhdGVkIGZvclxuICAgICAqIHtAbGluayBDb21tb25PcHRpb25zLnBhY2thZ2VKc29ufSBkZXBlbmRlbmNpZXMuIE5vdGUgdGhhdCBvbmx5IHRoZSBjYWNoZWRcbiAgICAgKiByZXNvdXJjZXMgY3JlYXRlZCBieSB0aGlzIGluc3RhbmNlIG9mIEZhYXN0TW9kdWxlIGFyZSBkZWxldGVkLCBub3QgY2FjaGVkXG4gICAgICogcmVzb3VyY2VzIGZyb20gb3RoZXIgRmFhc3RNb2R1bGVzLiBUaGlzIGlzIHNpbWlsYXIgdG8gc2V0dGluZ1xuICAgICAqIGB1c2VDYWNoZWREZXBlbmRlbmNpZXNgIHRvIGBmYWxzZWAgZHVyaW5nIGZ1bmN0aW9uIGNvbnN0cnVjdGlvbiwgZXhjZXB0XG4gICAgICogYGRlbGV0ZUNhY2hlc2AgY2FuIGJlIHNldCBhdCBmdW5jdGlvbiBjbGVhbnVwIHRpbWUsIGFuZCBhbnkgb3RoZXJcbiAgICAgKiBGYWFzdE1vZHVsZXMgY3JlYXRlZCBiZWZvcmUgY2xlYW51cCBtYXkgdXNlIHRoZSBjYWNoZWQgTGF5ZXJzLlxuICAgICAqL1xuICAgIGRlbGV0ZUNhY2hlcz86IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBOdW1iZXIgb2Ygc2Vjb25kcyB0byB3YWl0IGZvciBnYXJiYWdlIGNvbGxlY3Rpb24uIERlZmF1bHQ6IDEwLlxuICAgICAqIEByZW1hcmtzXG4gICAgICogR2FyYmFnZSBjb2xsZWN0aW9uIGNhbiBzdGlsbCBiZSBvcGVyYXRpbmcgd2hlbiBjbGVhbnVwIGlzIGNhbGxlZDsgdGhpc1xuICAgICAqIG9wdGlvbiBsaW1pdHMgdGhlIGFtb3VudCBvZiB0aW1lIGZhYXN0IHdhaXRzIGZvciB0aGUgZ2FyYmFnZSBjb2xsZWN0b3IuXG4gICAgICogSWYgc2V0IHRvIDAsIHRoZSB3YWl0IGlzIHVubGltaXRlZC5cbiAgICAgKi9cbiAgICBnY1RpbWVvdXQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBjb25zdCBDbGVhbnVwT3B0aW9uRGVmYXVsdHM6IFJlcXVpcmVkPENsZWFudXBPcHRpb25zPiA9IHtcbiAgICBkZWxldGVSZXNvdXJjZXM6IHRydWUsXG4gICAgZGVsZXRlQ2FjaGVzOiBmYWxzZSxcbiAgICBnY1RpbWVvdXQ6IDEwXG59O1xuXG4vKipcbiAqIFN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZnVuY3Rpb24gaW52b2NhdGlvbnMuXG4gKiBAcmVtYXJrc1xuICogYGBgXG4gKiAgICAgICAgICAgICAgIGxvY2FsU3RhcnRMYXRlbmN5ICAgICAgcmVtb3RlU3RhcnRMYXRlbmN5ICAgICAgZXhlY3V0aW9uVGltZVxuICogICAgICAgICAgICAg4peA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pa24peBIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilrfil4DilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilrZcbiAqXG4gKiDilIzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilKzilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJBcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgIExvY2FsICAgICAgICAgICAgICAg4pSCICAgICAgICAgICAgQ2xvdWQgUHJvdmlkZXIgICAgICAgICAgICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQICAgIOKUgiAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkCAgICAgICAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkCAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICDilIIgICDilIIgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUgiAgbG9jYWwgIOKUgiAgICDilIIgICDilIIgcmVxdWVzdCAg4pSCICAgICAgICAg4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICBpbnZva2UgIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKWtuKUgiAgcXVldWUgIOKUguKUgOKUgOKUgOKUgOKUvOKUgOKUgOKWtuKUgiAgcXVldWUgICDilJzilIDilIDilIDilIDilIDilIDilIDilIDilrbilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgIOKUgiAgIOKUgiAgICAgICAgICDilIIgICAgICAgICDilIIgICAgICAgICAg4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYICAgIOKUgiAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmCAgICAgICAgIOKUgiAgY2xvdWQgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICDilIIgZnVuY3Rpb24g4pSCICDilIJcbiAqIOKUgiAgICAgICAgICAgICAgICAgICAg4pSM4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSQICAgIOKUgiAgIOKUjOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUkCAgICAgICAgIOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICDilIIgICAg4pSCICAg4pSCICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICAgICAgICDilIIgIOKUglxuICog4pSCICAgcmVzdWx0ICDil4DilIDilIDilIDilIDilIDilIDilIDilIDilIIgIGxvY2FsICDilILil4DilIDilIDilIDilLzilIDilIDilIDilIIgcmVzcG9uc2Ug4pSC4peA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUgiBwb2xsaW5nIOKUgiAgICDilIIgICDilIIgIHF1ZXVlICAg4pSCICAgICAgICAg4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUgiAgICAgICAgIOKUgiAgICDilIIgICDilIIgICAgICAgICAg4pSCICAgICAgICAg4pSCICAgICAgICAgIOKUgiAg4pSCXG4gKiDilIIgICAgICAgICAgICAgICAgICAgIOKUlOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUmCAgICDilIIgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJggICAgICAgICDilJTilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilJggIOKUglxuICog4pSCICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICDilIIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIOKUglxuICog4pSU4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pS04pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSYXG4gKlxuICogICAgICAgICAgICAg4peBIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pSAIOKUgCDilIAg4pa3XG4gKiAgICAgICAgICAgICAgICAgICAgICByZXR1cm5MYXRlbmN5ICAgICAgICAgICAgICAgICAg4peA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pa2XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VuZFJlc3BvbnNlTGF0ZW5jeVxuICogYGBgXG4gKlxuICogYGxvY2FsU3RhcnRMYXRlbmN5YCBhbmQgYGV4ZWN1dGlvblRpbWVgIGFyZSBtZWFzdXJlZCBvbiBvbmUgbWFjaGluZSBhbmQgYXJlXG4gKiBmcmVlIG9mIGNsb2NrIHNrZXcuIGByZW1vdGVTdGFydExhdGVuY3lgIGFuZCBgcmV0dXJuTGF0ZW5jeWAgYXJlIG1lYXN1cmVkIGFzXG4gKiB0aW1lIGRpZmZlcmVuY2VzIGJldHdlZW4gbWFjaGluZXMgYW5kIGFyZSBzdWJqZWN0IHRvIG11Y2ggbW9yZSB1bmNlcnRhaW50eSxcbiAqIGFuZCBlZmZlY3RzIGxpa2UgY2xvY2sgc2tldy5cbiAqXG4gKiBBbGwgdGltZXMgYXJlIGluIG1pbGxpc2Vjb25kcy5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjbGFzcyBGdW5jdGlvblN0YXRzIHtcbiAgICAvKipcbiAgICAgKiBTdGF0aXN0aWNzIGZvciBob3cgbG9uZyBpbnZvY2F0aW9ucyBzdGF5IGluIHRoZSBsb2NhbCBxdWV1ZSBiZWZvcmUgYmVpbmdcbiAgICAgKiBzZW50IHRvIHRoZSBjbG91ZCBwcm92aWRlci5cbiAgICAgKi9cbiAgICBsb2NhbFN0YXJ0TGF0ZW5jeSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgLyoqXG4gICAgICogU3RhdGlzdGljcyBmb3IgaG93IGxvbmcgcmVxdWVzdHMgdGFrZSB0byBzdGFydCBleGVjdXRpb24gYWZ0ZXIgYmVpbmcgc2VudFxuICAgICAqIHRvIHRoZSBjbG91ZCBwcm92aWRlci4gVGhpcyB0eXBpY2FsbHkgaW5jbHVkZXMgcmVtb3RlIHF1ZXVlaW5nIGFuZCBjb2xkXG4gICAgICogc3RhcnQgdGltZXMuIEJlY2F1c2UgdGhpcyBtZWFzdXJlbWVudCByZXF1aXJlcyBjb21wYXJpbmcgdGltZXN0YW1wcyBmcm9tXG4gICAgICogZGlmZmVyZW50IG1hY2hpbmVzLCBpdCBpcyBzdWJqZWN0IHRvIGNsb2NrIHNrZXcgYW5kIG90aGVyIGVmZmVjdHMsIGFuZFxuICAgICAqIHNob3VsZCBub3QgYmUgY29uc2lkZXJlZCBoaWdobHkgYWNjdXJhdGUuIEl0IGNhbiBiZSB1c2VmdWwgZm9yIGRldGVjdGluZ1xuICAgICAqIGV4Y2Vzc2l2ZWx5IGhpZ2ggbGF0ZW5jeSBwcm9ibGVtcy4gRmFhc3QuanMgYXR0ZW1wdCB0byBjb3JyZWN0IGZvciBjbG9ja1xuICAgICAqIHNrZXcgaGV1cmlzdGljYWxseS5cbiAgICAgKi9cbiAgICByZW1vdGVTdGFydExhdGVuY3kgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIC8qKlxuICAgICAqIFN0YXRpc3RpY3MgZm9yIGZ1bmN0aW9uIGV4ZWN1dGlvbiB0aW1lIGluIG1pbGxpc2Vjb25kcy4gIFRoaXMgaXMgbWVhc3VyZWRcbiAgICAgKiBhcyB3YWxsIGNsb2NrIHRpbWUgaW5zaWRlIHRoZSBjbG91ZCBmdW5jdGlvbiwgYW5kIGRvZXMgbm90IGluY2x1ZGUgdGhlXG4gICAgICogdGltZSB0YWtlbiB0byBzZW5kIHRoZSByZXNwb25zZSB0byB0aGUgcmVzcG9uc2UgcXVldWUuIE5vdGUgdGhhdCBtb3N0XG4gICAgICogY2xvdWQgcHJvdmlkZXJzIHJvdW5kIHVwIHRvIHRoZSBuZXh0IDEwMG1zIGZvciBwcmljaW5nLlxuICAgICAqL1xuICAgIGV4ZWN1dGlvblRpbWUgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIC8qKlxuICAgICAqIFN0YXRpc3RpY3MgZm9yIGhvdyBsb25nIGl0IHRha2VzIHRvIHNlbmQgdGhlIHJlc3BvbnNlIHRvIHRoZSByZXNwb25zZVxuICAgICAqIHF1ZXVlLlxuICAgICAqL1xuICAgIHNlbmRSZXNwb25zZUxhdGVuY3kgPSBuZXcgU3RhdGlzdGljcygpO1xuICAgIC8qKlxuICAgICAqIFN0YXRpc3RpY3MgZm9yIGhvdyBsb25nIGl0IHRha2VzIHRvIHJldHVybiBhIHJlc3BvbnNlIGZyb20gdGhlIGVuZCBvZlxuICAgICAqIGV4ZWN1dGlvbiB0aW1lIHRvIHRoZSByZWNlaXB0IG9mIHRoZSByZXNwb25zZSBsb2NhbGx5LiBUaGlzIG1lYXN1cmVtZW50XG4gICAgICogcmVxdWlyZXMgY29tcGFyaW5nIHRpbWVzdGFtcHMgZnJvbSBkaWZmZXJlbnQgbWFjaGluZXMsIGFuZCBpcyBzdWJqZWN0IHRvXG4gICAgICogY2xvY2sgc2tldyBhbmQgb3RoZXIgZWZmZWN0cy4gSXQgc2hvdWxkIG5vdCBiZSBjb25zaWRlcmVkIGhpZ2hseVxuICAgICAqIGFjY3VyYXRlLiBJdCBjYW4gYmUgdXNlZnVsIGZvciBkZXRlY3RpbmcgZXhjZXNzaXZlbHkgaGlnaCBsYXRlbmN5XG4gICAgICogcHJvYmxlbXMuIEZhYXN0LmpzIGF0dGVtcHRzIHRvIGNvcnJlY3QgZm9yIGNsb2NrIHNrZXcgaGV1cmlzdGljYWxseS5cbiAgICAgKi9cbiAgICByZXR1cm5MYXRlbmN5ID0gbmV3IFN0YXRpc3RpY3MoKTtcbiAgICAvKipcbiAgICAgKiBTdGF0aXN0aWNzIGZvciBhbW91bnQgb2YgdGltZSBiaWxsZWQuIFRoaXMgaXMgc2ltaWxhciB0b1xuICAgICAqIHtAbGluayBGdW5jdGlvblN0YXRzLmV4ZWN1dGlvblRpbWV9IGV4Y2VwdCBlYWNoIHNhbXBsZWQgdGltZSBpcyByb3VuZGVkXG4gICAgICogdXAgdG8gdGhlIG5leHQgMTAwbXMuXG4gICAgICovXG4gICAgZXN0aW1hdGVkQmlsbGVkVGltZSA9IG5ldyBTdGF0aXN0aWNzKCk7XG4gICAgLyoqXG4gICAgICogVGhlIG51bWJlciBvZiBpbnZvY2F0aW9ucyBhdHRlbXB0ZWQuIElmIGFuIGludm9jYXRpb24gaXMgcmV0cmllZCwgdGhpc1xuICAgICAqIG9ubHkgY291bnRzIHRoZSBpbnZvY2F0aW9uIG9uY2UuXG4gICAgICovXG4gICAgaW52b2NhdGlvbnMgPSAwO1xuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW52b2NhdGlvbnMgdGhhdCB3ZXJlIHN1Y2Nlc3NmdWxseSBjb21wbGV0ZWQuXG4gICAgICovXG4gICAgY29tcGxldGVkID0gMDtcbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIGludm9jYXRpb24gcmV0cmllcyBhdHRlbXB0ZWQuIFRoaXMgY291bnRzIHJldHJpZXNcbiAgICAgKiBhdHRlbXB0ZWQgYnkgZmFhc3QuanMgdG8gcmVjb3ZlciBmcm9tIHRyYW5zaWVudCBlcnJvcnMsIGJ1dCBkb2VzIG5vdFxuICAgICAqIGNvdW50IHJldHJpZXMgYnkgdGhlIGNsb3VkIHByb3ZpZGVyLlxuICAgICAqL1xuICAgIHJldHJpZXMgPSAwO1xuICAgIC8qKlxuICAgICAqIFRoZSBudW1iZXIgb2YgaW52b2NhdGlvbnMgdGhhdCByZXN1bHRlZCBpbiBhbiBlcnJvci4gSWYgYW4gaW52b2NhdGlvbiBpc1xuICAgICAqIHJldHJpZWQsIGFuIGVycm9yIGlzIG9ubHkgY291bnRlZCBvbmNlLCBubyBtYXR0ZXIgaG93IG1hbnkgcmV0cmllcyB3ZXJlXG4gICAgICogYXR0ZW1wdGVkLlxuICAgICAqL1xuICAgIGVycm9ycyA9IDA7XG4gICAgLyoqXG4gICAgICogU3VtbWFyaXplIHRoZSBmdW5jdGlvbiBzdGF0cyBhcyBhIHN0cmluZy5cbiAgICAgKiBAcmV0dXJucyBhIHN0cmluZyBzaG93aW5nIHRoZSB2YWx1ZSBvZiBjb21wbGV0ZWQsIHJldHJpZXMsIGVycm9ycywgYW5kXG4gICAgICogbWVhbiBleGVjdXRpb24gdGltZS4gVGhpcyBzdHJpbmcgZXhjbHVkZXMgaW52b2NhdGlvbnMgYnkgZGVmYXVsdCBiZWNhdXNlXG4gICAgICogaXQgaXMgb2Z0ZW4gZml4ZWQuXG4gICAgICovXG4gICAgdG9TdHJpbmcoKSB7XG4gICAgICAgIHJldHVybiBgY29tcGxldGVkOiAke3RoaXMuY29tcGxldGVkfSwgcmV0cmllczogJHt0aGlzLnJldHJpZXN9LCBlcnJvcnM6ICR7dGhpcy5lcnJvcnN9LCBleGVjdXRpb25UaW1lLm1lYW46ICR7dGhpcy5leGVjdXRpb25UaW1lLm1lYW59bXNgO1xuICAgIH1cbiAgICAvKiogQGludGVybmFsICovXG4gICAgY2xvbmUoKTogRnVuY3Rpb25TdGF0cyB7XG4gICAgICAgIGNvbnN0IHJ2ID0gT2JqZWN0LmFzc2lnbihPYmplY3QuY3JlYXRlKE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSksIHRoaXMpO1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzT2YocnYpKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHJ2W2tleV0gIT09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICAgICAgICBydltrZXldID0gcnZba2V5XS5jbG9uZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBydjtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBGdW5jdGlvbkV4ZWN1dGlvbk1ldHJpY3Mge1xuICAgIHNlY29uZE1ldHJpY3M6IFN0YXRpc3RpY3NbXSA9IFtdO1xufVxuXG5leHBvcnQgdHlwZSBDYWxsSWQgPSBzdHJpbmc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzcG9uc2VDb250ZXh0IHtcbiAgICB0eXBlOiBcImZ1bGZpbGxcIiB8IFwicmVqZWN0XCI7XG4gICAgdmFsdWU6IHN0cmluZztcbiAgICBjYWxsSWQ6IENhbGxJZDtcbiAgICBpc0Vycm9yT2JqZWN0PzogYm9vbGVhbjtcbiAgICByZW1vdGVFeGVjdXRpb25TdGFydFRpbWU/OiBudW1iZXI7XG4gICAgcmVtb3RlRXhlY3V0aW9uRW5kVGltZT86IG51bWJlcjtcbiAgICBsb2dVcmw/OiBzdHJpbmc7XG4gICAgaW5zdGFuY2VJZD86IHN0cmluZztcbiAgICBleGVjdXRpb25JZD86IHN0cmluZztcbiAgICBtZW1vcnlVc2FnZT86IE5vZGVKUy5NZW1vcnlVc2FnZTtcbiAgICB0aW1lc3RhbXA/OiBudW1iZXI7IC8vIHRpbWVzdGFtcCB3aGVuIHJlc3BvbnNlIG1lc3NhZ2Ugd2FzIHNlbnQgYWNjb3JkaW5nIHRvIGNsb3VkIHNlcnZpY2UsIHRoaXMgaXMgb3B0aW9uYWwgYW5kIHVzZWQgdG8gcHJvdmlkZSBtb3JlIGFjY3VyYXRlIG1ldHJpY3MuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUHJvbWlzZVJlc3BvbnNlTWVzc2FnZSBleHRlbmRzIFJlc3BvbnNlQ29udGV4dCB7XG4gICAga2luZDogXCJwcm9taXNlXCI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSXRlcmF0b3JSZXNwb25zZU1lc3NhZ2UgZXh0ZW5kcyBSZXNwb25zZUNvbnRleHQge1xuICAgIGtpbmQ6IFwiaXRlcmF0b3JcIjtcbiAgICBzZXF1ZW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEZ1bmN0aW9uU3RhcnRlZE1lc3NhZ2Uge1xuICAgIGtpbmQ6IFwiZnVuY3Rpb25zdGFydGVkXCI7XG4gICAgY2FsbElkOiBDYWxsSWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ3B1TWV0cmljc01lc3NhZ2Uge1xuICAgIGtpbmQ6IFwiY3B1bWV0cmljc1wiO1xuICAgIGNhbGxJZDogQ2FsbElkO1xuICAgIG1ldHJpY3M6IENwdU1lYXN1cmVtZW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBvbGxSZXN1bHQge1xuICAgIE1lc3NhZ2VzOiBNZXNzYWdlW107XG4gICAgaXNGdWxsTWVzc2FnZUJhdGNoPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IHR5cGUgTWVzc2FnZSA9XG4gICAgfCBQcm9taXNlUmVzcG9uc2VNZXNzYWdlXG4gICAgfCBJdGVyYXRvclJlc3BvbnNlTWVzc2FnZVxuICAgIHwgRnVuY3Rpb25TdGFydGVkTWVzc2FnZVxuICAgIHwgQ3B1TWV0cmljc01lc3NhZ2U7XG5cbmV4cG9ydCB0eXBlIEtpbmQgPSBNZXNzYWdlW1wia2luZFwiXTtcbmV4cG9ydCB0eXBlIFVVSUQgPSBzdHJpbmc7XG5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJNZXNzYWdlczxLIGV4dGVuZHMgS2luZD4obWVzc2FnZXM6IE1lc3NhZ2VbXSwga2luZDogSykge1xuICAgIHJldHVybiBtZXNzYWdlcy5maWx0ZXIoXG4gICAgICAgIChtc2c6IE1lc3NhZ2UpOiBtc2cgaXMgRXh0cmFjdDxNZXNzYWdlLCB7IGtpbmQ6IEsgfT4gPT4gbXNnLmtpbmQgPT09IGtpbmRcbiAgICApO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFByb3ZpZGVySW1wbDxPIGV4dGVuZHMgQ29tbW9uT3B0aW9ucywgUz4ge1xuICAgIG5hbWU6IFByb3ZpZGVyO1xuICAgIGRlZmF1bHRzOiBSZXF1aXJlZDxPPjtcbiAgICBpbml0aWFsaXplKHNlcnZlck1vZHVsZTogc3RyaW5nLCBub25jZTogVVVJRCwgb3B0aW9uczogUmVxdWlyZWQ8Tz4pOiBQcm9taXNlPFM+O1xuICAgIGNvc3RTbmFwc2hvdChzdGF0ZTogUywgc3RhdHM6IEZ1bmN0aW9uU3RhdHMpOiBQcm9taXNlPENvc3RTbmFwc2hvdD47XG4gICAgY2xlYW51cChzdGF0ZTogUywgb3B0aW9uczogUmVxdWlyZWQ8Q2xlYW51cE9wdGlvbnM+KTogUHJvbWlzZTx2b2lkPjtcbiAgICBsb2dVcmwoc3RhdGU6IFMpOiBzdHJpbmc7XG4gICAgaW52b2tlKHN0YXRlOiBTLCByZXF1ZXN0OiBGdW5jdGlvbkNhbGwsIGNhbmNlbDogUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD47XG4gICAgcG9sbChzdGF0ZTogUywgY2FuY2VsOiBQcm9taXNlPHZvaWQ+KTogUHJvbWlzZTxQb2xsUmVzdWx0PjtcbiAgICByZXNwb25zZVF1ZXVlSWQoc3RhdGU6IFMpOiBzdHJpbmc7XG59XG4iXX0=
\No newline at end of file