footprintjs 9.43.0 → 9.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,24 +6,35 @@
6
6
  * (`pause/record.ts` · `CHECKPOINT_VERSION` / `decodeCheckpoint`), and
7
7
  * detaches it with one `structuredClone`.
8
8
  *
9
- * Clone resilience lives beside it. The JSON-safe contract governs what
10
- * CONSUMERS put into a checkpoint (pauseData, shared state) — but the
11
- * execution tree's diagnostic bags (`logs`/`errors`/`metrics`/`evals`) accept
12
- * ANY value at write time without cloning (`$debug`/`$error`/`$metric`/`$eval`
13
- * route through `DiagnosticCollector`, which stores raw references). A
14
- * `$debug`'d function in any stage of a pausing run would make the
15
- * whole-checkpoint clone throw `DataCloneError` — swallowing the pause. That
16
- * violates the library's error-isolation grain (observability side-bags never
17
- * abort traversal anywhere else), so:
9
+ * LEAN (format 2). The checkpoint holds what `resume()` reads and the pause's
10
+ * own record, nothing else:
18
11
  *
19
- * - `sanitizeDiagnosticBags` — replace non-cloneable diagnostic values with
20
- * marker strings (`'[non-serializable: function]'`) so the pause survives.
21
- * - `describeCheckpointCloneFailure` — when the clone STILL fails after
22
- * sanitization (the non-cloneable lives in consumer-owned data, e.g.
23
- * `pauseData`), name the offending checkpoint field(s) and point at the
24
- * JSON-safe contract instead of letting a naked `DataCloneError` escape.
12
+ * read by resume the cursor (`pausedStageId`, `subflowPath`, `pausedBy`),
13
+ * the state (`sharedState`, and `subflowStates` — one capture
14
+ * per subflow ON the pause path), the counters
15
+ * (`executionCount`, `visitCounts` — one entry per stage id),
16
+ * the waiting siblings (`pendingPauses`), the redaction names
17
+ * (`redactionMarks`), the link (`pausedExecution`);
18
+ * the record `pauseData` (the question), `invokerStageId`, `pausedAt`.
25
19
  *
26
- * Both run ONLY on the clone-failure path of a pause — never on the hot path.
20
+ * So its size is the state's and the chart's, never the run's length. Format 1
21
+ * also carried the whole execution tree and the finished subflows' results —
22
+ * the run's served record, which no resume read and which grew with every
23
+ * finished iteration (`bench/checkpoint-size.ts`: 19.3 MB after 60 agent
24
+ * turns whose resumable state — root plus captures — is 0.13 MB; the tree
25
+ * alone was 97%). That record is `getSnapshot()`'s. Pinned:
26
+ * test/lib/pause/checkpoint-size.test.ts.
27
+ *
28
+ * THE LAW holds: the checkpoint keeps REAL values — no redaction policy ever
29
+ * touches it (it is what the resumed run computes on); the marks travel as
30
+ * NAMES only.
31
+ *
32
+ * The JSON-safe contract governs what CONSUMERS put into a checkpoint
33
+ * (`pauseData`, shared state). A value `structuredClone` refuses can only come
34
+ * from them — shared state is cloned at every commit, so a function never
35
+ * reaches it, and no diagnostic bag is carried — so a failed clone becomes a
36
+ * DESCRIPTIVE contract error naming the field (`describeCheckpointCloneFailure`)
37
+ * instead of a naked `DataCloneError`.
27
38
  */
28
39
  import type { FlowchartTraverser } from '../engine/traversal/FlowchartTraverser.js';
29
40
  import type { FlowchartCheckpoint, PauseSignal, RedactionMarks } from '../pause/types.js';
@@ -36,7 +47,7 @@ export interface PausedRun {
36
47
  readonly redactionMarks?: RedactionMarks;
37
48
  }
38
49
  /**
39
- * Build a fully DETACHED checkpoint from a caught PauseSignal.
50
+ * Build a fully DETACHED, lean checkpoint from a caught PauseSignal.
40
51
  *
41
52
  * Every field is deep-copied via one `structuredClone` of the assembled
42
53
  * checkpoint, because the raw pieces alias live engine state:
@@ -45,27 +56,21 @@ export interface PausedRun {
45
56
  * but (copy-on-write, 9.29.0) every later generation shares its
46
57
  * unchanged subtrees, so a checkpoint that aliased it would alias the
47
58
  * resumed run's state too.
48
- * - `executionTree` nodes are fresh, but their `logs`/`errors`/`metrics`/
49
- * `evals`/`stageReads`/`flowMessages` fields reference live
50
- * `DiagnosticCollector` bags that keep accumulating on same-executor
51
- * resume.
52
59
  * - `subflowStates` values are shallow copies whose NESTED objects alias
53
60
  * subflow memory, and they get seeded back into live runtimes on resume.
54
- * - `subflowResults` values stay referenced by the traverser's results map.
55
61
  *
56
62
  * The checkpoint is persisted by contract ("store in Redis/Postgres") — it
57
- * must never share structure with the engine. Pause is not a hot path; the
58
- * clone cost is irrelevant.
63
+ * must never share structure with the engine.
59
64
  *
60
- * On clone failure the diagnostic bags are sanitized (the live engine bags
61
- * are never touched) and the clone retried; if the retry STILL fails, the
62
- * violation is in consumer-owned data (realistically `pauseData` — a function
63
- * can never reach shared state: the record's clone at commit refuses it) and a
64
- * DESCRIPTIVE contract error names the offending checkpoint field(s).
65
+ * The state is read straight off the root runtime's store — no snapshot is
66
+ * built (a snapshot would build the execution tree and copy the commit log,
67
+ * work proportional to the run's length, only to throw both away).
65
68
  *
66
69
  * Subflow scope capture (`subflowStates`) survives ONLY on the signal — the
67
70
  * nested runtimes are GC'd as the stack unwinds. Promoting it onto the
68
71
  * checkpoint here lets cross-executor resume restore pre-pause subflow
69
- * scope (e.g. an Agent's `scope.history`). Empty `{}` for root-level pauses.
72
+ * scope (e.g. an Agent's `scope.history`). The signal captures a subflow only
73
+ * as it bubbles through that subflow's boundary, so the keys are exactly the
74
+ * pause path's. Empty `{}` for root-level pauses.
70
75
  */
71
76
  export declare function buildPauseCheckpoint(signal: PauseSignal, traverser: FlowchartTraverser<any, any>, run: PausedRun): FlowchartCheckpoint;
@@ -6,29 +6,39 @@
6
6
  * (`pause/record.ts` · `CHECKPOINT_VERSION` / `decodeCheckpoint`), and
7
7
  * detaches it with one `structuredClone`.
8
8
  *
9
- * Clone resilience lives beside it. The JSON-safe contract governs what
10
- * CONSUMERS put into a checkpoint (pauseData, shared state) — but the
11
- * execution tree's diagnostic bags (`logs`/`errors`/`metrics`/`evals`) accept
12
- * ANY value at write time without cloning (`$debug`/`$error`/`$metric`/`$eval`
13
- * route through `DiagnosticCollector`, which stores raw references). A
14
- * `$debug`'d function in any stage of a pausing run would make the
15
- * whole-checkpoint clone throw `DataCloneError` — swallowing the pause. That
16
- * violates the library's error-isolation grain (observability side-bags never
17
- * abort traversal anywhere else), so:
9
+ * LEAN (format 2). The checkpoint holds what `resume()` reads and the pause's
10
+ * own record, nothing else:
18
11
  *
19
- * - `sanitizeDiagnosticBags` — replace non-cloneable diagnostic values with
20
- * marker strings (`'[non-serializable: function]'`) so the pause survives.
21
- * - `describeCheckpointCloneFailure` — when the clone STILL fails after
22
- * sanitization (the non-cloneable lives in consumer-owned data, e.g.
23
- * `pauseData`), name the offending checkpoint field(s) and point at the
24
- * JSON-safe contract instead of letting a naked `DataCloneError` escape.
12
+ * read by resume the cursor (`pausedStageId`, `subflowPath`, `pausedBy`),
13
+ * the state (`sharedState`, and `subflowStates` — one capture
14
+ * per subflow ON the pause path), the counters
15
+ * (`executionCount`, `visitCounts` — one entry per stage id),
16
+ * the waiting siblings (`pendingPauses`), the redaction names
17
+ * (`redactionMarks`), the link (`pausedExecution`);
18
+ * the record `pauseData` (the question), `invokerStageId`, `pausedAt`.
25
19
  *
26
- * Both run ONLY on the clone-failure path of a pause — never on the hot path.
20
+ * So its size is the state's and the chart's, never the run's length. Format 1
21
+ * also carried the whole execution tree and the finished subflows' results —
22
+ * the run's served record, which no resume read and which grew with every
23
+ * finished iteration (`bench/checkpoint-size.ts`: 19.3 MB after 60 agent
24
+ * turns whose resumable state — root plus captures — is 0.13 MB; the tree
25
+ * alone was 97%). That record is `getSnapshot()`'s. Pinned:
26
+ * test/lib/pause/checkpoint-size.test.ts.
27
+ *
28
+ * THE LAW holds: the checkpoint keeps REAL values — no redaction policy ever
29
+ * touches it (it is what the resumed run computes on); the marks travel as
30
+ * NAMES only.
31
+ *
32
+ * The JSON-safe contract governs what CONSUMERS put into a checkpoint
33
+ * (`pauseData`, shared state). A value `structuredClone` refuses can only come
34
+ * from them — shared state is cloned at every commit, so a function never
35
+ * reaches it, and no diagnostic bag is carried — so a failed clone becomes a
36
+ * DESCRIPTIVE contract error naming the field (`describeCheckpointCloneFailure`)
37
+ * instead of a naked `DataCloneError`.
27
38
  */
28
- import { isExecutionKey } from '../ids/runtimeStageId.js';
29
39
  import { CHECKPOINT_VERSION } from '../pause/record.js';
30
40
  /**
31
- * Build a fully DETACHED checkpoint from a caught PauseSignal.
41
+ * Build a fully DETACHED, lean checkpoint from a caught PauseSignal.
32
42
  *
33
43
  * Every field is deep-copied via one `structuredClone` of the assembled
34
44
  * checkpoint, because the raw pieces alias live engine state:
@@ -37,40 +47,31 @@ import { CHECKPOINT_VERSION } from '../pause/record.js';
37
47
  * but (copy-on-write, 9.29.0) every later generation shares its
38
48
  * unchanged subtrees, so a checkpoint that aliased it would alias the
39
49
  * resumed run's state too.
40
- * - `executionTree` nodes are fresh, but their `logs`/`errors`/`metrics`/
41
- * `evals`/`stageReads`/`flowMessages` fields reference live
42
- * `DiagnosticCollector` bags that keep accumulating on same-executor
43
- * resume.
44
50
  * - `subflowStates` values are shallow copies whose NESTED objects alias
45
51
  * subflow memory, and they get seeded back into live runtimes on resume.
46
- * - `subflowResults` values stay referenced by the traverser's results map.
47
52
  *
48
53
  * The checkpoint is persisted by contract ("store in Redis/Postgres") — it
49
- * must never share structure with the engine. Pause is not a hot path; the
50
- * clone cost is irrelevant.
54
+ * must never share structure with the engine.
51
55
  *
52
- * On clone failure the diagnostic bags are sanitized (the live engine bags
53
- * are never touched) and the clone retried; if the retry STILL fails, the
54
- * violation is in consumer-owned data (realistically `pauseData` — a function
55
- * can never reach shared state: the record's clone at commit refuses it) and a
56
- * DESCRIPTIVE contract error names the offending checkpoint field(s).
56
+ * The state is read straight off the root runtime's store — no snapshot is
57
+ * built (a snapshot would build the execution tree and copy the commit log,
58
+ * work proportional to the run's length, only to throw both away).
57
59
  *
58
60
  * Subflow scope capture (`subflowStates`) survives ONLY on the signal — the
59
61
  * nested runtimes are GC'd as the stack unwinds. Promoting it onto the
60
62
  * checkpoint here lets cross-executor resume restore pre-pause subflow
61
- * scope (e.g. an Agent's `scope.history`). Empty `{}` for root-level pauses.
63
+ * scope (e.g. an Agent's `scope.history`). The signal captures a subflow only
64
+ * as it bubbles through that subflow's boundary, so the keys are exactly the
65
+ * pause path's. Empty `{}` for root-level pauses.
62
66
  */
63
67
  export function buildPauseCheckpoint(signal, traverser, run) {
64
68
  // Every pause that paused in THIS run is named by it; a sibling raised again
65
69
  // on resume keeps the run it originally paused in.
66
70
  signal.completeExecution(run.runId);
67
- const snapshot = traverser.getSnapshot();
68
- const leanSubflowResults = leanSubflowResultsOf(traverser.getSubflowResults());
69
71
  const checkpoint = {
70
- // The format (9.39.0) — read back by `pause/record.ts · decodeCheckpoint`.
72
+ // The format — read back by `pause/record.ts · decodeCheckpoint`.
71
73
  checkpointVersion: CHECKPOINT_VERSION,
72
- sharedState: snapshot.sharedState,
73
- executionTree: snapshot.executionTree,
74
+ sharedState: traverser.getRuntime().globalStore.getState(),
74
75
  pausedStageId: signal.stageId,
75
76
  // The paused EXECUTION (9.37.0) — a queued sibling raised on resume
76
77
  // carries the run it ORIGINALLY paused in.
@@ -84,7 +85,6 @@ export function buildPauseCheckpoint(signal, traverser, run) {
84
85
  // below untouched). See test/lib/pause/resume-execution-counter-continuity.test.ts.
85
86
  executionCount: run.executionCount,
86
87
  visitCounts: Object.fromEntries(run.visitCounts),
87
- ...(Object.keys(leanSubflowResults).length > 0 && { subflowResults: leanSubflowResults }),
88
88
  // Invoker context — collected during traversal bubble-up (not tree-walked).
89
89
  // (`continuationStageId` is legacy-only since 9.39.0: no longer written.)
90
90
  ...(signal.invokerStageId && { invokerStageId: signal.invokerStageId }),
@@ -105,49 +105,11 @@ export function buildPauseCheckpoint(signal, traverser, run) {
105
105
  try {
106
106
  return structuredClone(checkpoint);
107
107
  }
108
- catch {
109
- // Non-cloneable diagnostics must not swallow the pause — sanitize the
110
- // executionTree's bags (markers replace the offenders) and retry.
111
- try {
112
- checkpoint.executionTree = sanitizeDiagnosticBags(checkpoint.executionTree);
113
- return structuredClone(checkpoint);
114
- }
115
- catch (retryError) {
116
- // Genuine JSON-safe contract violation in consumer-owned data.
117
- throw describeCheckpointCloneFailure(checkpoint, retryError);
118
- }
119
- }
120
- }
121
- /**
122
- * Lean subflowResults for the checkpoint (design: docs/design/subflow-commit-visibility.md):
123
- * - DROP the per-iteration mount-runtimeStageId keys ('#') that the snapshot dual-keys —
124
- * they would DOUBLE the checkpoint, and resume restores scope from `subflowStates`, not these.
125
- * - STRIP each subflow's `treeContext.history` — resume NEVER reads `subflowResults` (it
126
- * restores from `subflowStates` + `sharedState`), so the per-subflow commit log is pure
127
- * checkpoint bloat. The flat agent's checkpoint carries no commit history either → symmetric.
128
- */
129
- function leanSubflowResultsOf(sfResults) {
130
- const leanSubflowResults = {};
131
- for (const [key, value] of sfResults) {
132
- if (isExecutionKey(key))
133
- continue; // per-iteration keys are snapshot-only
134
- const v = value;
135
- if (v?.treeContext) {
136
- const treeCtxRest = {};
137
- for (const ck of Object.keys(v.treeContext)) {
138
- if (ck !== 'history')
139
- treeCtxRest[ck] = v.treeContext[ck]; // strip the per-subflow commit log
140
- }
141
- leanSubflowResults[key] = { ...value, treeContext: treeCtxRest };
142
- }
143
- else {
144
- leanSubflowResults[key] = value;
145
- }
108
+ catch (error) {
109
+ // Genuine JSON-safe contract violation in consumer-owned data.
110
+ throw describeCheckpointCloneFailure(checkpoint, error);
146
111
  }
147
- return leanSubflowResults;
148
112
  }
149
- /** The StageSnapshot fields written by `$debug`/`$error`/`$metric`/`$eval`. */
150
- const DIAGNOSTIC_BAGS = ['logs', 'errors', 'metrics', 'evals'];
151
113
  /** `true` when `structuredClone` accepts the value as-is. */
152
114
  function isCloneable(value) {
153
115
  try {
@@ -158,89 +120,12 @@ function isCloneable(value) {
158
120
  return false;
159
121
  }
160
122
  }
161
- /** Human-readable kind for the `[non-serializable: …]` marker. */
162
- function describeKind(value) {
163
- if (value === null)
164
- return 'null';
165
- if (typeof value !== 'object')
166
- return typeof value;
167
- return value.constructor?.name ?? 'object';
168
- }
169
- /** Plain data container we can rebuild entry-by-entry without lying about the type. */
170
- function isPlainObject(value) {
171
- const proto = Object.getPrototypeOf(value);
172
- return proto === Object.prototype || proto === null;
173
- }
174
- /**
175
- * Deep-replace non-cloneable values with `'[non-serializable: <kind>]'`
176
- * marker strings, preserving everything `structuredClone` accepts.
177
- *
178
- * Fast path: a cloneable value is returned AS-IS (no copy — the caller
179
- * clones the whole checkpoint right after). Only containers that actually
180
- * hold a non-cloneable leaf are rebuilt, and only KNOWN container shapes
181
- * (array / Map / Set / plain object) are rebuilt entry-by-entry — exotic
182
- * non-cloneables (Promise, WeakMap, class instances holding a function, …)
183
- * become a typed marker rather than a misleading empty shell. Pure cycles
184
- * pass the fast path untouched (`structuredClone` supports them); a cycle
185
- * is only broken — with a marker — when it shares a container with a
186
- * non-cloneable value.
187
- */
188
- function sanitizeValue(value, seen) {
189
- if (isCloneable(value))
190
- return value;
191
- if (value !== null && typeof value === 'object') {
192
- if (seen.has(value))
193
- return '[non-serializable: circular]';
194
- seen.add(value);
195
- if (Array.isArray(value)) {
196
- return value.map((v) => sanitizeValue(v, seen));
197
- }
198
- if (value instanceof Map) {
199
- return new Map([...value].map(([k, v]) => [sanitizeValue(k, seen), sanitizeValue(v, seen)]));
200
- }
201
- if (value instanceof Set) {
202
- return new Set([...value].map((v) => sanitizeValue(v, seen)));
203
- }
204
- if (isPlainObject(value)) {
205
- return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, sanitizeValue(v, seen)]));
206
- }
207
- }
208
- return `[non-serializable: ${describeKind(value)}]`;
209
- }
210
- /**
211
- * Walk a `StageSnapshot` tree (via `next` + `children`) and sanitize the four
212
- * diagnostic bags on every node IN PLACE.
213
- *
214
- * In-place is safe and intentional: `StageContext.getSnapshot()` builds fresh
215
- * node objects on every call, but the bag fields on those fresh nodes ALIAS
216
- * the live `DiagnosticCollector` bags. We replace the node's bag REFERENCE
217
- * with a sanitized copy — the live engine bags are never mutated, so a
218
- * same-executor resume keeps the original diagnostic values.
219
- */
220
- function sanitizeDiagnosticBags(tree) {
221
- const seen = new WeakSet();
222
- const visit = (node) => {
223
- for (const bag of DIAGNOSTIC_BAGS) {
224
- const bagValue = node[bag];
225
- if (bagValue !== undefined && !isCloneable(bagValue)) {
226
- node[bag] = sanitizeValue(bagValue, seen);
227
- }
228
- }
229
- if (node.next)
230
- visit(node.next);
231
- if (node.children)
232
- for (const child of node.children)
233
- visit(child);
234
- };
235
- visit(tree);
236
- return tree;
237
- }
238
123
  /**
239
- * Build the DESCRIPTIVE error for a checkpoint that still cannot be cloned
240
- * after diagnostic-bag sanitization — i.e. the non-cloneable value lives in
241
- * consumer-owned data (a genuine JSON-safe contract violation). Probes each
242
- * top-level checkpoint field individually so the message names the offending
243
- * field family. Never lets a naked `DataCloneError` escape.
124
+ * Build the DESCRIPTIVE error for a checkpoint that cannot be cloned — the
125
+ * non-cloneable value lives in consumer-owned data (a genuine JSON-safe
126
+ * contract violation). Probes each top-level checkpoint field individually so
127
+ * the message names the offending field family. Never lets a naked
128
+ * `DataCloneError` escape.
244
129
  */
245
130
  function describeCheckpointCloneFailure(checkpoint, cause) {
246
131
  const failing = Object.entries(checkpoint)
@@ -251,7 +136,7 @@ function describeCheckpointCloneFailure(checkpoint, cause) {
251
136
  `checkpoint field(s): ${fields}. The checkpoint contract is JSON-safe (no functions, no ` +
252
137
  "class instances). Check the pauseData returned by the pausable stage's execute(), and any " +
253
138
  'subflow state captured at the pause. Diagnostic values from $debug/$metric/$error/$eval ' +
254
- 'are sanitized automatically and never cause this error. ' +
139
+ 'are never part of a checkpoint and never cause this error. ' +
255
140
  'See docs/guides/execution-model.md ("Pause / resume — what a checkpoint captures").', { cause });
256
141
  }
257
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcnVubmVyL2NoZWNrcG9pbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBSUgsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTFELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBWXhEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWdDRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FDbEMsTUFBbUIsRUFDbkIsU0FBdUMsRUFDdkMsR0FBYztJQUVkLDZFQUE2RTtJQUM3RSxtREFBbUQ7SUFDbkQsTUFBTSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNwQyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDekMsTUFBTSxrQkFBa0IsR0FBRyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDO0lBQy9FLE1BQU0sVUFBVSxHQUFHO1FBQ2pCLDJFQUEyRTtRQUMzRSxpQkFBaUIsRUFBRSxrQkFBa0I7UUFDckMsV0FBVyxFQUFFLFFBQVEsQ0FBQyxXQUFXO1FBQ2pDLGFBQWEsRUFBRSxRQUFRLENBQUMsYUFBYTtRQUNyQyxhQUFhLEVBQUUsTUFBTSxDQUFDLE9BQU87UUFDN0Isb0VBQW9FO1FBQ3BFLDJDQUEyQztRQUMzQyxHQUFHLENBQUMsTUFBTSxDQUFDLGVBQWUsSUFBSSxFQUFFLGVBQWUsRUFBRSxNQUFNLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDMUUsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO1FBQy9CLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUztRQUMzQixhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWE7UUFDbkMsdUVBQXVFO1FBQ3ZFLDBFQUEwRTtRQUMxRSx5RUFBeUU7UUFDekUsb0ZBQW9GO1FBQ3BGLGNBQWMsRUFBRSxHQUFHLENBQUMsY0FBYztRQUNsQyxXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO1FBQ2hELEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDO1FBQ3pGLDRFQUE0RTtRQUM1RSwwRUFBMEU7UUFDMUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxjQUFjLElBQUksRUFBRSxjQUFjLEVBQUUsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZFLHNFQUFzRTtRQUN0RSxnRUFBZ0U7UUFDaEUsMEJBQTBCO1FBQzFCLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQy9FLHFFQUFxRTtRQUNyRSx5RUFBeUU7UUFDekUsd0VBQXdFO1FBQ3hFLHVFQUF1RTtRQUN2RSxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDckQsMEZBQTBGO1FBQzFGLDBGQUEwRjtRQUMxRixHQUFHLENBQUMsR0FBRyxDQUFDLGNBQWMsSUFBSSxFQUFFLGNBQWMsRUFBRSxHQUFHLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDakUsUUFBUSxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUU7S0FDckIsQ0FBQztJQUNGLElBQUksQ0FBQztRQUNILE9BQU8sZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxzRUFBc0U7UUFDdEUsa0VBQWtFO1FBQ2xFLElBQUksQ0FBQztZQUNILFVBQVUsQ0FBQyxhQUFhLEdBQUcsc0JBQXNCLENBQUMsVUFBVSxDQUFDLGFBQThCLENBQUMsQ0FBQztZQUM3RixPQUFPLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBQUMsT0FBTyxVQUFVLEVBQUUsQ0FBQztZQUNwQiwrREFBK0Q7WUFDL0QsTUFBTSw4QkFBOEIsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDL0QsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsb0JBQW9CLENBQUMsU0FBcUM7SUFDakUsTUFBTSxrQkFBa0IsR0FBNEIsRUFBRSxDQUFDO0lBQ3ZELEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNyQyxJQUFJLGNBQWMsQ0FBQyxHQUFHLENBQUM7WUFBRSxTQUFTLENBQUMsdUNBQXVDO1FBQzFFLE1BQU0sQ0FBQyxHQUFHLEtBQTZELENBQUM7UUFDeEUsSUFBSSxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUM7WUFDbkIsTUFBTSxXQUFXLEdBQTRCLEVBQUUsQ0FBQztZQUNoRCxLQUFLLE1BQU0sRUFBRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7Z0JBQzVDLElBQUksRUFBRSxLQUFLLFNBQVM7b0JBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxtQ0FBbUM7WUFDaEcsQ0FBQztZQUNELGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBSSxLQUE0QyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsQ0FBQztRQUMzRyxDQUFDO2FBQU0sQ0FBQztZQUNOLGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUNsQyxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sa0JBQWtCLENBQUM7QUFDNUIsQ0FBQztBQUVELCtFQUErRTtBQUMvRSxNQUFNLGVBQWUsR0FBRyxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBVSxDQUFDO0FBRXhFLDZEQUE2RDtBQUM3RCxTQUFTLFdBQVcsQ0FBQyxLQUFjO0lBQ2pDLElBQUksQ0FBQztRQUNILGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQsa0VBQWtFO0FBQ2xFLFNBQVMsWUFBWSxDQUFDLEtBQWM7SUFDbEMsSUFBSSxLQUFLLEtBQUssSUFBSTtRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQ2xDLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtRQUFFLE9BQU8sT0FBTyxLQUFLLENBQUM7SUFDbkQsT0FBTyxLQUFLLENBQUMsV0FBVyxFQUFFLElBQUksSUFBSSxRQUFRLENBQUM7QUFDN0MsQ0FBQztBQUVELHVGQUF1RjtBQUN2RixTQUFTLGFBQWEsQ0FBQyxLQUFhO0lBQ2xDLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFrQixDQUFDO0lBQzVELE9BQU8sS0FBSyxLQUFLLE1BQU0sQ0FBQyxTQUFTLElBQUksS0FBSyxLQUFLLElBQUksQ0FBQztBQUN0RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILFNBQVMsYUFBYSxDQUFDLEtBQWMsRUFBRSxJQUFxQjtJQUMxRCxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNyQyxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDaEQsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sOEJBQThCLENBQUM7UUFDM0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBQ0QsSUFBSSxLQUFLLFlBQVksR0FBRyxFQUFFLENBQUM7WUFDekIsT0FBTyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQy9GLENBQUM7UUFDRCxJQUFJLEtBQUssWUFBWSxHQUFHLEVBQUUsQ0FBQztZQUN6QixPQUFPLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hFLENBQUM7UUFDRCxJQUFJLGFBQWEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pCLE9BQU8sTUFBTSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hHLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxzQkFBc0IsWUFBWSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7QUFDdEQsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILFNBQVMsc0JBQXNCLENBQUMsSUFBbUI7SUFDakQsTUFBTSxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztJQUNuQyxNQUFNLEtBQUssR0FBRyxDQUFDLElBQW1CLEVBQVEsRUFBRTtRQUMxQyxLQUFLLE1BQU0sR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMzQixJQUFJLFFBQVEsS0FBSyxTQUFTLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztnQkFDckQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUE0QixDQUFDO1lBQ3ZFLENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSTtZQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEMsSUFBSSxJQUFJLENBQUMsUUFBUTtZQUFFLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLFFBQVE7Z0JBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JFLENBQUMsQ0FBQztJQUNGLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNaLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsOEJBQThCLENBQUMsVUFBbUMsRUFBRSxLQUFjO0lBQ3pGLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO1NBQ3ZDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDMUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0IsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUNuRSxPQUFPLElBQUksS0FBSyxDQUNkLHNGQUFzRjtRQUNwRix3QkFBd0IsTUFBTSwyREFBMkQ7UUFDekYsNEZBQTRGO1FBQzVGLDBGQUEwRjtRQUMxRiwwREFBMEQ7UUFDMUQscUZBQXFGLEVBQ3ZGLEVBQUUsS0FBSyxFQUFFLENBQ1YsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGNoZWNrcG9pbnQg4oCUIHRoZSBwYXVzZSBjaGVja3BvaW50LCBidWlsdCBPTkNFIGF0IHRoZSBwYXVzZSAoRjkpLlxuICpcbiAqIGBidWlsZFBhdXNlQ2hlY2twb2ludGAgYXNzZW1ibGVzIHRoZSBjaGVja3BvaW50IGZyb20gYSBjYXVnaHQgYFBhdXNlU2lnbmFsYFxuICogYW5kIHRoZSBwYXVzZWQgcnVuLCBzdGFtcGVkIHdpdGggdGhlIGZvcm1hdCB0aGUgT05FIGNvZGVjIHJlYWRzIGJhY2tcbiAqIChgcGF1c2UvcmVjb3JkLnRzYCDCtyBgQ0hFQ0tQT0lOVF9WRVJTSU9OYCAvIGBkZWNvZGVDaGVja3BvaW50YCksIGFuZFxuICogZGV0YWNoZXMgaXQgd2l0aCBvbmUgYHN0cnVjdHVyZWRDbG9uZWAuXG4gKlxuICogQ2xvbmUgcmVzaWxpZW5jZSBsaXZlcyBiZXNpZGUgaXQuIFRoZSBKU09OLXNhZmUgY29udHJhY3QgZ292ZXJucyB3aGF0XG4gKiBDT05TVU1FUlMgcHV0IGludG8gYSBjaGVja3BvaW50IChwYXVzZURhdGEsIHNoYXJlZCBzdGF0ZSkg4oCUIGJ1dCB0aGVcbiAqIGV4ZWN1dGlvbiB0cmVlJ3MgZGlhZ25vc3RpYyBiYWdzIChgbG9nc2AvYGVycm9yc2AvYG1ldHJpY3NgL2BldmFsc2ApIGFjY2VwdFxuICogQU5ZIHZhbHVlIGF0IHdyaXRlIHRpbWUgd2l0aG91dCBjbG9uaW5nIChgJGRlYnVnYC9gJGVycm9yYC9gJG1ldHJpY2AvYCRldmFsYFxuICogcm91dGUgdGhyb3VnaCBgRGlhZ25vc3RpY0NvbGxlY3RvcmAsIHdoaWNoIHN0b3JlcyByYXcgcmVmZXJlbmNlcykuIEFcbiAqIGAkZGVidWdgJ2QgZnVuY3Rpb24gaW4gYW55IHN0YWdlIG9mIGEgcGF1c2luZyBydW4gd291bGQgbWFrZSB0aGVcbiAqIHdob2xlLWNoZWNrcG9pbnQgY2xvbmUgdGhyb3cgYERhdGFDbG9uZUVycm9yYCDigJQgc3dhbGxvd2luZyB0aGUgcGF1c2UuIFRoYXRcbiAqIHZpb2xhdGVzIHRoZSBsaWJyYXJ5J3MgZXJyb3ItaXNvbGF0aW9uIGdyYWluIChvYnNlcnZhYmlsaXR5IHNpZGUtYmFncyBuZXZlclxuICogYWJvcnQgdHJhdmVyc2FsIGFueXdoZXJlIGVsc2UpLCBzbzpcbiAqXG4gKiAgIC0gYHNhbml0aXplRGlhZ25vc3RpY0JhZ3NgIOKAlCByZXBsYWNlIG5vbi1jbG9uZWFibGUgZGlhZ25vc3RpYyB2YWx1ZXMgd2l0aFxuICogICAgIG1hcmtlciBzdHJpbmdzIChgJ1tub24tc2VyaWFsaXphYmxlOiBmdW5jdGlvbl0nYCkgc28gdGhlIHBhdXNlIHN1cnZpdmVzLlxuICogICAtIGBkZXNjcmliZUNoZWNrcG9pbnRDbG9uZUZhaWx1cmVgIOKAlCB3aGVuIHRoZSBjbG9uZSBTVElMTCBmYWlscyBhZnRlclxuICogICAgIHNhbml0aXphdGlvbiAodGhlIG5vbi1jbG9uZWFibGUgbGl2ZXMgaW4gY29uc3VtZXItb3duZWQgZGF0YSwgZS5nLlxuICogICAgIGBwYXVzZURhdGFgKSwgbmFtZSB0aGUgb2ZmZW5kaW5nIGNoZWNrcG9pbnQgZmllbGQocykgYW5kIHBvaW50IGF0IHRoZVxuICogICAgIEpTT04tc2FmZSBjb250cmFjdCBpbnN0ZWFkIG9mIGxldHRpbmcgYSBuYWtlZCBgRGF0YUNsb25lRXJyb3JgIGVzY2FwZS5cbiAqXG4gKiBCb3RoIHJ1biBPTkxZIG9uIHRoZSBjbG9uZS1mYWlsdXJlIHBhdGggb2YgYSBwYXVzZSDigJQgbmV2ZXIgb24gdGhlIGhvdCBwYXRoLlxuICovXG5cbmltcG9ydCB0eXBlIHsgRmxvd2NoYXJ0VHJhdmVyc2VyIH0gZnJvbSAnLi4vZW5naW5lL3RyYXZlcnNhbC9GbG93Y2hhcnRUcmF2ZXJzZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBTdWJmbG93UmVzdWx0IH0gZnJvbSAnLi4vZW5naW5lL3R5cGVzLmpzJztcbmltcG9ydCB7IGlzRXhlY3V0aW9uS2V5IH0gZnJvbSAnLi4vaWRzL3J1bnRpbWVTdGFnZUlkLmpzJztcbmltcG9ydCB0eXBlIHsgU3RhZ2VTbmFwc2hvdCB9IGZyb20gJy4uL21lbW9yeS90eXBlcy5qcyc7XG5pbXBvcnQgeyBDSEVDS1BPSU5UX1ZFUlNJT04gfSBmcm9tICcuLi9wYXVzZS9yZWNvcmQuanMnO1xuaW1wb3J0IHR5cGUgeyBGbG93Y2hhcnRDaGVja3BvaW50LCBQYXVzZVNpZ25hbCwgUmVkYWN0aW9uTWFya3MgfSBmcm9tICcuLi9wYXVzZS90eXBlcy5qcyc7XG5cbi8qKiBUaGUgcGF1c2VkIHJ1bidzIGNvdW50ZXJzLCBhcyB0aGUgZXhlY3V0b3IgaG9sZHMgdGhlbSBhdCB0aGUgcGF1c2UuICovXG5leHBvcnQgaW50ZXJmYWNlIFBhdXNlZFJ1biB7XG4gIHJlYWRvbmx5IHJ1bklkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGV4ZWN1dGlvbkNvdW50OiBudW1iZXI7XG4gIHJlYWRvbmx5IHZpc2l0Q291bnRzOiBSZWFkb25seU1hcDxzdHJpbmcsIG51bWJlcj47XG4gIC8qKiBUaGUgcnVuJ3MgcmVkYWN0aW9uIG1hcmtzIOKAlCBuYW1lcyBvbmx5IChgUmVkYWN0aW9uUnVsZSDCtyBtYXJrc0ZvckNoZWNrcG9pbnRgKTsgYWJzZW50IHdoZW4gbm9uZS4gKi9cbiAgcmVhZG9ubHkgcmVkYWN0aW9uTWFya3M/OiBSZWRhY3Rpb25NYXJrcztcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGZ1bGx5IERFVEFDSEVEIGNoZWNrcG9pbnQgZnJvbSBhIGNhdWdodCBQYXVzZVNpZ25hbC5cbiAqXG4gKiBFdmVyeSBmaWVsZCBpcyBkZWVwLWNvcGllZCB2aWEgb25lIGBzdHJ1Y3R1cmVkQ2xvbmVgIG9mIHRoZSBhc3NlbWJsZWRcbiAqIGNoZWNrcG9pbnQsIGJlY2F1c2UgdGhlIHJhdyBwaWVjZXMgYWxpYXMgbGl2ZSBlbmdpbmUgc3RhdGU6XG4gKlxuICogICAtIGBzaGFyZWRTdGF0ZWAgSVMgYFNoYXJlZE1lbW9yeWAncyBjdXJyZW50IGdlbmVyYXRpb24g4oCUIG5ldmVyIGVkaXRlZCxcbiAqICAgICBidXQgKGNvcHktb24td3JpdGUsIDkuMjkuMCkgZXZlcnkgbGF0ZXIgZ2VuZXJhdGlvbiBzaGFyZXMgaXRzXG4gKiAgICAgdW5jaGFuZ2VkIHN1YnRyZWVzLCBzbyBhIGNoZWNrcG9pbnQgdGhhdCBhbGlhc2VkIGl0IHdvdWxkIGFsaWFzIHRoZVxuICogICAgIHJlc3VtZWQgcnVuJ3Mgc3RhdGUgdG9vLlxuICogICAtIGBleGVjdXRpb25UcmVlYCBub2RlcyBhcmUgZnJlc2gsIGJ1dCB0aGVpciBgbG9nc2AvYGVycm9yc2AvYG1ldHJpY3NgL1xuICogICAgIGBldmFsc2AvYHN0YWdlUmVhZHNgL2BmbG93TWVzc2FnZXNgIGZpZWxkcyByZWZlcmVuY2UgbGl2ZVxuICogICAgIGBEaWFnbm9zdGljQ29sbGVjdG9yYCBiYWdzIHRoYXQga2VlcCBhY2N1bXVsYXRpbmcgb24gc2FtZS1leGVjdXRvclxuICogICAgIHJlc3VtZS5cbiAqICAgLSBgc3ViZmxvd1N0YXRlc2AgdmFsdWVzIGFyZSBzaGFsbG93IGNvcGllcyB3aG9zZSBORVNURUQgb2JqZWN0cyBhbGlhc1xuICogICAgIHN1YmZsb3cgbWVtb3J5LCBhbmQgdGhleSBnZXQgc2VlZGVkIGJhY2sgaW50byBsaXZlIHJ1bnRpbWVzIG9uIHJlc3VtZS5cbiAqICAgLSBgc3ViZmxvd1Jlc3VsdHNgIHZhbHVlcyBzdGF5IHJlZmVyZW5jZWQgYnkgdGhlIHRyYXZlcnNlcidzIHJlc3VsdHMgbWFwLlxuICpcbiAqIFRoZSBjaGVja3BvaW50IGlzIHBlcnNpc3RlZCBieSBjb250cmFjdCAoXCJzdG9yZSBpbiBSZWRpcy9Qb3N0Z3Jlc1wiKSDigJQgaXRcbiAqIG11c3QgbmV2ZXIgc2hhcmUgc3RydWN0dXJlIHdpdGggdGhlIGVuZ2luZS4gUGF1c2UgaXMgbm90IGEgaG90IHBhdGg7IHRoZVxuICogY2xvbmUgY29zdCBpcyBpcnJlbGV2YW50LlxuICpcbiAqIE9uIGNsb25lIGZhaWx1cmUgdGhlIGRpYWdub3N0aWMgYmFncyBhcmUgc2FuaXRpemVkICh0aGUgbGl2ZSBlbmdpbmUgYmFnc1xuICogYXJlIG5ldmVyIHRvdWNoZWQpIGFuZCB0aGUgY2xvbmUgcmV0cmllZDsgaWYgdGhlIHJldHJ5IFNUSUxMIGZhaWxzLCB0aGVcbiAqIHZpb2xhdGlvbiBpcyBpbiBjb25zdW1lci1vd25lZCBkYXRhIChyZWFsaXN0aWNhbGx5IGBwYXVzZURhdGFgIOKAlCBhIGZ1bmN0aW9uXG4gKiBjYW4gbmV2ZXIgcmVhY2ggc2hhcmVkIHN0YXRlOiB0aGUgcmVjb3JkJ3MgY2xvbmUgYXQgY29tbWl0IHJlZnVzZXMgaXQpIGFuZCBhXG4gKiBERVNDUklQVElWRSBjb250cmFjdCBlcnJvciBuYW1lcyB0aGUgb2ZmZW5kaW5nIGNoZWNrcG9pbnQgZmllbGQocykuXG4gKlxuICogU3ViZmxvdyBzY29wZSBjYXB0dXJlIChgc3ViZmxvd1N0YXRlc2ApIHN1cnZpdmVzIE9OTFkgb24gdGhlIHNpZ25hbCDigJQgdGhlXG4gKiBuZXN0ZWQgcnVudGltZXMgYXJlIEdDJ2QgYXMgdGhlIHN0YWNrIHVud2luZHMuIFByb21vdGluZyBpdCBvbnRvIHRoZVxuICogY2hlY2twb2ludCBoZXJlIGxldHMgY3Jvc3MtZXhlY3V0b3IgcmVzdW1lIHJlc3RvcmUgcHJlLXBhdXNlIHN1YmZsb3dcbiAqIHNjb3BlIChlLmcuIGFuIEFnZW50J3MgYHNjb3BlLmhpc3RvcnlgKS4gRW1wdHkgYHt9YCBmb3Igcm9vdC1sZXZlbCBwYXVzZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBhdXNlQ2hlY2twb2ludChcbiAgc2lnbmFsOiBQYXVzZVNpZ25hbCxcbiAgdHJhdmVyc2VyOiBGbG93Y2hhcnRUcmF2ZXJzZXI8YW55LCBhbnk+LFxuICBydW46IFBhdXNlZFJ1bixcbik6IEZsb3djaGFydENoZWNrcG9pbnQge1xuICAvLyBFdmVyeSBwYXVzZSB0aGF0IHBhdXNlZCBpbiBUSElTIHJ1biBpcyBuYW1lZCBieSBpdDsgYSBzaWJsaW5nIHJhaXNlZCBhZ2FpblxuICAvLyBvbiByZXN1bWUga2VlcHMgdGhlIHJ1biBpdCBvcmlnaW5hbGx5IHBhdXNlZCBpbi5cbiAgc2lnbmFsLmNvbXBsZXRlRXhlY3V0aW9uKHJ1bi5ydW5JZCk7XG4gIGNvbnN0IHNuYXBzaG90ID0gdHJhdmVyc2VyLmdldFNuYXBzaG90KCk7XG4gIGNvbnN0IGxlYW5TdWJmbG93UmVzdWx0cyA9IGxlYW5TdWJmbG93UmVzdWx0c09mKHRyYXZlcnNlci5nZXRTdWJmbG93UmVzdWx0cygpKTtcbiAgY29uc3QgY2hlY2twb2ludCA9IHtcbiAgICAvLyBUaGUgZm9ybWF0ICg5LjM5LjApIOKAlCByZWFkIGJhY2sgYnkgYHBhdXNlL3JlY29yZC50cyDCtyBkZWNvZGVDaGVja3BvaW50YC5cbiAgICBjaGVja3BvaW50VmVyc2lvbjogQ0hFQ0tQT0lOVF9WRVJTSU9OLFxuICAgIHNoYXJlZFN0YXRlOiBzbmFwc2hvdC5zaGFyZWRTdGF0ZSxcbiAgICBleGVjdXRpb25UcmVlOiBzbmFwc2hvdC5leGVjdXRpb25UcmVlLFxuICAgIHBhdXNlZFN0YWdlSWQ6IHNpZ25hbC5zdGFnZUlkLFxuICAgIC8vIFRoZSBwYXVzZWQgRVhFQ1VUSU9OICg5LjM3LjApIOKAlCBhIHF1ZXVlZCBzaWJsaW5nIHJhaXNlZCBvbiByZXN1bWVcbiAgICAvLyBjYXJyaWVzIHRoZSBydW4gaXQgT1JJR0lOQUxMWSBwYXVzZWQgaW4uXG4gICAgLi4uKHNpZ25hbC5wYXVzZWRFeGVjdXRpb24gJiYgeyBwYXVzZWRFeGVjdXRpb246IHNpZ25hbC5wYXVzZWRFeGVjdXRpb24gfSksXG4gICAgc3ViZmxvd1BhdGg6IHNpZ25hbC5zdWJmbG93UGF0aCxcbiAgICBwYXVzZURhdGE6IHNpZ25hbC5wYXVzZURhdGEsXG4gICAgc3ViZmxvd1N0YXRlczogc2lnbmFsLnN1YmZsb3dTdGF0ZXMsXG4gICAgLy8gQ291bnRlciBjb250aW51aXR5IOKAlCBzZWVkZWQgYmFjayBpbiByZXN1bWUoKSBzbyBydW50aW1lU3RhZ2VJZHMgc3RheVxuICAgIC8vIHVuaXF1ZSBhbmQgbG9vcEl0ZXJhdGlvbiBzdGF5cyBtb25vdG9uaWMgYWNyb3NzIGEgQ1JPU1MtZXhlY3V0b3IgcmVzdW1lXG4gICAgLy8gKGJvdGggYXJlIHBsYWluIG51bWJlci9yZWNvcmQsIHNvIHRoZXkgcmlkZSB0aGUgc2luZ2xlIHN0cnVjdHVyZWRDbG9uZVxuICAgIC8vIGJlbG93IHVudG91Y2hlZCkuIFNlZSB0ZXN0L2xpYi9wYXVzZS9yZXN1bWUtZXhlY3V0aW9uLWNvdW50ZXItY29udGludWl0eS50ZXN0LnRzLlxuICAgIGV4ZWN1dGlvbkNvdW50OiBydW4uZXhlY3V0aW9uQ291bnQsXG4gICAgdmlzaXRDb3VudHM6IE9iamVjdC5mcm9tRW50cmllcyhydW4udmlzaXRDb3VudHMpLFxuICAgIC4uLihPYmplY3Qua2V5cyhsZWFuU3ViZmxvd1Jlc3VsdHMpLmxlbmd0aCA+IDAgJiYgeyBzdWJmbG93UmVzdWx0czogbGVhblN1YmZsb3dSZXN1bHRzIH0pLFxuICAgIC8vIEludm9rZXIgY29udGV4dCDigJQgY29sbGVjdGVkIGR1cmluZyB0cmF2ZXJzYWwgYnViYmxlLXVwIChub3QgdHJlZS13YWxrZWQpLlxuICAgIC8vIChgY29udGludWF0aW9uU3RhZ2VJZGAgaXMgbGVnYWN5LW9ubHkgc2luY2UgOS4zOS4wOiBubyBsb25nZXIgd3JpdHRlbi4pXG4gICAgLi4uKHNpZ25hbC5pbnZva2VyU3RhZ2VJZCAmJiB7IGludm9rZXJTdGFnZUlkOiBzaWduYWwuaW52b2tlclN0YWdlSWQgfSksXG4gICAgLy8gUGFyYWxsZWwgc2libGluZ3MnIHBhdXNlcyBmcm9tIHRoZSBzYW1lIGZhbi1vdXQsIHdhaXRpbmcgdGhlaXIgdHVyblxuICAgIC8vICg5LjI4LjApLiBBYnNlbnQgd2hlbiBvbmx5IG9uZSBjaGlsZCBwYXVzZWQg4oCUIHRoZSBzaGFwZSBldmVyeVxuICAgIC8vIGVhcmxpZXIgY2hlY2twb2ludCBoYXMuXG4gICAgLi4uKHNpZ25hbC5wZW5kaW5nUGF1c2VzLmxlbmd0aCA+IDAgJiYgeyBwZW5kaW5nUGF1c2VzOiBzaWduYWwucGVuZGluZ1BhdXNlcyB9KSxcbiAgICAvLyBIT1cgdGhlIHBhdXNlIHdhcyByYWlzZWQuIE9uZSBjaGVja3BvaW50IHNoYXBlLCBvbmUgZXh0cmEgb3B0aW9uYWxcbiAgICAvLyBmaWVsZCDigJQgYW4gaW50ZXJydXB0KCkgcGF1c2UgaXMgbm90IGEgc2Vjb25kIGtpbmQgb2YgY2hlY2twb2ludCwgaXQgaXNcbiAgICAvLyB0aGUgc2FtZSBjaGVja3BvaW50IHRoYXQgcmVzdW1lKCkgcmUtZW50ZXJzIGRpZmZlcmVudGx5IChzdGFnZSB0b3AgdnNcbiAgICAvLyByZXN1bWVGbikuIEFic2VudCBmb3IgZXZlcnkgcHJlLTkuMTQuMCBjaGVja3BvaW50LCB3aGljaCBpcyBjb3JyZWN0LlxuICAgIC4uLihzaWduYWwucGF1c2VkQnkgJiYgeyBwYXVzZWRCeTogc2lnbmFsLnBhdXNlZEJ5IH0pLFxuICAgIC8vIFRoZSByZWRhY3Rpb24gdGhlIHBhdXNlZCBydW4gaGFkIG1hZGUg4oCUIE5BTUVTIG9ubHkgKG1hcmtzLCBhIG1hcHBlcidzIHRhaW50cywgaW5oZXJpdGVkXG4gICAgLy8gZmllbGRzKS4gUmVzdW1lIHNlZWRzIHRoZSByZXN1bWVkIHJ1bidzIHJ1bGUgd2l0aCB0aGVtLiBBYnNlbnQgd2hlbiBub3RoaW5nIHdhcyBtYXJrZWQuXG4gICAgLi4uKHJ1bi5yZWRhY3Rpb25NYXJrcyAmJiB7IHJlZGFjdGlvbk1hcmtzOiBydW4ucmVkYWN0aW9uTWFya3MgfSksXG4gICAgcGF1c2VkQXQ6IERhdGUubm93KCksXG4gIH07XG4gIHRyeSB7XG4gICAgcmV0dXJuIHN0cnVjdHVyZWRDbG9uZShjaGVja3BvaW50KTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gTm9uLWNsb25lYWJsZSBkaWFnbm9zdGljcyBtdXN0IG5vdCBzd2FsbG93IHRoZSBwYXVzZSDigJQgc2FuaXRpemUgdGhlXG4gICAgLy8gZXhlY3V0aW9uVHJlZSdzIGJhZ3MgKG1hcmtlcnMgcmVwbGFjZSB0aGUgb2ZmZW5kZXJzKSBhbmQgcmV0cnkuXG4gICAgdHJ5IHtcbiAgICAgIGNoZWNrcG9pbnQuZXhlY3V0aW9uVHJlZSA9IHNhbml0aXplRGlhZ25vc3RpY0JhZ3MoY2hlY2twb2ludC5leGVjdXRpb25UcmVlIGFzIFN0YWdlU25hcHNob3QpO1xuICAgICAgcmV0dXJuIHN0cnVjdHVyZWRDbG9uZShjaGVja3BvaW50KTtcbiAgICB9IGNhdGNoIChyZXRyeUVycm9yKSB7XG4gICAgICAvLyBHZW51aW5lIEpTT04tc2FmZSBjb250cmFjdCB2aW9sYXRpb24gaW4gY29uc3VtZXItb3duZWQgZGF0YS5cbiAgICAgIHRocm93IGRlc2NyaWJlQ2hlY2twb2ludENsb25lRmFpbHVyZShjaGVja3BvaW50LCByZXRyeUVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBMZWFuIHN1YmZsb3dSZXN1bHRzIGZvciB0aGUgY2hlY2twb2ludCAoZGVzaWduOiBkb2NzL2Rlc2lnbi9zdWJmbG93LWNvbW1pdC12aXNpYmlsaXR5Lm1kKTpcbiAqICAgLSBEUk9QIHRoZSBwZXItaXRlcmF0aW9uIG1vdW50LXJ1bnRpbWVTdGFnZUlkIGtleXMgKCcjJykgdGhhdCB0aGUgc25hcHNob3QgZHVhbC1rZXlzIOKAlFxuICogICAgIHRoZXkgd291bGQgRE9VQkxFIHRoZSBjaGVja3BvaW50LCBhbmQgcmVzdW1lIHJlc3RvcmVzIHNjb3BlIGZyb20gYHN1YmZsb3dTdGF0ZXNgLCBub3QgdGhlc2UuXG4gKiAgIC0gU1RSSVAgZWFjaCBzdWJmbG93J3MgYHRyZWVDb250ZXh0Lmhpc3RvcnlgIOKAlCByZXN1bWUgTkVWRVIgcmVhZHMgYHN1YmZsb3dSZXN1bHRzYCAoaXRcbiAqICAgICByZXN0b3JlcyBmcm9tIGBzdWJmbG93U3RhdGVzYCArIGBzaGFyZWRTdGF0ZWApLCBzbyB0aGUgcGVyLXN1YmZsb3cgY29tbWl0IGxvZyBpcyBwdXJlXG4gKiAgICAgY2hlY2twb2ludCBibG9hdC4gVGhlIGZsYXQgYWdlbnQncyBjaGVja3BvaW50IGNhcnJpZXMgbm8gY29tbWl0IGhpc3RvcnkgZWl0aGVyIOKGkiBzeW1tZXRyaWMuXG4gKi9cbmZ1bmN0aW9uIGxlYW5TdWJmbG93UmVzdWx0c09mKHNmUmVzdWx0czogTWFwPHN0cmluZywgU3ViZmxvd1Jlc3VsdD4pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gIGNvbnN0IGxlYW5TdWJmbG93UmVzdWx0czogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2Ygc2ZSZXN1bHRzKSB7XG4gICAgaWYgKGlzRXhlY3V0aW9uS2V5KGtleSkpIGNvbnRpbnVlOyAvLyBwZXItaXRlcmF0aW9uIGtleXMgYXJlIHNuYXBzaG90LW9ubHlcbiAgICBjb25zdCB2ID0gdmFsdWUgYXMgdW5rbm93biBhcyB7IHRyZWVDb250ZXh0PzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfTtcbiAgICBpZiAodj8udHJlZUNvbnRleHQpIHtcbiAgICAgIGNvbnN0IHRyZWVDdHhSZXN0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgICAgZm9yIChjb25zdCBjayBvZiBPYmplY3Qua2V5cyh2LnRyZWVDb250ZXh0KSkge1xuICAgICAgICBpZiAoY2sgIT09ICdoaXN0b3J5JykgdHJlZUN0eFJlc3RbY2tdID0gdi50cmVlQ29udGV4dFtja107IC8vIHN0cmlwIHRoZSBwZXItc3ViZmxvdyBjb21taXQgbG9nXG4gICAgICB9XG4gICAgICBsZWFuU3ViZmxvd1Jlc3VsdHNba2V5XSA9IHsgLi4uKHZhbHVlIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLCB0cmVlQ29udGV4dDogdHJlZUN0eFJlc3QgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGVhblN1YmZsb3dSZXN1bHRzW2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGxlYW5TdWJmbG93UmVzdWx0cztcbn1cblxuLyoqIFRoZSBTdGFnZVNuYXBzaG90IGZpZWxkcyB3cml0dGVuIGJ5IGAkZGVidWdgL2AkZXJyb3JgL2AkbWV0cmljYC9gJGV2YWxgLiAqL1xuY29uc3QgRElBR05PU1RJQ19CQUdTID0gWydsb2dzJywgJ2Vycm9ycycsICdtZXRyaWNzJywgJ2V2YWxzJ10gYXMgY29uc3Q7XG5cbi8qKiBgdHJ1ZWAgd2hlbiBgc3RydWN0dXJlZENsb25lYCBhY2NlcHRzIHRoZSB2YWx1ZSBhcy1pcy4gKi9cbmZ1bmN0aW9uIGlzQ2xvbmVhYmxlKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgc3RydWN0dXJlZENsb25lKHZhbHVlKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKiBIdW1hbi1yZWFkYWJsZSBraW5kIGZvciB0aGUgYFtub24tc2VyaWFsaXphYmxlOiDigKZdYCBtYXJrZXIuICovXG5mdW5jdGlvbiBkZXNjcmliZUtpbmQodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICBpZiAodmFsdWUgPT09IG51bGwpIHJldHVybiAnbnVsbCc7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09ICdvYmplY3QnKSByZXR1cm4gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gdmFsdWUuY29uc3RydWN0b3I/Lm5hbWUgPz8gJ29iamVjdCc7XG59XG5cbi8qKiBQbGFpbiBkYXRhIGNvbnRhaW5lciB3ZSBjYW4gcmVidWlsZCBlbnRyeS1ieS1lbnRyeSB3aXRob3V0IGx5aW5nIGFib3V0IHRoZSB0eXBlLiAqL1xuZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZTogb2JqZWN0KTogYm9vbGVhbiB7XG4gIGNvbnN0IHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbHVlKSBhcyBvYmplY3QgfCBudWxsO1xuICByZXR1cm4gcHJvdG8gPT09IE9iamVjdC5wcm90b3R5cGUgfHwgcHJvdG8gPT09IG51bGw7XG59XG5cbi8qKlxuICogRGVlcC1yZXBsYWNlIG5vbi1jbG9uZWFibGUgdmFsdWVzIHdpdGggYCdbbm9uLXNlcmlhbGl6YWJsZTogPGtpbmQ+XSdgXG4gKiBtYXJrZXIgc3RyaW5ncywgcHJlc2VydmluZyBldmVyeXRoaW5nIGBzdHJ1Y3R1cmVkQ2xvbmVgIGFjY2VwdHMuXG4gKlxuICogRmFzdCBwYXRoOiBhIGNsb25lYWJsZSB2YWx1ZSBpcyByZXR1cm5lZCBBUy1JUyAobm8gY29weSDigJQgdGhlIGNhbGxlclxuICogY2xvbmVzIHRoZSB3aG9sZSBjaGVja3BvaW50IHJpZ2h0IGFmdGVyKS4gT25seSBjb250YWluZXJzIHRoYXQgYWN0dWFsbHlcbiAqIGhvbGQgYSBub24tY2xvbmVhYmxlIGxlYWYgYXJlIHJlYnVpbHQsIGFuZCBvbmx5IEtOT1dOIGNvbnRhaW5lciBzaGFwZXNcbiAqIChhcnJheSAvIE1hcCAvIFNldCAvIHBsYWluIG9iamVjdCkgYXJlIHJlYnVpbHQgZW50cnktYnktZW50cnkg4oCUIGV4b3RpY1xuICogbm9uLWNsb25lYWJsZXMgKFByb21pc2UsIFdlYWtNYXAsIGNsYXNzIGluc3RhbmNlcyBob2xkaW5nIGEgZnVuY3Rpb24sIOKApilcbiAqIGJlY29tZSBhIHR5cGVkIG1hcmtlciByYXRoZXIgdGhhbiBhIG1pc2xlYWRpbmcgZW1wdHkgc2hlbGwuIFB1cmUgY3ljbGVzXG4gKiBwYXNzIHRoZSBmYXN0IHBhdGggdW50b3VjaGVkIChgc3RydWN0dXJlZENsb25lYCBzdXBwb3J0cyB0aGVtKTsgYSBjeWNsZVxuICogaXMgb25seSBicm9rZW4g4oCUIHdpdGggYSBtYXJrZXIg4oCUIHdoZW4gaXQgc2hhcmVzIGEgY29udGFpbmVyIHdpdGggYVxuICogbm9uLWNsb25lYWJsZSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gc2FuaXRpemVWYWx1ZSh2YWx1ZTogdW5rbm93biwgc2VlbjogV2Vha1NldDxvYmplY3Q+KTogdW5rbm93biB7XG4gIGlmIChpc0Nsb25lYWJsZSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgaWYgKHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICBpZiAoc2Vlbi5oYXModmFsdWUpKSByZXR1cm4gJ1tub24tc2VyaWFsaXphYmxlOiBjaXJjdWxhcl0nO1xuICAgIHNlZW4uYWRkKHZhbHVlKTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS5tYXAoKHYpID0+IHNhbml0aXplVmFsdWUodiwgc2VlbikpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgIHJldHVybiBuZXcgTWFwKFsuLi52YWx1ZV0ubWFwKChbaywgdl0pID0+IFtzYW5pdGl6ZVZhbHVlKGssIHNlZW4pLCBzYW5pdGl6ZVZhbHVlKHYsIHNlZW4pXSkpO1xuICAgIH1cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgIHJldHVybiBuZXcgU2V0KFsuLi52YWx1ZV0ubWFwKCh2KSA9PiBzYW5pdGl6ZVZhbHVlKHYsIHNlZW4pKSk7XG4gICAgfVxuICAgIGlmIChpc1BsYWluT2JqZWN0KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyh2YWx1ZSkubWFwKChbaywgdl0pID0+IFtrLCBzYW5pdGl6ZVZhbHVlKHYsIHNlZW4pXSkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYFtub24tc2VyaWFsaXphYmxlOiAke2Rlc2NyaWJlS2luZCh2YWx1ZSl9XWA7XG59XG5cbi8qKlxuICogV2FsayBhIGBTdGFnZVNuYXBzaG90YCB0cmVlICh2aWEgYG5leHRgICsgYGNoaWxkcmVuYCkgYW5kIHNhbml0aXplIHRoZSBmb3VyXG4gKiBkaWFnbm9zdGljIGJhZ3Mgb24gZXZlcnkgbm9kZSBJTiBQTEFDRS5cbiAqXG4gKiBJbi1wbGFjZSBpcyBzYWZlIGFuZCBpbnRlbnRpb25hbDogYFN0YWdlQ29udGV4dC5nZXRTbmFwc2hvdCgpYCBidWlsZHMgZnJlc2hcbiAqIG5vZGUgb2JqZWN0cyBvbiBldmVyeSBjYWxsLCBidXQgdGhlIGJhZyBmaWVsZHMgb24gdGhvc2UgZnJlc2ggbm9kZXMgQUxJQVNcbiAqIHRoZSBsaXZlIGBEaWFnbm9zdGljQ29sbGVjdG9yYCBiYWdzLiBXZSByZXBsYWNlIHRoZSBub2RlJ3MgYmFnIFJFRkVSRU5DRVxuICogd2l0aCBhIHNhbml0aXplZCBjb3B5IOKAlCB0aGUgbGl2ZSBlbmdpbmUgYmFncyBhcmUgbmV2ZXIgbXV0YXRlZCwgc28gYVxuICogc2FtZS1leGVjdXRvciByZXN1bWUga2VlcHMgdGhlIG9yaWdpbmFsIGRpYWdub3N0aWMgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBzYW5pdGl6ZURpYWdub3N0aWNCYWdzKHRyZWU6IFN0YWdlU25hcHNob3QpOiBTdGFnZVNuYXBzaG90IHtcbiAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0PG9iamVjdD4oKTtcbiAgY29uc3QgdmlzaXQgPSAobm9kZTogU3RhZ2VTbmFwc2hvdCk6IHZvaWQgPT4ge1xuICAgIGZvciAoY29uc3QgYmFnIG9mIERJQUdOT1NUSUNfQkFHUykge1xuICAgICAgY29uc3QgYmFnVmFsdWUgPSBub2RlW2JhZ107XG4gICAgICBpZiAoYmFnVmFsdWUgIT09IHVuZGVmaW5lZCAmJiAhaXNDbG9uZWFibGUoYmFnVmFsdWUpKSB7XG4gICAgICAgIG5vZGVbYmFnXSA9IHNhbml0aXplVmFsdWUoYmFnVmFsdWUsIHNlZW4pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAobm9kZS5uZXh0KSB2aXNpdChub2RlLm5leHQpO1xuICAgIGlmIChub2RlLmNoaWxkcmVuKSBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4pIHZpc2l0KGNoaWxkKTtcbiAgfTtcbiAgdmlzaXQodHJlZSk7XG4gIHJldHVybiB0cmVlO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBERVNDUklQVElWRSBlcnJvciBmb3IgYSBjaGVja3BvaW50IHRoYXQgc3RpbGwgY2Fubm90IGJlIGNsb25lZFxuICogYWZ0ZXIgZGlhZ25vc3RpYy1iYWcgc2FuaXRpemF0aW9uIOKAlCBpLmUuIHRoZSBub24tY2xvbmVhYmxlIHZhbHVlIGxpdmVzIGluXG4gKiBjb25zdW1lci1vd25lZCBkYXRhIChhIGdlbnVpbmUgSlNPTi1zYWZlIGNvbnRyYWN0IHZpb2xhdGlvbikuIFByb2JlcyBlYWNoXG4gKiB0b3AtbGV2ZWwgY2hlY2twb2ludCBmaWVsZCBpbmRpdmlkdWFsbHkgc28gdGhlIG1lc3NhZ2UgbmFtZXMgdGhlIG9mZmVuZGluZ1xuICogZmllbGQgZmFtaWx5LiBOZXZlciBsZXRzIGEgbmFrZWQgYERhdGFDbG9uZUVycm9yYCBlc2NhcGUuXG4gKi9cbmZ1bmN0aW9uIGRlc2NyaWJlQ2hlY2twb2ludENsb25lRmFpbHVyZShjaGVja3BvaW50OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgY2F1c2U6IHVua25vd24pOiBFcnJvciB7XG4gIGNvbnN0IGZhaWxpbmcgPSBPYmplY3QuZW50cmllcyhjaGVja3BvaW50KVxuICAgIC5maWx0ZXIoKFssIHZhbHVlXSkgPT4gIWlzQ2xvbmVhYmxlKHZhbHVlKSlcbiAgICAubWFwKChbZmllbGRdKSA9PiBmaWVsZCk7XG4gIGNvbnN0IGZpZWxkcyA9IGZhaWxpbmcubGVuZ3RoID4gMCA/IGZhaWxpbmcuam9pbignLCAnKSA6ICd1bmtub3duJztcbiAgcmV0dXJuIG5ldyBFcnJvcihcbiAgICAnRmxvd0NoYXJ0RXhlY3V0b3I6IGNhbm5vdCBidWlsZCB0aGUgcGF1c2UgY2hlY2twb2ludCDigJQgbm9uLXNlcmlhbGl6YWJsZSB2YWx1ZShzKSBpbiAnICtcbiAgICAgIGBjaGVja3BvaW50IGZpZWxkKHMpOiAke2ZpZWxkc30uIFRoZSBjaGVja3BvaW50IGNvbnRyYWN0IGlzIEpTT04tc2FmZSAobm8gZnVuY3Rpb25zLCBubyBgICtcbiAgICAgIFwiY2xhc3MgaW5zdGFuY2VzKS4gQ2hlY2sgdGhlIHBhdXNlRGF0YSByZXR1cm5lZCBieSB0aGUgcGF1c2FibGUgc3RhZ2UncyBleGVjdXRlKCksIGFuZCBhbnkgXCIgK1xuICAgICAgJ3N1YmZsb3cgc3RhdGUgY2FwdHVyZWQgYXQgdGhlIHBhdXNlLiBEaWFnbm9zdGljIHZhbHVlcyBmcm9tICRkZWJ1Zy8kbWV0cmljLyRlcnJvci8kZXZhbCAnICtcbiAgICAgICdhcmUgc2FuaXRpemVkIGF1dG9tYXRpY2FsbHkgYW5kIG5ldmVyIGNhdXNlIHRoaXMgZXJyb3IuICcgK1xuICAgICAgJ1NlZSBkb2NzL2d1aWRlcy9leGVjdXRpb24tbW9kZWwubWQgKFwiUGF1c2UgLyByZXN1bWUg4oCUIHdoYXQgYSBjaGVja3BvaW50IGNhcHR1cmVzXCIpLicsXG4gICAgeyBjYXVzZSB9LFxuICApO1xufVxuIl19
142
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcnVubmVyL2NoZWNrcG9pbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQ0c7QUFHSCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQVl4RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLE1BQW1CLEVBQ25CLFNBQXVDLEVBQ3ZDLEdBQWM7SUFFZCw2RUFBNkU7SUFDN0UsbURBQW1EO0lBQ25ELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEMsTUFBTSxVQUFVLEdBQUc7UUFDakIsa0VBQWtFO1FBQ2xFLGlCQUFpQixFQUFFLGtCQUFrQjtRQUNyQyxXQUFXLEVBQUUsU0FBUyxDQUFDLFVBQVUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUU7UUFDMUQsYUFBYSxFQUFFLE1BQU0sQ0FBQyxPQUFPO1FBQzdCLG9FQUFvRTtRQUNwRSwyQ0FBMkM7UUFDM0MsR0FBRyxDQUFDLE1BQU0sQ0FBQyxlQUFlLElBQUksRUFBRSxlQUFlLEVBQUUsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQzFFLFdBQVcsRUFBRSxNQUFNLENBQUMsV0FBVztRQUMvQixTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVM7UUFDM0IsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhO1FBQ25DLHVFQUF1RTtRQUN2RSwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ3pFLG9GQUFvRjtRQUNwRixjQUFjLEVBQUUsR0FBRyxDQUFDLGNBQWM7UUFDbEMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQztRQUNoRCw0RUFBNEU7UUFDNUUsMEVBQTBFO1FBQzFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsY0FBYyxJQUFJLEVBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN2RSxzRUFBc0U7UUFDdEUsZ0VBQWdFO1FBQ2hFLDBCQUEwQjtRQUMxQixHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMvRSxxRUFBcUU7UUFDckUseUVBQXlFO1FBQ3pFLHdFQUF3RTtRQUN4RSx1RUFBdUU7UUFDdkUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3JELDBGQUEwRjtRQUMxRiwwRkFBMEY7UUFDMUYsR0FBRyxDQUFDLEdBQUcsQ0FBQyxjQUFjLElBQUksRUFBRSxjQUFjLEVBQUUsR0FBRyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ2pFLFFBQVEsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFO0tBQ3JCLENBQUM7SUFDRixJQUFJLENBQUM7UUFDSCxPQUFPLGVBQWUsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLCtEQUErRDtRQUMvRCxNQUFNLDhCQUE4QixDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMxRCxDQUFDO0FBQ0gsQ0FBQztBQUVELDZEQUE2RDtBQUM3RCxTQUFTLFdBQVcsQ0FBQyxLQUFjO0lBQ2pDLElBQUksQ0FBQztRQUNILGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBUyw4QkFBOEIsQ0FBQyxVQUFtQyxFQUFFLEtBQWM7SUFDekYsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7U0FDdkMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUMxQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQixNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ25FLE9BQU8sSUFBSSxLQUFLLENBQ2Qsc0ZBQXNGO1FBQ3BGLHdCQUF3QixNQUFNLDJEQUEyRDtRQUN6Riw0RkFBNEY7UUFDNUYsMEZBQTBGO1FBQzFGLDZEQUE2RDtRQUM3RCxxRkFBcUYsRUFDdkYsRUFBRSxLQUFLLEVBQUUsQ0FDVixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogY2hlY2twb2ludCDigJQgdGhlIHBhdXNlIGNoZWNrcG9pbnQsIGJ1aWx0IE9OQ0UgYXQgdGhlIHBhdXNlIChGOSkuXG4gKlxuICogYGJ1aWxkUGF1c2VDaGVja3BvaW50YCBhc3NlbWJsZXMgdGhlIGNoZWNrcG9pbnQgZnJvbSBhIGNhdWdodCBgUGF1c2VTaWduYWxgXG4gKiBhbmQgdGhlIHBhdXNlZCBydW4sIHN0YW1wZWQgd2l0aCB0aGUgZm9ybWF0IHRoZSBPTkUgY29kZWMgcmVhZHMgYmFja1xuICogKGBwYXVzZS9yZWNvcmQudHNgIMK3IGBDSEVDS1BPSU5UX1ZFUlNJT05gIC8gYGRlY29kZUNoZWNrcG9pbnRgKSwgYW5kXG4gKiBkZXRhY2hlcyBpdCB3aXRoIG9uZSBgc3RydWN0dXJlZENsb25lYC5cbiAqXG4gKiBMRUFOIChmb3JtYXQgMikuIFRoZSBjaGVja3BvaW50IGhvbGRzIHdoYXQgYHJlc3VtZSgpYCByZWFkcyBhbmQgdGhlIHBhdXNlJ3NcbiAqIG93biByZWNvcmQsIG5vdGhpbmcgZWxzZTpcbiAqXG4gKiAgIHJlYWQgYnkgcmVzdW1lICB0aGUgY3Vyc29yIChgcGF1c2VkU3RhZ2VJZGAsIGBzdWJmbG93UGF0aGAsIGBwYXVzZWRCeWApLFxuICogICAgICAgICAgICAgICAgICAgdGhlIHN0YXRlIChgc2hhcmVkU3RhdGVgLCBhbmQgYHN1YmZsb3dTdGF0ZXNgIOKAlCBvbmUgY2FwdHVyZVxuICogICAgICAgICAgICAgICAgICAgcGVyIHN1YmZsb3cgT04gdGhlIHBhdXNlIHBhdGgpLCB0aGUgY291bnRlcnNcbiAqICAgICAgICAgICAgICAgICAgIChgZXhlY3V0aW9uQ291bnRgLCBgdmlzaXRDb3VudHNgIOKAlCBvbmUgZW50cnkgcGVyIHN0YWdlIGlkKSxcbiAqICAgICAgICAgICAgICAgICAgIHRoZSB3YWl0aW5nIHNpYmxpbmdzIChgcGVuZGluZ1BhdXNlc2ApLCB0aGUgcmVkYWN0aW9uIG5hbWVzXG4gKiAgICAgICAgICAgICAgICAgICAoYHJlZGFjdGlvbk1hcmtzYCksIHRoZSBsaW5rIChgcGF1c2VkRXhlY3V0aW9uYCk7XG4gKiAgIHRoZSByZWNvcmQgICAgICBgcGF1c2VEYXRhYCAodGhlIHF1ZXN0aW9uKSwgYGludm9rZXJTdGFnZUlkYCwgYHBhdXNlZEF0YC5cbiAqXG4gKiBTbyBpdHMgc2l6ZSBpcyB0aGUgc3RhdGUncyBhbmQgdGhlIGNoYXJ0J3MsIG5ldmVyIHRoZSBydW4ncyBsZW5ndGguIEZvcm1hdCAxXG4gKiBhbHNvIGNhcnJpZWQgdGhlIHdob2xlIGV4ZWN1dGlvbiB0cmVlIGFuZCB0aGUgZmluaXNoZWQgc3ViZmxvd3MnIHJlc3VsdHMg4oCUXG4gKiB0aGUgcnVuJ3Mgc2VydmVkIHJlY29yZCwgd2hpY2ggbm8gcmVzdW1lIHJlYWQgYW5kIHdoaWNoIGdyZXcgd2l0aCBldmVyeVxuICogZmluaXNoZWQgaXRlcmF0aW9uIChgYmVuY2gvY2hlY2twb2ludC1zaXplLnRzYDogMTkuMyBNQiBhZnRlciA2MCBhZ2VudFxuICogdHVybnMgd2hvc2UgcmVzdW1hYmxlIHN0YXRlIOKAlCByb290IHBsdXMgY2FwdHVyZXMg4oCUIGlzIDAuMTMgTUI7IHRoZSB0cmVlXG4gKiBhbG9uZSB3YXMgOTclKS4gVGhhdCByZWNvcmQgaXMgYGdldFNuYXBzaG90KClgJ3MuIFBpbm5lZDpcbiAqIHRlc3QvbGliL3BhdXNlL2NoZWNrcG9pbnQtc2l6ZS50ZXN0LnRzLlxuICpcbiAqIFRIRSBMQVcgaG9sZHM6IHRoZSBjaGVja3BvaW50IGtlZXBzIFJFQUwgdmFsdWVzIOKAlCBubyByZWRhY3Rpb24gcG9saWN5IGV2ZXJcbiAqIHRvdWNoZXMgaXQgKGl0IGlzIHdoYXQgdGhlIHJlc3VtZWQgcnVuIGNvbXB1dGVzIG9uKTsgdGhlIG1hcmtzIHRyYXZlbCBhc1xuICogTkFNRVMgb25seS5cbiAqXG4gKiBUaGUgSlNPTi1zYWZlIGNvbnRyYWN0IGdvdmVybnMgd2hhdCBDT05TVU1FUlMgcHV0IGludG8gYSBjaGVja3BvaW50XG4gKiAoYHBhdXNlRGF0YWAsIHNoYXJlZCBzdGF0ZSkuIEEgdmFsdWUgYHN0cnVjdHVyZWRDbG9uZWAgcmVmdXNlcyBjYW4gb25seSBjb21lXG4gKiBmcm9tIHRoZW0g4oCUIHNoYXJlZCBzdGF0ZSBpcyBjbG9uZWQgYXQgZXZlcnkgY29tbWl0LCBzbyBhIGZ1bmN0aW9uIG5ldmVyXG4gKiByZWFjaGVzIGl0LCBhbmQgbm8gZGlhZ25vc3RpYyBiYWcgaXMgY2FycmllZCDigJQgc28gYSBmYWlsZWQgY2xvbmUgYmVjb21lcyBhXG4gKiBERVNDUklQVElWRSBjb250cmFjdCBlcnJvciBuYW1pbmcgdGhlIGZpZWxkIChgZGVzY3JpYmVDaGVja3BvaW50Q2xvbmVGYWlsdXJlYClcbiAqIGluc3RlYWQgb2YgYSBuYWtlZCBgRGF0YUNsb25lRXJyb3JgLlxuICovXG5cbmltcG9ydCB0eXBlIHsgRmxvd2NoYXJ0VHJhdmVyc2VyIH0gZnJvbSAnLi4vZW5naW5lL3RyYXZlcnNhbC9GbG93Y2hhcnRUcmF2ZXJzZXIuanMnO1xuaW1wb3J0IHsgQ0hFQ0tQT0lOVF9WRVJTSU9OIH0gZnJvbSAnLi4vcGF1c2UvcmVjb3JkLmpzJztcbmltcG9ydCB0eXBlIHsgRmxvd2NoYXJ0Q2hlY2twb2ludCwgUGF1c2VTaWduYWwsIFJlZGFjdGlvbk1hcmtzIH0gZnJvbSAnLi4vcGF1c2UvdHlwZXMuanMnO1xuXG4vKiogVGhlIHBhdXNlZCBydW4ncyBjb3VudGVycywgYXMgdGhlIGV4ZWN1dG9yIGhvbGRzIHRoZW0gYXQgdGhlIHBhdXNlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQYXVzZWRSdW4ge1xuICByZWFkb25seSBydW5JZDogc3RyaW5nO1xuICByZWFkb25seSBleGVjdXRpb25Db3VudDogbnVtYmVyO1xuICByZWFkb25seSB2aXNpdENvdW50czogUmVhZG9ubHlNYXA8c3RyaW5nLCBudW1iZXI+O1xuICAvKiogVGhlIHJ1bidzIHJlZGFjdGlvbiBtYXJrcyDigJQgbmFtZXMgb25seSAoYFJlZGFjdGlvblJ1bGUgwrcgbWFya3NGb3JDaGVja3BvaW50YCk7IGFic2VudCB3aGVuIG5vbmUuICovXG4gIHJlYWRvbmx5IHJlZGFjdGlvbk1hcmtzPzogUmVkYWN0aW9uTWFya3M7XG59XG5cbi8qKlxuICogQnVpbGQgYSBmdWxseSBERVRBQ0hFRCwgbGVhbiBjaGVja3BvaW50IGZyb20gYSBjYXVnaHQgUGF1c2VTaWduYWwuXG4gKlxuICogRXZlcnkgZmllbGQgaXMgZGVlcC1jb3BpZWQgdmlhIG9uZSBgc3RydWN0dXJlZENsb25lYCBvZiB0aGUgYXNzZW1ibGVkXG4gKiBjaGVja3BvaW50LCBiZWNhdXNlIHRoZSByYXcgcGllY2VzIGFsaWFzIGxpdmUgZW5naW5lIHN0YXRlOlxuICpcbiAqICAgLSBgc2hhcmVkU3RhdGVgIElTIGBTaGFyZWRNZW1vcnlgJ3MgY3VycmVudCBnZW5lcmF0aW9uIOKAlCBuZXZlciBlZGl0ZWQsXG4gKiAgICAgYnV0IChjb3B5LW9uLXdyaXRlLCA5LjI5LjApIGV2ZXJ5IGxhdGVyIGdlbmVyYXRpb24gc2hhcmVzIGl0c1xuICogICAgIHVuY2hhbmdlZCBzdWJ0cmVlcywgc28gYSBjaGVja3BvaW50IHRoYXQgYWxpYXNlZCBpdCB3b3VsZCBhbGlhcyB0aGVcbiAqICAgICByZXN1bWVkIHJ1bidzIHN0YXRlIHRvby5cbiAqICAgLSBgc3ViZmxvd1N0YXRlc2AgdmFsdWVzIGFyZSBzaGFsbG93IGNvcGllcyB3aG9zZSBORVNURUQgb2JqZWN0cyBhbGlhc1xuICogICAgIHN1YmZsb3cgbWVtb3J5LCBhbmQgdGhleSBnZXQgc2VlZGVkIGJhY2sgaW50byBsaXZlIHJ1bnRpbWVzIG9uIHJlc3VtZS5cbiAqXG4gKiBUaGUgY2hlY2twb2ludCBpcyBwZXJzaXN0ZWQgYnkgY29udHJhY3QgKFwic3RvcmUgaW4gUmVkaXMvUG9zdGdyZXNcIikg4oCUIGl0XG4gKiBtdXN0IG5ldmVyIHNoYXJlIHN0cnVjdHVyZSB3aXRoIHRoZSBlbmdpbmUuXG4gKlxuICogVGhlIHN0YXRlIGlzIHJlYWQgc3RyYWlnaHQgb2ZmIHRoZSByb290IHJ1bnRpbWUncyBzdG9yZSDigJQgbm8gc25hcHNob3QgaXNcbiAqIGJ1aWx0IChhIHNuYXBzaG90IHdvdWxkIGJ1aWxkIHRoZSBleGVjdXRpb24gdHJlZSBhbmQgY29weSB0aGUgY29tbWl0IGxvZyxcbiAqIHdvcmsgcHJvcG9ydGlvbmFsIHRvIHRoZSBydW4ncyBsZW5ndGgsIG9ubHkgdG8gdGhyb3cgYm90aCBhd2F5KS5cbiAqXG4gKiBTdWJmbG93IHNjb3BlIGNhcHR1cmUgKGBzdWJmbG93U3RhdGVzYCkgc3Vydml2ZXMgT05MWSBvbiB0aGUgc2lnbmFsIOKAlCB0aGVcbiAqIG5lc3RlZCBydW50aW1lcyBhcmUgR0MnZCBhcyB0aGUgc3RhY2sgdW53aW5kcy4gUHJvbW90aW5nIGl0IG9udG8gdGhlXG4gKiBjaGVja3BvaW50IGhlcmUgbGV0cyBjcm9zcy1leGVjdXRvciByZXN1bWUgcmVzdG9yZSBwcmUtcGF1c2Ugc3ViZmxvd1xuICogc2NvcGUgKGUuZy4gYW4gQWdlbnQncyBgc2NvcGUuaGlzdG9yeWApLiBUaGUgc2lnbmFsIGNhcHR1cmVzIGEgc3ViZmxvdyBvbmx5XG4gKiBhcyBpdCBidWJibGVzIHRocm91Z2ggdGhhdCBzdWJmbG93J3MgYm91bmRhcnksIHNvIHRoZSBrZXlzIGFyZSBleGFjdGx5IHRoZVxuICogcGF1c2UgcGF0aCdzLiBFbXB0eSBge31gIGZvciByb290LWxldmVsIHBhdXNlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGF1c2VDaGVja3BvaW50KFxuICBzaWduYWw6IFBhdXNlU2lnbmFsLFxuICB0cmF2ZXJzZXI6IEZsb3djaGFydFRyYXZlcnNlcjxhbnksIGFueT4sXG4gIHJ1bjogUGF1c2VkUnVuLFxuKTogRmxvd2NoYXJ0Q2hlY2twb2ludCB7XG4gIC8vIEV2ZXJ5IHBhdXNlIHRoYXQgcGF1c2VkIGluIFRISVMgcnVuIGlzIG5hbWVkIGJ5IGl0OyBhIHNpYmxpbmcgcmFpc2VkIGFnYWluXG4gIC8vIG9uIHJlc3VtZSBrZWVwcyB0aGUgcnVuIGl0IG9yaWdpbmFsbHkgcGF1c2VkIGluLlxuICBzaWduYWwuY29tcGxldGVFeGVjdXRpb24ocnVuLnJ1bklkKTtcbiAgY29uc3QgY2hlY2twb2ludCA9IHtcbiAgICAvLyBUaGUgZm9ybWF0IOKAlCByZWFkIGJhY2sgYnkgYHBhdXNlL3JlY29yZC50cyDCtyBkZWNvZGVDaGVja3BvaW50YC5cbiAgICBjaGVja3BvaW50VmVyc2lvbjogQ0hFQ0tQT0lOVF9WRVJTSU9OLFxuICAgIHNoYXJlZFN0YXRlOiB0cmF2ZXJzZXIuZ2V0UnVudGltZSgpLmdsb2JhbFN0b3JlLmdldFN0YXRlKCksXG4gICAgcGF1c2VkU3RhZ2VJZDogc2lnbmFsLnN0YWdlSWQsXG4gICAgLy8gVGhlIHBhdXNlZCBFWEVDVVRJT04gKDkuMzcuMCkg4oCUIGEgcXVldWVkIHNpYmxpbmcgcmFpc2VkIG9uIHJlc3VtZVxuICAgIC8vIGNhcnJpZXMgdGhlIHJ1biBpdCBPUklHSU5BTExZIHBhdXNlZCBpbi5cbiAgICAuLi4oc2lnbmFsLnBhdXNlZEV4ZWN1dGlvbiAmJiB7IHBhdXNlZEV4ZWN1dGlvbjogc2lnbmFsLnBhdXNlZEV4ZWN1dGlvbiB9KSxcbiAgICBzdWJmbG93UGF0aDogc2lnbmFsLnN1YmZsb3dQYXRoLFxuICAgIHBhdXNlRGF0YTogc2lnbmFsLnBhdXNlRGF0YSxcbiAgICBzdWJmbG93U3RhdGVzOiBzaWduYWwuc3ViZmxvd1N0YXRlcyxcbiAgICAvLyBDb3VudGVyIGNvbnRpbnVpdHkg4oCUIHNlZWRlZCBiYWNrIGluIHJlc3VtZSgpIHNvIHJ1bnRpbWVTdGFnZUlkcyBzdGF5XG4gICAgLy8gdW5pcXVlIGFuZCBsb29wSXRlcmF0aW9uIHN0YXlzIG1vbm90b25pYyBhY3Jvc3MgYSBDUk9TUy1leGVjdXRvciByZXN1bWVcbiAgICAvLyAoYm90aCBhcmUgcGxhaW4gbnVtYmVyL3JlY29yZCwgc28gdGhleSByaWRlIHRoZSBzaW5nbGUgc3RydWN0dXJlZENsb25lXG4gICAgLy8gYmVsb3cgdW50b3VjaGVkKS4gU2VlIHRlc3QvbGliL3BhdXNlL3Jlc3VtZS1leGVjdXRpb24tY291bnRlci1jb250aW51aXR5LnRlc3QudHMuXG4gICAgZXhlY3V0aW9uQ291bnQ6IHJ1bi5leGVjdXRpb25Db3VudCxcbiAgICB2aXNpdENvdW50czogT2JqZWN0LmZyb21FbnRyaWVzKHJ1bi52aXNpdENvdW50cyksXG4gICAgLy8gSW52b2tlciBjb250ZXh0IOKAlCBjb2xsZWN0ZWQgZHVyaW5nIHRyYXZlcnNhbCBidWJibGUtdXAgKG5vdCB0cmVlLXdhbGtlZCkuXG4gICAgLy8gKGBjb250aW51YXRpb25TdGFnZUlkYCBpcyBsZWdhY3ktb25seSBzaW5jZSA5LjM5LjA6IG5vIGxvbmdlciB3cml0dGVuLilcbiAgICAuLi4oc2lnbmFsLmludm9rZXJTdGFnZUlkICYmIHsgaW52b2tlclN0YWdlSWQ6IHNpZ25hbC5pbnZva2VyU3RhZ2VJZCB9KSxcbiAgICAvLyBQYXJhbGxlbCBzaWJsaW5ncycgcGF1c2VzIGZyb20gdGhlIHNhbWUgZmFuLW91dCwgd2FpdGluZyB0aGVpciB0dXJuXG4gICAgLy8gKDkuMjguMCkuIEFic2VudCB3aGVuIG9ubHkgb25lIGNoaWxkIHBhdXNlZCDigJQgdGhlIHNoYXBlIGV2ZXJ5XG4gICAgLy8gZWFybGllciBjaGVja3BvaW50IGhhcy5cbiAgICAuLi4oc2lnbmFsLnBlbmRpbmdQYXVzZXMubGVuZ3RoID4gMCAmJiB7IHBlbmRpbmdQYXVzZXM6IHNpZ25hbC5wZW5kaW5nUGF1c2VzIH0pLFxuICAgIC8vIEhPVyB0aGUgcGF1c2Ugd2FzIHJhaXNlZC4gT25lIGNoZWNrcG9pbnQgc2hhcGUsIG9uZSBleHRyYSBvcHRpb25hbFxuICAgIC8vIGZpZWxkIOKAlCBhbiBpbnRlcnJ1cHQoKSBwYXVzZSBpcyBub3QgYSBzZWNvbmQga2luZCBvZiBjaGVja3BvaW50LCBpdCBpc1xuICAgIC8vIHRoZSBzYW1lIGNoZWNrcG9pbnQgdGhhdCByZXN1bWUoKSByZS1lbnRlcnMgZGlmZmVyZW50bHkgKHN0YWdlIHRvcCB2c1xuICAgIC8vIHJlc3VtZUZuKS4gQWJzZW50IGZvciBldmVyeSBwcmUtOS4xNC4wIGNoZWNrcG9pbnQsIHdoaWNoIGlzIGNvcnJlY3QuXG4gICAgLi4uKHNpZ25hbC5wYXVzZWRCeSAmJiB7IHBhdXNlZEJ5OiBzaWduYWwucGF1c2VkQnkgfSksXG4gICAgLy8gVGhlIHJlZGFjdGlvbiB0aGUgcGF1c2VkIHJ1biBoYWQgbWFkZSDigJQgTkFNRVMgb25seSAobWFya3MsIGEgbWFwcGVyJ3MgdGFpbnRzLCBpbmhlcml0ZWRcbiAgICAvLyBmaWVsZHMpLiBSZXN1bWUgc2VlZHMgdGhlIHJlc3VtZWQgcnVuJ3MgcnVsZSB3aXRoIHRoZW0uIEFic2VudCB3aGVuIG5vdGhpbmcgd2FzIG1hcmtlZC5cbiAgICAuLi4ocnVuLnJlZGFjdGlvbk1hcmtzICYmIHsgcmVkYWN0aW9uTWFya3M6IHJ1bi5yZWRhY3Rpb25NYXJrcyB9KSxcbiAgICBwYXVzZWRBdDogRGF0ZS5ub3coKSxcbiAgfTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gc3RydWN0dXJlZENsb25lKGNoZWNrcG9pbnQpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIC8vIEdlbnVpbmUgSlNPTi1zYWZlIGNvbnRyYWN0IHZpb2xhdGlvbiBpbiBjb25zdW1lci1vd25lZCBkYXRhLlxuICAgIHRocm93IGRlc2NyaWJlQ2hlY2twb2ludENsb25lRmFpbHVyZShjaGVja3BvaW50LCBlcnJvcik7XG4gIH1cbn1cblxuLyoqIGB0cnVlYCB3aGVuIGBzdHJ1Y3R1cmVkQ2xvbmVgIGFjY2VwdHMgdGhlIHZhbHVlIGFzLWlzLiAqL1xuZnVuY3Rpb24gaXNDbG9uZWFibGUodmFsdWU6IHVua25vd24pOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBzdHJ1Y3R1cmVkQ2xvbmUodmFsdWUpO1xuICAgIHJldHVybiB0cnVlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgREVTQ1JJUFRJVkUgZXJyb3IgZm9yIGEgY2hlY2twb2ludCB0aGF0IGNhbm5vdCBiZSBjbG9uZWQg4oCUIHRoZVxuICogbm9uLWNsb25lYWJsZSB2YWx1ZSBsaXZlcyBpbiBjb25zdW1lci1vd25lZCBkYXRhIChhIGdlbnVpbmUgSlNPTi1zYWZlXG4gKiBjb250cmFjdCB2aW9sYXRpb24pLiBQcm9iZXMgZWFjaCB0b3AtbGV2ZWwgY2hlY2twb2ludCBmaWVsZCBpbmRpdmlkdWFsbHkgc29cbiAqIHRoZSBtZXNzYWdlIG5hbWVzIHRoZSBvZmZlbmRpbmcgZmllbGQgZmFtaWx5LiBOZXZlciBsZXRzIGEgbmFrZWRcbiAqIGBEYXRhQ2xvbmVFcnJvcmAgZXNjYXBlLlxuICovXG5mdW5jdGlvbiBkZXNjcmliZUNoZWNrcG9pbnRDbG9uZUZhaWx1cmUoY2hlY2twb2ludDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIGNhdXNlOiB1bmtub3duKTogRXJyb3Ige1xuICBjb25zdCBmYWlsaW5nID0gT2JqZWN0LmVudHJpZXMoY2hlY2twb2ludClcbiAgICAuZmlsdGVyKChbLCB2YWx1ZV0pID0+ICFpc0Nsb25lYWJsZSh2YWx1ZSkpXG4gICAgLm1hcCgoW2ZpZWxkXSkgPT4gZmllbGQpO1xuICBjb25zdCBmaWVsZHMgPSBmYWlsaW5nLmxlbmd0aCA+IDAgPyBmYWlsaW5nLmpvaW4oJywgJykgOiAndW5rbm93bic7XG4gIHJldHVybiBuZXcgRXJyb3IoXG4gICAgJ0Zsb3dDaGFydEV4ZWN1dG9yOiBjYW5ub3QgYnVpbGQgdGhlIHBhdXNlIGNoZWNrcG9pbnQg4oCUIG5vbi1zZXJpYWxpemFibGUgdmFsdWUocykgaW4gJyArXG4gICAgICBgY2hlY2twb2ludCBmaWVsZChzKTogJHtmaWVsZHN9LiBUaGUgY2hlY2twb2ludCBjb250cmFjdCBpcyBKU09OLXNhZmUgKG5vIGZ1bmN0aW9ucywgbm8gYCArXG4gICAgICBcImNsYXNzIGluc3RhbmNlcykuIENoZWNrIHRoZSBwYXVzZURhdGEgcmV0dXJuZWQgYnkgdGhlIHBhdXNhYmxlIHN0YWdlJ3MgZXhlY3V0ZSgpLCBhbmQgYW55IFwiICtcbiAgICAgICdzdWJmbG93IHN0YXRlIGNhcHR1cmVkIGF0IHRoZSBwYXVzZS4gRGlhZ25vc3RpYyB2YWx1ZXMgZnJvbSAkZGVidWcvJG1ldHJpYy8kZXJyb3IvJGV2YWwgJyArXG4gICAgICAnYXJlIG5ldmVyIHBhcnQgb2YgYSBjaGVja3BvaW50IGFuZCBuZXZlciBjYXVzZSB0aGlzIGVycm9yLiAnICtcbiAgICAgICdTZWUgZG9jcy9ndWlkZXMvZXhlY3V0aW9uLW1vZGVsLm1kIChcIlBhdXNlIC8gcmVzdW1lIOKAlCB3aGF0IGEgY2hlY2twb2ludCBjYXB0dXJlc1wiKS4nLFxuICAgIHsgY2F1c2UgfSxcbiAgKTtcbn1cbiJdfQ==