@workflow/core 5.0.0-beta.41 → 5.0.0-beta.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/create-hook.d.ts +9 -5
- package/dist/create-hook.d.ts.map +1 -1
- package/dist/create-hook.js +1 -1
- package/dist/events-consumer.d.ts +97 -0
- package/dist/events-consumer.d.ts.map +1 -1
- package/dist/events-consumer.js +147 -14
- package/dist/private.d.ts +31 -12
- package/dist/private.d.ts.map +1 -1
- package/dist/private.js +149 -26
- package/dist/runtime/constants.d.ts +62 -0
- package/dist/runtime/constants.d.ts.map +1 -1
- package/dist/runtime/constants.js +70 -1
- package/dist/runtime/helpers.d.ts +127 -93
- package/dist/runtime/helpers.d.ts.map +1 -1
- package/dist/runtime/helpers.js +149 -132
- package/dist/runtime/quickjs-entrypoint.d.ts +10 -9
- package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -1
- package/dist/runtime/quickjs-entrypoint.js +162 -38
- package/dist/runtime/replay-budget.d.ts +8 -0
- package/dist/runtime/replay-budget.d.ts.map +1 -1
- package/dist/runtime/replay-budget.js +3 -3
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +53 -13
- package/dist/runtime/resume-latency.d.ts +143 -0
- package/dist/runtime/resume-latency.d.ts.map +1 -0
- package/dist/runtime/resume-latency.js +153 -0
- package/dist/runtime/run.d.ts.map +1 -1
- package/dist/runtime/run.js +54 -29
- package/dist/runtime/step-executor.d.ts +76 -13
- package/dist/runtime/step-executor.d.ts.map +1 -1
- package/dist/runtime/step-executor.js +171 -19
- package/dist/runtime/step-latency.d.ts +6 -0
- package/dist/runtime/step-latency.d.ts.map +1 -1
- package/dist/runtime/step-latency.js +3 -1
- package/dist/runtime/suspension-handler.d.ts +119 -8
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +643 -46
- package/dist/runtime/world-compatibility.d.ts +6 -5
- package/dist/runtime/world-compatibility.d.ts.map +1 -1
- package/dist/runtime/world-compatibility.js +7 -6
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +583 -142
- package/dist/serialization/codec-devalue.d.ts.map +1 -1
- package/dist/serialization/codec-devalue.js +15 -4
- package/dist/serialization.d.ts +10 -2
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +55 -8
- package/dist/telemetry/semantic-conventions.d.ts +81 -0
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +67 -1
- package/dist/telemetry.d.ts +6 -0
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +22 -1
- package/dist/test-support/orchestrator-context.d.ts +25 -0
- package/dist/test-support/orchestrator-context.d.ts.map +1 -0
- package/dist/test-support/orchestrator-context.js +91 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/dist/workflow/create-hook.js +2 -2
- package/dist/workflow/hook.js +3 -3
- package/dist/workflow.js +43 -2
- package/docs/foundations/hooks.mdx +2 -2
- package/docs/foundations/streaming.mdx +24 -0
- package/docs/how-it-works/event-sourcing.mdx +39 -1
- package/package.json +5 -5
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { EntityConflictError, FatalError, HookNotFoundError, PreconditionFailedError, RunExpiredError, WorkflowWorldError, } from '@workflow/errors';
|
|
2
|
-
import { AttributeValidationError, SPEC_VERSION_CURRENT, SPEC_VERSION_SUPPORTS_COMPRESSION, } from '@workflow/world';
|
|
2
|
+
import { AttributeValidationError, SPEC_VERSION_CURRENT, SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT, SPEC_VERSION_SUPPORTS_COMPRESSION, SPEC_VERSION_SUPPORTS_SLOT_IDENTITY, } from '@workflow/world';
|
|
3
|
+
import { isRetryableWorldError } from '../classify-error.js';
|
|
3
4
|
import { importKey } from '../encryption.js';
|
|
4
5
|
import { runtimeLogger } from '../logger.js';
|
|
5
6
|
import { dehydrateStepArguments } from '../serialization.js';
|
|
6
7
|
import * as Attribute from '../telemetry/semantic-conventions.js';
|
|
7
8
|
import { getAbortStreamIdFromToken } from '../util.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
9
|
+
import { COMPUTE_INSTANCE_ID } from './compute-instance.js';
|
|
10
|
+
import { getMaxInlineSteps, isBatchTransitionsEnabled, isResilientStepDispatchEnabled, MAX_BATCH_FANOUT_EVENTS, MAX_RESILIENT_STEP_INPUT_BYTES, } from './constants.js';
|
|
11
|
+
import { absorbSkippedSlotReport, maxEventSlot, queueMessage, slotSnapshotParams, stepDispatchIdempotencyKey, } from './helpers.js';
|
|
10
12
|
import { ReplayRecoveryReporter } from './replay-recovery-reporter.js';
|
|
11
13
|
async function createHookEvent({ runId, hookEvent, queueItem, requestId, createEvent, }) {
|
|
12
14
|
try {
|
|
@@ -65,7 +67,7 @@ async function createHookEvent({ runId, hookEvent, queueItem, requestId, createE
|
|
|
65
67
|
* 1. Hooks are processed first to prevent race conditions with webhook receivers
|
|
66
68
|
* 2. Step events and wait events are created in parallel
|
|
67
69
|
*/
|
|
68
|
-
export async function handleSuspension({ suspension, world, run, span, requestId, eventLog, runReadyBarrier, replayRecoveryReporter, }) {
|
|
70
|
+
export async function handleSuspension({ suspension, world, run, span, requestId, eventLog, runReadyBarrier, replayRecoveryReporter, stepDispatch, ownerMessageId, allowDeferredBatchWork, }) {
|
|
69
71
|
const runId = run.runId;
|
|
70
72
|
// Turbo mode: hold every world write below until the backgrounded
|
|
71
73
|
// `run_started` has *settled*, so we never write a step/hook/wait event for a
|
|
@@ -133,41 +135,29 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
133
135
|
const log = eventLog;
|
|
134
136
|
const result = await createEvent(data, {
|
|
135
137
|
...params,
|
|
136
|
-
...
|
|
138
|
+
...slotSnapshotParams(log.events),
|
|
137
139
|
});
|
|
138
|
-
// Bump-and-report: the write landed above the slot it asked for, so
|
|
139
|
-
//
|
|
140
|
-
// each call site means the rest of this phase's writes — which read
|
|
141
|
-
// same array to build their own snapshot — ask for a slot above them,
|
|
142
|
-
// the replay that resumes from this log sees them without a reload.
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// carries only some of the events on them, so merging it would raise the
|
|
147
|
-
// log's highest position past a position whose event is missing. Every
|
|
148
|
-
// later write of this phase reads that maximum to say what it has seen, so
|
|
149
|
-
// each would claim a position it never saw and the World, which only
|
|
150
|
-
// reports the span a write skips, would never send it. Dropping the report
|
|
151
|
-
// costs one more round of the same events on the next write and keeps the
|
|
152
|
-
// log a prefix of the truth.
|
|
153
|
-
if (result.events?.length && result.hasMore !== true) {
|
|
154
|
-
const added = mergeReportedEvents(log.events, result.events);
|
|
155
|
-
reportedEvents += added;
|
|
156
|
-
if (added > 0) {
|
|
157
|
-
runtimeLogger.debug('Suspension write skipped occupied slots', {
|
|
158
|
-
workflowRunId: runId,
|
|
159
|
-
eventType: data.eventType,
|
|
160
|
-
eventId: result.event?.eventId,
|
|
161
|
-
reported: added,
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else if (result.events?.length) {
|
|
140
|
+
// Bump-and-report: the write landed above the slot it asked for, so the
|
|
141
|
+
// report holds the events it was decided without. Absorbing here rather
|
|
142
|
+
// than at each call site means the rest of this phase's writes — which read
|
|
143
|
+
// the same array to build their own snapshot — ask for a slot above them,
|
|
144
|
+
// and the replay that resumes from this log sees them without a reload.
|
|
145
|
+
const report = absorbSkippedSlotReport(log.events, result);
|
|
146
|
+
reportedEvents += report.added;
|
|
147
|
+
if (report.truncated) {
|
|
166
148
|
runtimeLogger.debug('Dropped a truncated skipped-slot report', {
|
|
167
149
|
workflowRunId: runId,
|
|
168
150
|
eventType: data.eventType,
|
|
169
151
|
eventId: result.event?.eventId,
|
|
170
|
-
offered:
|
|
152
|
+
offered: report.offered,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
else if (report.added > 0) {
|
|
156
|
+
runtimeLogger.debug('Suspension write skipped occupied slots', {
|
|
157
|
+
workflowRunId: runId,
|
|
158
|
+
eventType: data.eventType,
|
|
159
|
+
eventId: result.event?.eventId,
|
|
160
|
+
reported: report.added,
|
|
171
161
|
});
|
|
172
162
|
}
|
|
173
163
|
return result;
|
|
@@ -390,10 +380,104 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
390
380
|
// settle, so the inline batch order is stable regardless of dehydration timing.
|
|
391
381
|
const lazyInlineByCorrelationId = new Map();
|
|
392
382
|
const ops = [];
|
|
393
|
-
//
|
|
383
|
+
// Correlation IDs of steps whose step-execution queue message was already
|
|
384
|
+
// published by the resilient-dispatch ops below (alongside the step_created
|
|
385
|
+
// write). Reported to the caller so its dispatch pass skips them.
|
|
386
|
+
const queuedStepCorrelationIds = new Set();
|
|
387
|
+
// Resilient step dispatch eligibility, shared by every step op below (the
|
|
388
|
+
// per-step input-size check is applied inside the op). All must hold:
|
|
389
|
+
//
|
|
390
|
+
// - The caller provided a dispatch target (`stepDispatch`) — terminal
|
|
391
|
+
// drains and other create-only callers never queue.
|
|
392
|
+
// - The feature is enabled (`WORKFLOW_RESILIENT_STEP_DISPATCH` opt-in).
|
|
393
|
+
// It is off by default because the publish races the create's verdict,
|
|
394
|
+
// and a create can come back refused: as a duplicate the replay should
|
|
395
|
+
// stop pursuing, or — on a World that would rather refuse a stale write
|
|
396
|
+
// than report what it missed — as a 412. Either way the queue message
|
|
397
|
+
// carrying the payload is already out, and the consumer can materialize a
|
|
398
|
+
// step whose create was refused. Nothing orders that verdict before the
|
|
399
|
+
// consumer's redelivery re-ensure, so no backend-side revocation
|
|
400
|
+
// bookkeeping can close the window: a best-effort marker that fails open
|
|
401
|
+
// cannot carry a correctness property. The sequential path is the only
|
|
402
|
+
// thing that gives the message a happens-after edge over the verdict.
|
|
403
|
+
// - The run's queue transport preserves binary payloads (CBOR,
|
|
404
|
+
// specVersion >= 3): `stepInput.input` is the serialized (possibly
|
|
405
|
+
// encrypted) input bytes, which the JSON transport would mangle.
|
|
406
|
+
const resilientDispatchEligible = stepDispatch !== undefined &&
|
|
407
|
+
isResilientStepDispatchEnabled() &&
|
|
408
|
+
(run.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_CBOR_QUEUE_TRANSPORT;
|
|
409
|
+
// Batched fan-out: fold this suspension's step_created + wait_created
|
|
410
|
+
// writes into one `events.createBatch` call (one durable write, per-event
|
|
411
|
+
// outcomes) instead of one write per event. Engages only for a CLEAN
|
|
412
|
+
// fan-out — no attribute writes, no hook writes, no resilient dispatch
|
|
413
|
+
// (whose creates are each paired with a queue publish) — on a World that
|
|
414
|
+
// implements the optional method and a run whose events are slot-numbered.
|
|
415
|
+
// Everything outside the gate keeps the single-event path byte-for-byte.
|
|
416
|
+
const batchFanoutEligible = isBatchTransitionsEnabled() &&
|
|
417
|
+
typeof world.events.createBatch === 'function' &&
|
|
418
|
+
(run.specVersion ?? 0) >= SPEC_VERSION_SUPPORTS_SLOT_IDENTITY &&
|
|
419
|
+
!resilientDispatchEligible &&
|
|
420
|
+
allHookItems.length === 0 &&
|
|
421
|
+
attributeItems.length === 0;
|
|
422
|
+
/**
|
|
423
|
+
* The fold's collection, in scheduling order (steps in stepItems order,
|
|
424
|
+
* then waits). Step entries are enqueued by their prep promises (input
|
|
425
|
+
* dehydration runs concurrently, so entries are ordered by `order`, not by
|
|
426
|
+
* completion); the single flush op below awaits every prep, sorts, and
|
|
427
|
+
* commits the whole set through `createBatch`.
|
|
428
|
+
*/
|
|
429
|
+
const batchQueue = [];
|
|
430
|
+
const batchPreps = [];
|
|
431
|
+
// Pre-claimed inline pairs: fold each lazy-inline step's deferred
|
|
432
|
+
// `step_created` (carrying its input) AND its `step_started` claim (bare,
|
|
433
|
+
// ownership-stamped) into the batch, so the whole fan-out — the inline
|
|
434
|
+
// steps' claims included — commits in the one durable write and the caller
|
|
435
|
+
// starts the bodies straight off that commit instead of posting one claim
|
|
436
|
+
// per inline step. The lone-inline case (nothing else to batch with) is
|
|
437
|
+
// excluded: a pair-only batch costs the same round trip as the single lazy
|
|
438
|
+
// claim while giving up the optimistic claim/body overlap and the
|
|
439
|
+
// bump-and-report that `createGuarded` provides, so it stays on the lazy
|
|
440
|
+
// path. Requires the caller's `ownerMessageId` — the started row must
|
|
441
|
+
// stamp ownership exactly like the lazy claim it replaces (and a caller
|
|
442
|
+
// that does not inline-execute never provides one).
|
|
443
|
+
const uncreatedWaitCount = waitItems.filter((item) => !item.hasCreatedEvent).length;
|
|
444
|
+
const inlinePairFoldEligible = batchFanoutEligible &&
|
|
445
|
+
ownerMessageId !== undefined &&
|
|
446
|
+
lazyInlineCorrelationIds.size > 0 &&
|
|
447
|
+
(lazyInlineCorrelationIds.size >= 2 ||
|
|
448
|
+
stepsNeedingCreation.size -
|
|
449
|
+
lazyInlineCorrelationIds.size +
|
|
450
|
+
uncreatedWaitCount >=
|
|
451
|
+
1);
|
|
452
|
+
const inlineClaims = new Map();
|
|
453
|
+
let batchCommittedSlotCeiling;
|
|
454
|
+
// The trace carrier for resilient step dispatches, resolved at most once per
|
|
455
|
+
// suspension (the per-step ops run concurrently and share it).
|
|
456
|
+
let stepDispatchTraceCarrier;
|
|
457
|
+
const getStepDispatchTraceCarrier = () => {
|
|
458
|
+
stepDispatchTraceCarrier ??=
|
|
459
|
+
stepDispatch?.getTraceCarrier() ?? Promise.resolve({});
|
|
460
|
+
return stepDispatchTraceCarrier;
|
|
461
|
+
};
|
|
462
|
+
// Producer-side resilient recovery count for the suspension span attribute.
|
|
463
|
+
let resilientDispatchRecovered = 0;
|
|
464
|
+
// Steps: create step_created events (no queuing — V2 returns pending steps
|
|
465
|
+
// to caller — EXCEPT on the resilient dispatch path, which parallelizes the
|
|
466
|
+
// create with the step's queue publish and reports it in
|
|
467
|
+
// `queuedStepCorrelationIds`).
|
|
468
|
+
let batchOrderCounter = 0;
|
|
394
469
|
for (const queueItem of stepItems) {
|
|
395
470
|
if (stepsNeedingCreation.has(queueItem.correlationId)) {
|
|
396
|
-
|
|
471
|
+
// Deterministic position in the batched fold (assigned in stepItems
|
|
472
|
+
// order, before the concurrent dehydration runs). A pair-folded inline
|
|
473
|
+
// step occupies two consecutive positions — created row then started
|
|
474
|
+
// row — which the flush keeps adjacent and never splits across chunks,
|
|
475
|
+
// so a World can fold them into one born-running create.
|
|
476
|
+
const pairFolded = inlinePairFoldEligible &&
|
|
477
|
+
lazyInlineCorrelationIds.has(queueItem.correlationId);
|
|
478
|
+
const stepOrder = batchOrderCounter;
|
|
479
|
+
batchOrderCounter += pairFolded ? 2 : 1;
|
|
480
|
+
const stepOp = (async () => {
|
|
397
481
|
// Per-step sink, merged below: the dehydrate wrapper emits span
|
|
398
482
|
// attributes from the sink it is handed, so sharing one across
|
|
399
483
|
// steps would re-emit (and misattribute) earlier steps' entries.
|
|
@@ -416,6 +500,44 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
416
500
|
stepName: queueItem.stepName,
|
|
417
501
|
dehydratedInput: dehydratedInput,
|
|
418
502
|
});
|
|
503
|
+
if (pairFolded) {
|
|
504
|
+
// Enqueue the pair the deferral would otherwise leave to the
|
|
505
|
+
// caller's lazy `step_started`: the created row carries the
|
|
506
|
+
// input (payloads ride creates in a batch), the started row is
|
|
507
|
+
// bare and stamps this invocation's ownership — the same claim
|
|
508
|
+
// shape the lazy start would have sent, settled by the batch.
|
|
509
|
+
batchQueue.push({
|
|
510
|
+
order: stepOrder,
|
|
511
|
+
kind: 'inline-created',
|
|
512
|
+
correlationId: queueItem.correlationId,
|
|
513
|
+
event: {
|
|
514
|
+
eventType: 'step_created',
|
|
515
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
516
|
+
correlationId: queueItem.correlationId,
|
|
517
|
+
eventData: {
|
|
518
|
+
stepName: queueItem.stepName,
|
|
519
|
+
workflowName: run.workflowName,
|
|
520
|
+
input: dehydratedInput,
|
|
521
|
+
},
|
|
522
|
+
},
|
|
523
|
+
});
|
|
524
|
+
batchQueue.push({
|
|
525
|
+
order: stepOrder + 1,
|
|
526
|
+
kind: 'inline-started',
|
|
527
|
+
correlationId: queueItem.correlationId,
|
|
528
|
+
event: {
|
|
529
|
+
eventType: 'step_started',
|
|
530
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
531
|
+
correlationId: queueItem.correlationId,
|
|
532
|
+
eventData: {
|
|
533
|
+
stepName: queueItem.stepName,
|
|
534
|
+
// Checked by inlinePairFoldEligible; spread keeps the
|
|
535
|
+
// narrow-through-closure problem away from the type.
|
|
536
|
+
...(ownerMessageId !== undefined ? { ownerMessageId } : {}),
|
|
537
|
+
},
|
|
538
|
+
},
|
|
539
|
+
});
|
|
540
|
+
}
|
|
419
541
|
return;
|
|
420
542
|
}
|
|
421
543
|
const stepEvent = {
|
|
@@ -428,6 +550,98 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
428
550
|
input: dehydratedInput,
|
|
429
551
|
},
|
|
430
552
|
};
|
|
553
|
+
// Resilient step dispatch: fire the step_created write and the
|
|
554
|
+
// step-execution queue publish in parallel — the message carries the
|
|
555
|
+
// same serialized input (`stepInput`) so the consumer can
|
|
556
|
+
// idempotently re-ensure the event if the direct write failed
|
|
557
|
+
// transiently. Mirrors the resilient start (`runInput`) and
|
|
558
|
+
// resilient hook resume (`hookInput`) patterns. Only for inputs the
|
|
559
|
+
// queue message can safely carry (binary, under the VQS size cap).
|
|
560
|
+
if (resilientDispatchEligible &&
|
|
561
|
+
dehydratedInput instanceof Uint8Array &&
|
|
562
|
+
dehydratedInput.byteLength <= MAX_RESILIENT_STEP_INPUT_BYTES) {
|
|
563
|
+
await ensureRunReady();
|
|
564
|
+
const traceCarrier = await getStepDispatchTraceCarrier();
|
|
565
|
+
const [createResult, queueResult] = await Promise.allSettled([
|
|
566
|
+
createGuarded(stepEvent, { requestId }),
|
|
567
|
+
queueMessage(world,
|
|
568
|
+
// biome-ignore lint/style/noNonNullAssertion: implied by resilientDispatchEligible
|
|
569
|
+
stepDispatch.queueName, {
|
|
570
|
+
runId,
|
|
571
|
+
stepId: queueItem.correlationId,
|
|
572
|
+
stepName: queueItem.stepName,
|
|
573
|
+
traceCarrier,
|
|
574
|
+
requestedAt: new Date(),
|
|
575
|
+
stepInput: { input: dehydratedInput },
|
|
576
|
+
},
|
|
577
|
+
// Same key as the caller's dispatch pass and any concurrent
|
|
578
|
+
// handler's — redundant publishes for this step dedupe. The
|
|
579
|
+
// key is step-identity-scoped so a revoked message for a
|
|
580
|
+
// reassigned correlation id cannot absorb the corrected
|
|
581
|
+
// schedule's dispatch — see stepDispatchIdempotencyKey.
|
|
582
|
+
{
|
|
583
|
+
idempotencyKey: stepDispatchIdempotencyKey(queueItem.correlationId, queueItem.stepName),
|
|
584
|
+
}),
|
|
585
|
+
]);
|
|
586
|
+
// Queue failure is always fatal for this suspension pass: without
|
|
587
|
+
// the message the step would rely on the create alone, and if the
|
|
588
|
+
// create ALSO failed there would be no durable record at all.
|
|
589
|
+
// Propagating redelivers the orchestrator message, which
|
|
590
|
+
// re-creates the (idempotent) step_created and re-dispatches —
|
|
591
|
+
// the same recovery as the sequential path.
|
|
592
|
+
if (queueResult.status === 'rejected') {
|
|
593
|
+
throw queueResult.reason;
|
|
594
|
+
}
|
|
595
|
+
queuedStepCorrelationIds.add(queueItem.correlationId);
|
|
596
|
+
if (createResult.status === 'rejected') {
|
|
597
|
+
const err = createResult.reason;
|
|
598
|
+
if (EntityConflictError.is(err)) {
|
|
599
|
+
// Concurrent handler wrote it first — same as the sequential
|
|
600
|
+
// path. The step message is already out; a duplicate publish
|
|
601
|
+
// by that handler dedupes on the shared idempotency key.
|
|
602
|
+
runtimeLogger.info('Step already exists, continuing', {
|
|
603
|
+
workflowRunId: runId,
|
|
604
|
+
correlationId: queueItem.correlationId,
|
|
605
|
+
message: err.message,
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
else if (isRetryableWorldError(err)) {
|
|
609
|
+
// Resilient: the write failed transiently (429 / 5xx /
|
|
610
|
+
// transport) but the step message — carrying the same
|
|
611
|
+
// serialized input — was published, so the consumer
|
|
612
|
+
// idempotently re-ensures the step_created before executing.
|
|
613
|
+
resilientDispatchRecovered++;
|
|
614
|
+
runtimeLogger.warn('Step creation event write failed, but the step was ' +
|
|
615
|
+
'dispatched via the queue. The step_created event will ' +
|
|
616
|
+
'be ensured by the queue consumer.', {
|
|
617
|
+
workflowRunId: runId,
|
|
618
|
+
correlationId: queueItem.correlationId,
|
|
619
|
+
stepName: queueItem.stepName,
|
|
620
|
+
error: err instanceof Error ? err.message : String(err),
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
else {
|
|
624
|
+
throw err;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
createdStepCorrelationIds.add(queueItem.correlationId);
|
|
629
|
+
}
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
if (batchFanoutEligible) {
|
|
633
|
+
// Fold into the batch instead of writing here. The enclosing
|
|
634
|
+
// promise joins `batchPreps` (see the loop below), so the flush
|
|
635
|
+
// op cannot run before this step's input finished dehydrating.
|
|
636
|
+
batchQueue.push({
|
|
637
|
+
order: stepOrder,
|
|
638
|
+
kind: 'step',
|
|
639
|
+
correlationId: queueItem.correlationId,
|
|
640
|
+
stepName: queueItem.stepName,
|
|
641
|
+
event: stepEvent,
|
|
642
|
+
});
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
431
645
|
try {
|
|
432
646
|
await ensureRunReady();
|
|
433
647
|
await createGuarded(stepEvent, { requestId });
|
|
@@ -445,21 +659,41 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
445
659
|
throw err;
|
|
446
660
|
}
|
|
447
661
|
}
|
|
448
|
-
})()
|
|
662
|
+
})();
|
|
663
|
+
ops.push(stepOp);
|
|
664
|
+
if (batchFanoutEligible) {
|
|
665
|
+
// The flush op waits for every prep before committing; a prep that
|
|
666
|
+
// rejected already surfaces through `ops`, so the flush's own wait
|
|
667
|
+
// swallows it and commits whatever was successfully enqueued —
|
|
668
|
+
// preserving today's per-op independence.
|
|
669
|
+
batchPreps.push(stepOp.catch(() => { }));
|
|
670
|
+
}
|
|
449
671
|
}
|
|
450
672
|
}
|
|
451
673
|
// Create wait events (same as V1)
|
|
452
674
|
for (const queueItem of waitItems) {
|
|
453
675
|
if (!queueItem.hasCreatedEvent) {
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
676
|
+
const waitEvent = {
|
|
677
|
+
eventType: 'wait_created',
|
|
678
|
+
specVersion: SPEC_VERSION_CURRENT,
|
|
679
|
+
correlationId: queueItem.correlationId,
|
|
680
|
+
eventData: {
|
|
681
|
+
resumeAt: queueItem.resumeAt,
|
|
682
|
+
},
|
|
683
|
+
};
|
|
684
|
+
if (batchFanoutEligible) {
|
|
685
|
+
// Waits need no dehydration, so they enqueue synchronously — after
|
|
686
|
+
// every step's order slot, preserving steps-then-waits scheduling
|
|
687
|
+
// order in the log.
|
|
688
|
+
batchQueue.push({
|
|
689
|
+
order: batchOrderCounter++,
|
|
690
|
+
kind: 'wait',
|
|
458
691
|
correlationId: queueItem.correlationId,
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
692
|
+
event: waitEvent,
|
|
693
|
+
});
|
|
694
|
+
continue;
|
|
695
|
+
}
|
|
696
|
+
ops.push((async () => {
|
|
463
697
|
try {
|
|
464
698
|
await ensureRunReady();
|
|
465
699
|
await createGuarded(waitEvent, { requestId });
|
|
@@ -479,6 +713,362 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
479
713
|
})());
|
|
480
714
|
}
|
|
481
715
|
}
|
|
716
|
+
// The batched fold's flush: the clean fan-out commits through
|
|
717
|
+
// `createBatch` in chunks of MAX_BATCH_FANOUT_EVENTS — all chunks IN
|
|
718
|
+
// FLIGHT CONCURRENTLY. Slot assignment is the server's, so parallel
|
|
719
|
+
// chunks race for slot ranges exactly like the pre-fold path's parallel
|
|
720
|
+
// single writes did; entity conditions, not commit order, carry
|
|
721
|
+
// correctness (sibling fan-out events have no cross-order the replay
|
|
722
|
+
// depends on — it matches by correlation id). Each event reports the
|
|
723
|
+
// outcome its own single create would have had: a 409 is the same
|
|
724
|
+
// already-exists tolerance as the single path, anything else fails the
|
|
725
|
+
// delivery the way a single-path rejection would.
|
|
726
|
+
//
|
|
727
|
+
// Latency shape: only the chunk carrying the pre-claimed inline pairs
|
|
728
|
+
// gates the handler's return (the caller starts bodies off its claims).
|
|
729
|
+
// Every other chunk's commit — and every chunk's step-message publishes,
|
|
730
|
+
// which fire the moment ITS creates are durable — rides
|
|
731
|
+
// `deferredBatchWork` when the caller opted in, joined before ack. A slow
|
|
732
|
+
// sibling chunk therefore delays neither the inline bodies nor another
|
|
733
|
+
// chunk's queue messages, while publish-after-create still holds per
|
|
734
|
+
// step: a step's message is only ever sent after the chunk carrying its
|
|
735
|
+
// create has committed.
|
|
736
|
+
let deferredBatchWork;
|
|
737
|
+
if (batchFanoutEligible) {
|
|
738
|
+
ops.push((async () => {
|
|
739
|
+
// Preps that rejected already surface through their own `ops`
|
|
740
|
+
// entries; the fold commits whatever was successfully enqueued,
|
|
741
|
+
// preserving today's per-op independence.
|
|
742
|
+
await Promise.all(batchPreps);
|
|
743
|
+
if (batchQueue.length === 0) {
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
const entries = [...batchQueue].sort((a, b) => a.order - b.order);
|
|
747
|
+
await ensureRunReady();
|
|
748
|
+
// A batch of ONE gains nothing over the single write (same round
|
|
749
|
+
// trip) and loses the slot-snapshot params + bump-and-report that
|
|
750
|
+
// createGuarded provides — so a lone eager event takes the ordinary
|
|
751
|
+
// single path, with the same conflict tolerance and ownership
|
|
752
|
+
// bookkeeping it would have had without the fold.
|
|
753
|
+
if (entries.length === 1) {
|
|
754
|
+
const [entry] = entries;
|
|
755
|
+
try {
|
|
756
|
+
await createGuarded(entry.event, { requestId });
|
|
757
|
+
if (entry.kind === 'step') {
|
|
758
|
+
createdStepCorrelationIds.add(entry.correlationId);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
catch (err) {
|
|
762
|
+
if (EntityConflictError.is(err)) {
|
|
763
|
+
runtimeLogger.info(entry.kind === 'step'
|
|
764
|
+
? 'Step already exists, continuing'
|
|
765
|
+
: 'Wait already exists, continuing', {
|
|
766
|
+
workflowRunId: runId,
|
|
767
|
+
correlationId: entry.correlationId,
|
|
768
|
+
message: err.message,
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
throw err;
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
// Seed for the foreign-interleaving diagnostic below. With chunks
|
|
778
|
+
// committing in parallel there is no per-chunk "expected next slot"
|
|
779
|
+
// — the whole fold's committed span is compared against the seed
|
|
780
|
+
// once every chunk has settled: committed slots are dense per the
|
|
781
|
+
// World's invariant, so any excess of (max committed slot − seed +
|
|
782
|
+
// 1) over the fold's own committed count is events OTHER writers
|
|
783
|
+
// landed in between.
|
|
784
|
+
const expectedFirstSlot = eventLog
|
|
785
|
+
? (maxEventSlot(eventLog.events) ?? 0) + 1
|
|
786
|
+
: undefined;
|
|
787
|
+
// Pair-aware chunking: a pre-claimed pair's two rows must land in
|
|
788
|
+
// the same createBatch call — adjacent, so a World can fold them
|
|
789
|
+
// into one born-running create — and never straddle a chunk
|
|
790
|
+
// boundary, which would turn the started row into a standalone
|
|
791
|
+
// claim racing its own create's commit.
|
|
792
|
+
const chunks = [];
|
|
793
|
+
{
|
|
794
|
+
let current = [];
|
|
795
|
+
for (let index = 0; index < entries.length; index++) {
|
|
796
|
+
const entry = entries[index];
|
|
797
|
+
const next = entries[index + 1];
|
|
798
|
+
const pairLead = entry.kind === 'inline-created' &&
|
|
799
|
+
next?.kind === 'inline-started' &&
|
|
800
|
+
next.correlationId === entry.correlationId;
|
|
801
|
+
const take = pairLead ? 2 : 1;
|
|
802
|
+
if (current.length > 0 &&
|
|
803
|
+
current.length + take > MAX_BATCH_FANOUT_EVENTS) {
|
|
804
|
+
chunks.push(current);
|
|
805
|
+
current = [];
|
|
806
|
+
}
|
|
807
|
+
current.push(entry);
|
|
808
|
+
if (pairLead) {
|
|
809
|
+
current.push(next);
|
|
810
|
+
index++;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
if (current.length > 0)
|
|
814
|
+
chunks.push(current);
|
|
815
|
+
}
|
|
816
|
+
// Steps whose queue messages THIS FLUSH will publish (the eager
|
|
817
|
+
// creates), recorded before any chunk settles so the caller's
|
|
818
|
+
// dispatch pass — which runs off the handler's return — skips them.
|
|
819
|
+
// The sends are guaranteed-or-failed by the trailing work the
|
|
820
|
+
// caller joins before acking, so "will be published by this flush"
|
|
821
|
+
// and "already published" are equivalent from the caller's side.
|
|
822
|
+
const publishEagerSteps = stepDispatch !== undefined;
|
|
823
|
+
if (publishEagerSteps) {
|
|
824
|
+
for (const entry of entries) {
|
|
825
|
+
if (entry.kind === 'step') {
|
|
826
|
+
queuedStepCorrelationIds.add(entry.correlationId);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
// Tallies for the foreign-interleaving diagnostic, folded across
|
|
831
|
+
// the concurrent chunks and read once all of them settled.
|
|
832
|
+
let committedCount = 0;
|
|
833
|
+
let maxCommittedSlot;
|
|
834
|
+
const commitChunk = async (chunk) => {
|
|
835
|
+
// Anchors for the pre-claimed steps' telemetry: the POST instant
|
|
836
|
+
// is the claim's "start POST sent" (RSFS's end), the return is the
|
|
837
|
+
// claim's completion (TTR's T6) — the same two instants the lazy
|
|
838
|
+
// claim's own POST would have produced.
|
|
839
|
+
const batchPostSentAtMs = Date.now();
|
|
840
|
+
// biome-ignore lint/style/noNonNullAssertion: batchFanoutEligible implies presence
|
|
841
|
+
const { results } = await world.events.createBatch(runId, chunk.map((entry) => ({
|
|
842
|
+
event: entry.event,
|
|
843
|
+
// The started row is the step's executing claim, so it carries
|
|
844
|
+
// the compute-instance attribution the single claim sends via
|
|
845
|
+
// CreateEventParams.
|
|
846
|
+
...(entry.kind === 'inline-started'
|
|
847
|
+
? { computeInstanceId: COMPUTE_INSTANCE_ID }
|
|
848
|
+
: {}),
|
|
849
|
+
})),
|
|
850
|
+
// Per-write request attribution, same as the single path's
|
|
851
|
+
// createGuarded(…, { requestId }).
|
|
852
|
+
{ requestId });
|
|
853
|
+
const claimCompletedAtMs = Date.now();
|
|
854
|
+
for (const [index, item] of results.entries()) {
|
|
855
|
+
const entry = chunk[index];
|
|
856
|
+
if (item.error === undefined) {
|
|
857
|
+
if (entry.kind === 'step') {
|
|
858
|
+
createdStepCorrelationIds.add(entry.correlationId);
|
|
859
|
+
}
|
|
860
|
+
else if (entry.kind === 'inline-started') {
|
|
861
|
+
// The pair committed: this invocation owns the step and the
|
|
862
|
+
// caller runs the body with no claim of its own. The
|
|
863
|
+
// readback entity is authoritative where present; a World
|
|
864
|
+
// that omitted it gets the same locally synthesized running
|
|
865
|
+
// attempt-1 the optimistic path executes against. Either
|
|
866
|
+
// way the input is re-attached locally — batch responses
|
|
867
|
+
// return refs lazily, and the body's hydration wants the
|
|
868
|
+
// exact bytes the pair's created row carried. (The created
|
|
869
|
+
// row's success is deliberately NOT membership in
|
|
870
|
+
// createdStepCorrelationIds: for inline steps ownership is
|
|
871
|
+
// the started row's verdict, and the caller's dispatch pass
|
|
872
|
+
// skips inline correlation ids regardless.)
|
|
873
|
+
const dehydrated = lazyInlineByCorrelationId.get(entry.correlationId);
|
|
874
|
+
if (dehydrated === undefined) {
|
|
875
|
+
// Unreachable: the same prep op that enqueued the pair set
|
|
876
|
+
// this entry, and the flush awaited every prep above.
|
|
877
|
+
//
|
|
878
|
+
// Not free if it ever fires, though: the pair is already
|
|
879
|
+
// durable here, so this throws with the step claimed and
|
|
880
|
+
// its body never run. The delivery fails, and redelivery
|
|
881
|
+
// recovers it through owned-recovery (the step carries this
|
|
882
|
+
// message's ownership stamp) rather than the request just
|
|
883
|
+
// failing cleanly.
|
|
884
|
+
throw new WorkflowWorldError(`no dehydrated input for pre-claimed step ${entry.correlationId}`, { status: 500 });
|
|
885
|
+
}
|
|
886
|
+
const now = new Date();
|
|
887
|
+
const startedStep = item.step?.startedAt
|
|
888
|
+
? { ...item.step, startedAt: item.step.startedAt }
|
|
889
|
+
: {
|
|
890
|
+
runId,
|
|
891
|
+
stepId: entry.correlationId,
|
|
892
|
+
stepName: dehydrated.stepName,
|
|
893
|
+
status: 'running',
|
|
894
|
+
attempt: 1,
|
|
895
|
+
createdAt: now,
|
|
896
|
+
updatedAt: now,
|
|
897
|
+
startedAt: now,
|
|
898
|
+
};
|
|
899
|
+
inlineClaims.set(entry.correlationId, {
|
|
900
|
+
owned: true,
|
|
901
|
+
step: {
|
|
902
|
+
...startedStep,
|
|
903
|
+
input: dehydrated.dehydratedInput,
|
|
904
|
+
},
|
|
905
|
+
batchPostSentAtMs,
|
|
906
|
+
claimCompletedAtMs,
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
continue;
|
|
910
|
+
}
|
|
911
|
+
if (item.status === 409) {
|
|
912
|
+
if (entry.kind === 'inline-created' ||
|
|
913
|
+
entry.kind === 'inline-started') {
|
|
914
|
+
// The pair lost its atomic create-claim: a concurrent writer
|
|
915
|
+
// already owns this step (an earlier delivery's create, or a
|
|
916
|
+
// racing handler's claim). Recorded as a lost claim — the
|
|
917
|
+
// caller's executeStep returns `skipped` without running the
|
|
918
|
+
// body, the same outcome as losing the lazy claim. A World
|
|
919
|
+
// that folds the pair reports the 409 on both rows (set
|
|
920
|
+
// twice, harmless); one that evaluates rows independently
|
|
921
|
+
// has the started row — processed second — decide, which is
|
|
922
|
+
// exactly the single path's semantics (create lost + claim
|
|
923
|
+
// won still runs the body; create won + claim lost skips).
|
|
924
|
+
inlineClaims.set(entry.correlationId, { owned: false });
|
|
925
|
+
runtimeLogger.info('Inline step pre-claim lost, continuing', {
|
|
926
|
+
workflowRunId: runId,
|
|
927
|
+
correlationId: entry.correlationId,
|
|
928
|
+
message: item.message,
|
|
929
|
+
});
|
|
930
|
+
continue;
|
|
931
|
+
}
|
|
932
|
+
// Same tolerance as the single path's EntityConflictError: a
|
|
933
|
+
// concurrent or earlier delivery already created it.
|
|
934
|
+
runtimeLogger.info(entry.kind === 'step'
|
|
935
|
+
? 'Step already exists, continuing'
|
|
936
|
+
: 'Wait already exists, continuing', {
|
|
937
|
+
workflowRunId: runId,
|
|
938
|
+
correlationId: entry.correlationId,
|
|
939
|
+
message: item.message,
|
|
940
|
+
});
|
|
941
|
+
continue;
|
|
942
|
+
}
|
|
943
|
+
throw new WorkflowWorldError(`batched ${entry.event.eventType} for ${entry.correlationId} ` +
|
|
944
|
+
`failed: ${item.error}: ${item.message}`, { status: item.status });
|
|
945
|
+
}
|
|
946
|
+
// Highest slot this chunk committed: the ceiling the caller folds
|
|
947
|
+
// into the inline executions' slot snapshot (see
|
|
948
|
+
// SuspensionHandlerResult.batchCommittedSlotCeiling) and one input
|
|
949
|
+
// of the interleaving diagnostic.
|
|
950
|
+
const chunkMaxSlot = maxEventSlot(results.flatMap((item) => item.error === undefined && item.event ? [item.event] : []));
|
|
951
|
+
if (chunkMaxSlot !== undefined &&
|
|
952
|
+
(batchCommittedSlotCeiling === undefined ||
|
|
953
|
+
chunkMaxSlot > batchCommittedSlotCeiling)) {
|
|
954
|
+
batchCommittedSlotCeiling = chunkMaxSlot;
|
|
955
|
+
}
|
|
956
|
+
committedCount += results.filter((item) => item.error === undefined).length;
|
|
957
|
+
if (chunkMaxSlot !== undefined &&
|
|
958
|
+
(maxCommittedSlot === undefined || chunkMaxSlot > maxCommittedSlot)) {
|
|
959
|
+
maxCommittedSlot = chunkMaxSlot;
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
// Publish the chunk's eager steps' queue messages the moment ITS
|
|
963
|
+
// creates are durable — the per-chunk half of publish-after-create.
|
|
964
|
+
// Same message shape and step-identity-scoped idempotency key as the
|
|
965
|
+
// caller's dispatch pass, so anything double-published dedupes.
|
|
966
|
+
const publishChunkSteps = async (chunk) => {
|
|
967
|
+
if (!publishEagerSteps)
|
|
968
|
+
return;
|
|
969
|
+
const stepEntries = chunk.filter((entry) => entry.kind === 'step');
|
|
970
|
+
if (stepEntries.length === 0)
|
|
971
|
+
return;
|
|
972
|
+
const traceCarrier = await getStepDispatchTraceCarrier();
|
|
973
|
+
await Promise.all(stepEntries.map((entry) => queueMessage(world,
|
|
974
|
+
// biome-ignore lint/style/noNonNullAssertion: publishEagerSteps implies presence
|
|
975
|
+
stepDispatch.queueName, {
|
|
976
|
+
runId,
|
|
977
|
+
stepId: entry.correlationId,
|
|
978
|
+
// biome-ignore lint/style/noNonNullAssertion: set on every 'step' entry at enqueue
|
|
979
|
+
stepName: entry.stepName,
|
|
980
|
+
traceCarrier,
|
|
981
|
+
requestedAt: new Date(),
|
|
982
|
+
}, {
|
|
983
|
+
idempotencyKey: stepDispatchIdempotencyKey(entry.correlationId,
|
|
984
|
+
// biome-ignore lint/style/noNonNullAssertion: set on every 'step' entry at enqueue
|
|
985
|
+
entry.stepName),
|
|
986
|
+
})));
|
|
987
|
+
};
|
|
988
|
+
// Launch every chunk's POST now; chain each chunk's publishes on its
|
|
989
|
+
// OWN commit. A chunk whose commit rejected keeps its messages
|
|
990
|
+
// unsent (the rejection fails the delivery; redelivery re-creates
|
|
991
|
+
// and re-dispatches, deduped by the idempotency keys).
|
|
992
|
+
const commits = chunks.map((chunk) => commitChunk(chunk));
|
|
993
|
+
const publishes = chunks.map(async (chunk, index) => {
|
|
994
|
+
await commits[index];
|
|
995
|
+
await publishChunkSteps(chunk);
|
|
996
|
+
});
|
|
997
|
+
const trailing = (async () => {
|
|
998
|
+
// Let every sibling settle before surfacing the first failure: a
|
|
999
|
+
// chunk that committed must still get its publishes out even when
|
|
1000
|
+
// another chunk failed, and the caller acks only after this
|
|
1001
|
+
// resolves.
|
|
1002
|
+
const settled = await Promise.allSettled([...commits, ...publishes]);
|
|
1003
|
+
// Foreign-interleaving visibility: the batch endpoint has no
|
|
1004
|
+
// bump-and-report, so events other writers landed between the
|
|
1005
|
+
// snapshot and these commits pushed the fold to higher slots
|
|
1006
|
+
// WITHOUT handing us the skipped events. Same accepted exposure
|
|
1007
|
+
// as a dropped truncated report on the single path: the local
|
|
1008
|
+
// log stays a strict prefix and the next reload observes them.
|
|
1009
|
+
// Logged so a bump is diagnosable rather than silent.
|
|
1010
|
+
if (expectedFirstSlot !== undefined &&
|
|
1011
|
+
maxCommittedSlot !== undefined) {
|
|
1012
|
+
const interleaved = maxCommittedSlot - expectedFirstSlot + 1 - committedCount;
|
|
1013
|
+
if (interleaved > 0) {
|
|
1014
|
+
runtimeLogger.debug('Batched fan-out committed above snapshot', {
|
|
1015
|
+
workflowRunId: runId,
|
|
1016
|
+
expectedFirstSlot,
|
|
1017
|
+
maxCommittedSlot,
|
|
1018
|
+
committedCount,
|
|
1019
|
+
interleaved,
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
const failure = settled.find((outcome) => outcome.status === 'rejected');
|
|
1024
|
+
if (failure)
|
|
1025
|
+
throw failure.reason;
|
|
1026
|
+
})();
|
|
1027
|
+
// EVERY chunk carrying pairs gates the return, not just the first:
|
|
1028
|
+
// a pair whose commit the caller has not seen yields no
|
|
1029
|
+
// `inlineClaims` entry, so the caller falls back to a lazy
|
|
1030
|
+
// `step_started` that would race this same fold's still-in-flight
|
|
1031
|
+
// pair for the same step. Today pairs always land in one chunk
|
|
1032
|
+
// (they sort first, and two rows per inline step fit inside one
|
|
1033
|
+
// chunk — pinned by constants.test.ts), so this is at most one
|
|
1034
|
+
// commit; the filter is what keeps the property true if either cap
|
|
1035
|
+
// moves.
|
|
1036
|
+
const pairCommits = chunks.flatMap((chunk, index) => chunk.some((entry) => entry.kind === 'inline-started')
|
|
1037
|
+
? [commits[index]]
|
|
1038
|
+
: []);
|
|
1039
|
+
if (allowDeferredBatchWork) {
|
|
1040
|
+
// The trailing work is the caller's to join before ack. Attach a
|
|
1041
|
+
// handler now so a rejection that races that join (or a foreground
|
|
1042
|
+
// failure that prevents the caller from ever reaching it) is never
|
|
1043
|
+
// an unhandledRejection — awaiting the promise still observes it.
|
|
1044
|
+
trailing.catch(() => { });
|
|
1045
|
+
deferredBatchWork = trailing;
|
|
1046
|
+
// Only the pair chunks gate the return: their claims are what the
|
|
1047
|
+
// caller starts the inline bodies from. With no pairs there is
|
|
1048
|
+
// nothing the caller's post-return work reads from the commits,
|
|
1049
|
+
// so nothing gates.
|
|
1050
|
+
if (pairCommits.length > 0) {
|
|
1051
|
+
try {
|
|
1052
|
+
await Promise.all(pairCommits);
|
|
1053
|
+
}
|
|
1054
|
+
catch (err) {
|
|
1055
|
+
// A pair chunk failed, so this phase's write set is NOT the
|
|
1056
|
+
// caller's to join any more — `deferredBatchWork` never
|
|
1057
|
+
// reaches it once handleSuspension throws. Settle the rest
|
|
1058
|
+
// before the rejection escapes, for the reason `settlePhase`
|
|
1059
|
+
// gives: a sibling create landing after the throw commits an
|
|
1060
|
+
// event from the abandoned replay's seeded sequence and races
|
|
1061
|
+
// the caller's restart reload while doing so.
|
|
1062
|
+
await trailing.catch(() => { });
|
|
1063
|
+
throw err;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
else {
|
|
1068
|
+
await trailing;
|
|
1069
|
+
}
|
|
1070
|
+
})());
|
|
1071
|
+
}
|
|
482
1072
|
for (const queueItem of attributeItems) {
|
|
483
1073
|
ops.push((async () => {
|
|
484
1074
|
try {
|
|
@@ -575,11 +1165,18 @@ export async function handleSuspension({ suspension, world, run, span, requestId
|
|
|
575
1165
|
...Attribute.WorkflowStepsCreated(stepItems.length),
|
|
576
1166
|
...Attribute.WorkflowHooksCreated(hooksNeedingCreation.length),
|
|
577
1167
|
...Attribute.WorkflowWaitsCreated(waitItems.length),
|
|
1168
|
+
...(resilientDispatchRecovered > 0
|
|
1169
|
+
? Attribute.StepResilientDispatchRecovered(resilientDispatchRecovered)
|
|
1170
|
+
: {}),
|
|
578
1171
|
});
|
|
579
1172
|
return {
|
|
580
1173
|
pendingSteps: stepItems,
|
|
581
1174
|
createdStepCorrelationIds,
|
|
1175
|
+
queuedStepCorrelationIds,
|
|
582
1176
|
lazyInlineSteps,
|
|
1177
|
+
inlineClaims,
|
|
1178
|
+
batchCommittedSlotCeiling,
|
|
1179
|
+
deferredBatchWork,
|
|
583
1180
|
// On hook conflict the caller re-invokes immediately and never reads
|
|
584
1181
|
// the wait timeout, so don't report one.
|
|
585
1182
|
waitTimeout: hasHookConflict ? undefined : soonestWait,
|
|
@@ -609,4 +1206,4 @@ function isWorldValidationFailure(err) {
|
|
|
609
1206
|
}
|
|
610
1207
|
return WorkflowWorldError.is(err) && err.status === 400;
|
|
611
1208
|
}
|
|
612
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VzcGVuc2lvbi1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvc3VzcGVuc2lvbi1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsVUFBVSxFQUNWLGlCQUFpQixFQUNqQix1QkFBdUIsRUFDdkIsZUFBZSxFQUNmLGtCQUFrQixHQUNuQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFDTCx3QkFBd0IsRUFLeEIsb0JBQW9CLEVBQ3BCLGlDQUFpQyxHQUdsQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQVE3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTdDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdELE9BQU8sS0FBSyxTQUFTLE1BQU0sc0NBQXNDLENBQUM7QUFDbEUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25ELE9BQU8sRUFHTCxtQkFBbUIsRUFDbkIsMEJBQTBCLEdBQzNCLE1BQU0sY0FBYyxDQUFDO0FBQ3RCLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBK0d2RSxLQUFLLFVBQVUsZUFBZSxDQUFDLEVBQzdCLEtBQUssRUFDTCxTQUFTLEVBQ1QsU0FBUyxFQUNULFNBQVMsRUFDVCxXQUFXLEdBVVo7SUFJQyxJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxTQUFTLEVBQUU7WUFDMUMsU0FBUztTQUNWLENBQUMsQ0FBQztRQUVILDZFQUE2RTtRQUM3RSwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ3pFLElBQUksTUFBTSxDQUFDLEtB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Q0FBQyxNQUFNLEdBQUcsQ0FBQztRQUM5QyxjQUFjO1FBQ2Qsc0JBQXNCO1FBQ3RCLGtCQUFrQixFQUFFLGNBQWM7S0FDbkMsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsd0JBQXdCLENBQUMsR0FBWTtJQUM1QyxJQUFJLEdBQUcsWUFBWSx3QkFBd0I7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN6RCxJQUFJLEdBQUcsWUFBWSxLQUFLLElBQUksR0FBRyxDQUFDLElBQUksS0FBSywwQkFBMEIsRUFBRSxDQUFDO1FBQ3BFLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE9BQU8sa0JBQWtCLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDO0FBQzFELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFNwYW4gfSBmcm9tICdAb3BlbnRlbGVtZXRyeS9hcGknO1xuaW1wb3J0IHtcbiAgRW50aXR5Q29uZmxpY3RFcnJvcixcbiAgRmF0YWxFcnJvcixcbiAgSG9va05vdEZvdW5kRXJyb3IsXG4gIFByZWNvbmRpdGlvbkZhaWxlZEVycm9yLFxuICBSdW5FeHBpcmVkRXJyb3IsXG4gIFdvcmtmbG93V29ybGRFcnJvcixcbn0gZnJvbSAnQHdvcmtmbG93L2Vycm9ycyc7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVWYWxpZGF0aW9uRXJyb3IsXG4gIHR5cGUgQ3JlYXRlRXZlbnRQYXJhbXMsXG4gIHR5cGUgQ3JlYXRlRXZlbnRSZXF1ZXN0LFxuICB0eXBlIEV2ZW50UmVzdWx0LFxuICB0eXBlIFNlcmlhbGl6ZWREYXRhLFxuICBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NPTVBSRVNTSU9OLFxuICB0eXBlIFdvcmtmbG93UnVuLFxuICB0eXBlIFdvcmxkLFxufSBmcm9tICdAd29ya2Zsb3cvd29ybGQnO1xuaW1wb3J0IHsgaW1wb3J0S2V5IH0gZnJvbSAnLi4vZW5jcnlwdGlvbi5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEF0dHJpYnV0ZUludm9jYXRpb25RdWV1ZUl0ZW0sXG4gIEhvb2tJbnZvY2F0aW9uUXVldWVJdGVtLFxuICBTdGVwSW52b2NhdGlvblF1ZXVlSXRlbSxcbiAgV2FpdEludm9jYXRpb25RdWV1ZUl0ZW0sXG4gIFdvcmtmbG93U3VzcGVuc2lvbixcbn0gZnJvbSAnLi4vZ2xvYmFsLmpzJztcbmltcG9ydCB7IHJ1bnRpbWVMb2dnZXIgfSBmcm9tICcuLi9sb2dnZXIuanMnO1xuaW1wb3J0IHR5cGUgeyBHdWVzdENvZGVTdGF0cyB9IGZyb20gJy4uL3NlcmlhbGl6YXRpb24vaGFyZGVuZWQuanMnO1xuaW1wb3J0IHsgZGVoeWRyYXRlU3RlcEFyZ3VtZW50cyB9IGZyb20gJy4uL3NlcmlhbGl6YXRpb24uanMnO1xuaW1wb3J0ICogYXMgQXR0cmlidXRlIGZyb20gJy4uL3RlbGVtZXRyeS9zZW1hbnRpYy1jb252ZW50aW9ucy5qcyc7XG5pbXBvcnQgeyBnZXRBYm9ydFN0cmVhbUlkRnJvbVRva2VuIH0gZnJvbSAnLi4vdXRpbC5qcyc7XG5pbXBvcnQgeyBnZXRNYXhJbmxpbmVTdGVwcyB9IGZyb20gJy4vY29uc3RhbnRzLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgRXZlbnRDcmVhdG9yLFxuICB0eXBlIExvYWRlZEV2ZW50TG9nLFxuICBtZXJnZVJlcG9ydGVkRXZlbnRzLFxuICBwcmVjb25kaXRpb25TbmFwc2hvdFBhcmFtcyxcbn0gZnJvbSAnLi9oZWxwZXJzLmpzJztcbmltcG9ydCB7IFJlcGxheVJlY292ZXJ5UmVwb3J0ZXIgfSBmcm9tICcuL3JlcGxheS1yZWNvdmVyeS1yZXBvcnRlci5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VzcGVuc2lvbkhhbmRsZXJQYXJhbXMge1xuICBzdXNwZW5zaW9uOiBXb3JrZmxvd1N1c3BlbnNpb247XG4gIHdvcmxkOiBXb3JsZDtcbiAgcnVuOiBXb3JrZmxvd1J1bjtcbiAgc3Bhbj86IFNwYW47XG4gIHJlcXVlc3RJZD86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBydW50aW1lJ3MgbG9hZGVkIGV2ZW50IGxvZy4gRXZlcnkgZXZlbnQgY3JlYXRpb24gdGhpcyBzdXNwZW5zaW9uIG1ha2VzXG4gICAqIGlzIHNlbnQgd2l0aCB0aGUgcHJlY29uZGl0aW9uIHNuYXBzaG90IGRlcml2ZWQgZnJvbSBpdCwgc28gYSBiYWNrZW5kIHRoYXRcbiAgICogaGFzIHJlY29yZGVkIGFuIGV2ZW50IHRoZSByZXBsYXkgZGlkIG5vdCBzZWUgcmVqZWN0cyB0aGUgd3JpdGUgd2l0aCBhIDQxMlxuICAgKiBpbnN0ZWFkIG9mIGFjY2VwdGluZyBhIGRpdmVyZ2VudCBldmVudC4gVGhlIHJlamVjdGlvbiBpcyBub3QgcmV0cmllZCBoZXJlOlxuICAgKiB0aGUgZXZlbnQncyBjb3JyZWxhdGlvbiBpZCB3YXMgbWludGVkIGJ5ICp0aGlzKiByZXBsYXkncyBzZWVkZWQgc2VxdWVuY2UsXG4gICAqIHNvIHJlLWNvbW1pdHRpbmcgaXQgYWdhaW5zdCBhIGNvcnJlY3RlZCBsb2cgd291bGQgcGVyc2lzdCBhbiBldmVudCBub1xuICAgKiBjb3JyZWN0IHJlcGxheSBwcm9kdWNlcy4gVGhlIGNhbGxlciByZXN0YXJ0cyB0aGUgcmVwbGF5IGluc3RlYWQuXG4gICAqL1xuICBldmVudExvZz86IExvYWRlZEV2ZW50TG9nO1xuICAvKipcbiAgICogVHVyYm8gbW9kZSBvbmx5OiBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBiYWNrZ3JvdW5kZWRcbiAgICogYHJ1bl9zdGFydGVkYCBoYXMgbGFuZGVkICh0aGUgcnVuIGV4aXN0cykuIFdoZW4gcHJlc2VudCwgZXZlcnkgd29ybGQgd3JpdGVcbiAgICogdGhpcyBzdXNwZW5zaW9uIHBlcmZvcm1zIChgaG9va19jcmVhdGVkYCwgYHdhaXRfY3JlYXRlZGAsIGVhZ2VyIG92ZXJmbG93XG4gICAqIGBzdGVwX2NyZWF0ZWRgLCDigKYpIGlzIGdhdGVkIG9uIGl0IHNvIHRoZSB3cml0ZSBuZXZlciByYWNlcyBhaGVhZCBvZiB0aGVcbiAgICogcnVuJ3MgY3JlYXRpb24uIFRoZSBwdXJlIGlubGluZSBob3QgcGF0aCBkZWZlcnMgYWxsIG9mIGl0cyBzdGVwcyBhbmQgd3JpdGVzXG4gICAqIG5vdGhpbmcgaGVyZSwgc28gaXQgbmV2ZXIgYXdhaXRzIHRoaXMgYmFycmllci4gYHVuZGVmaW5lZGAgb3V0c2lkZSB0dXJibyxcbiAgICogd2hlcmUgYHJ1bl9zdGFydGVkYCB3YXMgYWxyZWFkeSBhd2FpdGVkIHVwIGZyb250LlxuICAgKi9cbiAgcnVuUmVhZHlCYXJyaWVyPzogUHJvbWlzZTx1bmtub3duPjtcbiAgLyoqIE9uZS1zaG90IHRlbGVtZXRyeSByZXBvcnRlciwgYWN0aXZhdGVkIG9ubHkgYWZ0ZXIgcmVwbGF5IGhhcyByZWNvdmVyZWQuICovXG4gIHJlcGxheVJlY292ZXJ5UmVwb3J0ZXI/OiBSZXBsYXlSZWNvdmVyeVJlcG9ydGVyO1xufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBoYW5kbGluZyBhIHN1c3BlbnNpb24uIFJldHVybnMgcGVuZGluZyBzdGVwIGl0ZW1zIHNvIHRoZSBjYWxsZXJcbiAqIGNhbiBkZWNpZGUgd2hpY2ggdG8gZXhlY3V0ZSBpbmxpbmUgdnMgcXVldWUgdG8gYmFja2dyb3VuZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdXNwZW5zaW9uSGFuZGxlclJlc3VsdCB7XG4gIC8qKiBQZW5kaW5nIHN0ZXAgaXRlbXMgd2l0aCBldmVudHMgY3JlYXRlZCBidXQgTk9UIHF1ZXVlZCAqL1xuICBwZW5kaW5nU3RlcHM6IFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtW107XG4gIC8qKlxuICAgKiBDb3JyZWxhdGlvbiBJRHMgZm9yIHdoaWNoIHRoaXMgc3VzcGVuc2lvbiBjYWxsIGFjdHVhbGx5IHdyb3RlIHRoZVxuICAgKiBzdGVwX2NyZWF0ZWQgZXZlbnQgKGFzIG9wcG9zZWQgdG8gY2F0Y2hpbmcgRW50aXR5Q29uZmxpY3RFcnJvciBiZWNhdXNlXG4gICAqIGEgY29uY3VycmVudCBoYW5kbGVyIHdyb3RlIGl0IGZpcnN0KS4gT25seSB0aGUgaGFuZGxlciB0aGF0IHdyb3RlIHRoZVxuICAgKiBzdGVwX2NyZWF0ZWQgZXZlbnQgc2hvdWxkIHF1ZXVlIC8gaW5saW5lLWV4ZWN1dGUgdGhlIHN0ZXAg4oCUIHRoaXNcbiAgICogZ3VhcmFudGVlcyBhIHNpbmdsZSBvd25lciBwZXIgc3RlcCwgZXZlbiB3aGVuIG11bHRpcGxlIGhhbmRsZXJzIHJhY2VcbiAgICogaW50byB0aGUgc2FtZSBiYXRjaCBib3VuZGFyeS5cbiAgICovXG4gIGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHM6IFNldDxzdHJpbmc+O1xuICAvKipcbiAgICogSG93IG1hbnkgZXZlbnRzIHRoaXMgcGhhc2UncyB3cml0ZXMgcmVwb3J0ZWQgYmFjayBhcyBvY2N1cHlpbmcgc2xvdHMgdGhleVxuICAgKiBza2lwcGVkIG92ZXIsIGFscmVhZHkgbWVyZ2VkIGludG8gdGhlIGNhbGxlcidzIGBldmVudExvZy5ldmVudHNgLiBOb256ZXJvXG4gICAqIG1lYW5zIHRoZSBhcnJheSB3YXMgcmVvcmRlcmVkIHRvIHJlc3RvcmUgc2xvdCBvcmRlciwgc28gYW55IGluZGV4IHRoZVxuICAgKiBjYWxsZXIgY2FjaGVkIGludG8gaXQgKHBheWxvYWQgcHJld2FybSBzY2FuIHBvc2l0aW9uKSBpcyBzdGFsZS5cbiAgICovXG4gIHJlcG9ydGVkRXZlbnRDb3VudDogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIHN0ZXBzIHdob3NlIGBzdGVwX2NyZWF0ZWRgIHdyaXRlcyB3ZXJlIGludGVudGlvbmFsbHkgZGVmZXJyZWQgc28gdGhlXG4gICAqIGNhbGxlciBjYW4gcnVuIHRoZW0gaW5saW5lIHZpYSBsYXp5IGBzdGVwX3N0YXJ0ZWRgIGV2ZW50cyAod2hpY2ggY3JlYXRlXG4gICAqIHRoZSBzdGVwIG9uIHRoZSBmbHkpLCBzYXZpbmcgb25lIHdvcmxkIHJvdW5kLXRyaXAgcGVyIGlubGluZSBzdGVwLiBVcCB0b1xuICAgKiBgZ2V0TWF4SW5saW5lU3RlcHMoKWAgc3RlcHMgYXJlIGRlZmVycmVkOyB0aGUgY2FsbGVyIHJ1bnMgdGhlbSBpbmxpbmUgaW5cbiAgICogcGFyYWxsZWwgYW5kIHF1ZXVlcyB0aGUgcmVzdC4gRW1wdHkgd2hlbiBubyBzdGVwIHdhcyBkZWZlcnJlZCAobm90aGluZ1xuICAgKiBwZW5kaW5nLCBvciBhIGBob29rLmdldENvbmZsaWN0KClgIGF3YWl0ZXIgaXMgcHJlc2VudCBzbyBub3RoaW5nIGlzXG4gICAqIGV4ZWN1dGVkIGlubGluZSkuIFRoZSBjYWxsZXIgcGFzc2VzIGVhY2ggYGRlaHlkcmF0ZWRJbnB1dGAgc3RyYWlnaHQgdG9cbiAgICogYGV4ZWN1dGVTdGVwYCwgd2hpY2ggc2VuZHMgaXQgYXMgdGhlIGBzdGVwX3N0YXJ0ZWRgIHBheWxvYWQuIFRoZSBhdG9taWNcbiAgICogY3JlYXRlLWNsYWltIGluc2lkZSBlYWNoIGBzdGVwX3N0YXJ0ZWRgIGlzIHRoZSBleGFjdGx5LW9uZS1vd25lciBnYXRlIHRoYXRcbiAgICogdGhlIHN0YW5kYWxvbmUgYHN0ZXBfY3JlYXRlZGAgcHJvdmlkZWQgYmVmb3JlOiB0aGUgbG9zZXIgb2YgdGhlIHJhY2UgZ2V0c1xuICAgKiBgRW50aXR5Q29uZmxpY3RFcnJvcmAg4oaSIGBza2lwcGVkYCBhbmQgZG9lcyBub3QgcnVuIHRoZSBib2R5LlxuICAgKi9cbiAgbGF6eUlubGluZVN0ZXBzOiBBcnJheTx7XG4gICAgY29ycmVsYXRpb25JZDogc3RyaW5nO1xuICAgIHN0ZXBOYW1lOiBzdHJpbmc7XG4gICAgZGVoeWRyYXRlZElucHV0OiBTZXJpYWxpemVkRGF0YTtcbiAgfT47XG4gIC8qKlxuICAgKiBUaGUgc29vbmVzdCBwZW5kaW5nIHdhaXQsIGlmIGFueTogc2Vjb25kcyB1bnRpbCBpdCBlbGFwc2VzIGFuZCB0aGVcbiAgICogY29ycmVsYXRpb25JZCBvZiB0aGUgd2FpdCB0aGF0IHByb2R1Y2VkIHRoYXQgdGltZW91dC4gVGhlXG4gICAqIGNvcnJlbGF0aW9uSWQgc2VlZHMgdGhlIGlkZW1wb3RlbmN5IGtleSBmb3IgdGhlIHdhaXQtY29udGludWF0aW9uXG4gICAqIHF1ZXVlIG1lc3NhZ2Ugc28gdGhhdCByZXBlYXRlZCBzdXNwZW5zaW9uIHBhc3NlcyBvdmVyIHRoZSBzYW1lXG4gICAqIHBlbmRpbmcgd2FpdCBjb2xsYXBzZSBpbnRvIGEgc2luZ2xlIGRlbGF5ZWQgY29udGludWF0aW9uLlxuICAgKi9cbiAgd2FpdFRpbWVvdXQ/OiB7IHNlY29uZHM6IG51bWJlcjsgY29ycmVsYXRpb25JZDogc3RyaW5nIH07XG4gIC8qKiBXaGV0aGVyIGEgaG9vayBjb25mbGljdCB3YXMgZGV0ZWN0ZWQgKHNob3VsZCByZS1pbnZva2UgaW1tZWRpYXRlbHkpICovXG4gIGhhc0hvb2tDb25mbGljdDogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgYSBgaG9vay5nZXRDb25mbGljdCgpYCBhd2FpdGVyIG5lZWRzIHRoZSB3b3JrZmxvdyB0byBjb250aW51ZSBpbW1lZGlhdGVseSAqL1xuICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBib29sZWFuO1xuICAvKiogV2hldGhlciBuYXRpdmUgd29ya2Zsb3cgYXR0cmlidXRlIGV2ZW50cyB3ZXJlIHdyaXR0ZW4gZm9yIHJlcGxheS4gKi9cbiAgaGFzQXR0cmlidXRlRXZlbnRzOiBib29sZWFuO1xuICAvKipcbiAgICogV2hldGhlciB0aGlzIHN1c3BlbnNpb24gY3JlYXRlZCBhbnkgaG9vayAoYGhvb2tfY3JlYXRlZGApIGV2ZW50cy4gVW5saWtlXG4gICAqIGBoYXNIb29rQ29uZmxpY3RgIC8gYGhhc0F3YWl0ZWRIb29rQ3JlYXRpb25gLCB0aGlzIGlzIHRydWUgZXZlbiBmb3IgYSBwbGFpblxuICAgKiBmaXJlLWFuZC1mb3JnZXQgaG9vayB3aXRoIG5vIGNvbmZsaWN0IGFuZCBubyBhd2FpdGVyLiBUdXJibyBtb2RlIHVzZXMgaXQgdG9cbiAgICogZGV0ZWN0IFwiYSBob29rIHdhcyBjcmVhdGVkIHRoaXMgc3VzcGVuc2lvblwiIGFuZCBzdG9wIGZvcmNpbmcgb3B0aW1pc3RpY1xuICAgKiBpbmxpbmUgc3RhcnQgKGEgaG9vayBpbnRyb2R1Y2VzIGxhdGVyIHJlc3VtZSBpbnZvY2F0aW9ucyB0aGF0IGNvdWxkIHJhY2UpLlxuICAgKi9cbiAgaGFzSG9va0V2ZW50czogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFdhbGwtY2xvY2sgbXMgc3BlbnQgY29tbWl0dGluZyB0aGlzIHN1c3BlbnNpb24ncyBgaG9va19jcmVhdGVkYCBldmVudHNcbiAgICogKDAgd2hlbiBpdCBjcmVhdGVkIG5vbmUpLiBUaGUgY2FsbGVyIGFjY3VtdWxhdGVzIHRoaXMgYWNyb3NzIGl0ZXJhdGlvbnNcbiAgICogYW5kIHN1YnRyYWN0cyBpdCBmcm9tIHRoZSBUVEZTIGxhdGVuY3kgbWVhc3VyZW1lbnQsIHNvIHRpbWUgc3BlbnRcbiAgICogZHVyYWJseSBjcmVhdGluZyB0aGUgdXNlcidzIGhvb2tzIGRvZXNuJ3QgY291bnQgYXMgcnVudGltZSBvdmVyaGVhZC5cbiAgICovXG4gIGhvb2tDcmVhdGlvbk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHNlcmlhbGl6aW5nIHRoaXMgc3VzcGVuc2lvbidzIG5ldyBzdGVwIGlucHV0cyB3YXMgcGFzc2l2ZSAoZGlkXG4gICAqIG5vdCBleGVjdXRlIHdvcmtmbG93LW93bmVkIGNvZGUgc3VjaCBhcyBnZXR0ZXJzLCBwcm94eSB0cmFwcywgb3IgY3VzdG9tXG4gICAqIHNlcmlhbGl6ZXJzKS4gYGZhbHNlYCBtZWFucyB0aGUgcmV0YWluZWQgVk0gbWF5IGhhdmUgZGl2ZXJnZWQgZnJvbSB3aGF0XG4gICAqIGEgY29sZCByZXBsYXkgd291bGQgY29tcHV0ZSwgc28gdGhlIGNhbGxlciBtdXN0IGRlbW90ZSB0byByZXBsYXkuXG4gICAqL1xuICByZXRhaW5lZFN0ZXBJbnB1dHNTYWZlOiBib29sZWFuO1xufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVIb29rRXZlbnQoe1xuICBydW5JZCxcbiAgaG9va0V2ZW50LFxuICBxdWV1ZUl0ZW0sXG4gIHJlcXVlc3RJZCxcbiAgY3JlYXRlRXZlbnQsXG59OiB7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIGhvb2tFdmVudDogQ3JlYXRlRXZlbnRSZXF1ZXN0O1xuICBxdWV1ZUl0ZW06IEhvb2tJbnZvY2F0aW9uUXVldWVJdGVtO1xuICByZXF1ZXN0SWQ/OiBzdHJpbmc7XG4gIGNyZWF0ZUV2ZW50OiAoXG4gICAgZGF0YTogQ3JlYXRlRXZlbnRSZXF1ZXN0LFxuICAgIHBhcmFtcz86IENyZWF0ZUV2ZW50UGFyYW1zXG4gICkgPT4gUHJvbWlzZTxFdmVudFJlc3VsdD47XG59KTogUHJvbWlzZTx7XG4gIGhhc0hvb2tDb25mbGljdDogYm9vbGVhbjtcbiAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogYm9vbGVhbjtcbn0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjcmVhdGVFdmVudChob29rRXZlbnQsIHtcbiAgICAgIHJlcXVlc3RJZCxcbiAgICB9KTtcblxuICAgIC8vIENoZWNrIGlmIHRoZSB3b3JsZCByZXR1cm5lZCBhIGhvb2tfY29uZmxpY3QgZXZlbnQgaW5zdGVhZCBvZiBob29rX2NyZWF0ZWQuXG4gICAgLy8gVGhlIGhvb2tfY29uZmxpY3QgZXZlbnQgaXMgc3RvcmVkIGluIHRoZSBldmVudCBsb2cgYW5kIHdpbGwgYmUgcmVwbGF5ZWRcbiAgICAvLyBvbiB0aGUgbmV4dCB3b3JrZmxvdyBpbnZvY2F0aW9uLCBjYXVzaW5nIHRoZSBob29rJ3MgcHJvbWlzZSB0byByZWplY3QuXG4gICAgaWYgKHJlc3VsdC5ldmVudD8uZXZlbnRUeXBlID09PSAnaG9va19jb25mbGljdCcpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGhhc0hvb2tDb25mbGljdDogdHJ1ZSxcbiAgICAgICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogZmFsc2UsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBoYXNIb29rQ29uZmxpY3Q6IGZhbHNlLFxuICAgICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogcXVldWVJdGVtLmhhc0NvbmZsaWN0QXdhaXRlciA9PT0gdHJ1ZSxcbiAgICB9O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpKSB7XG4gICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ0hvb2sgYWxyZWFkeSBleGlzdHMsIGNvbnRpbnVpbmcnLCB7XG4gICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGFzSG9va0NvbmZsaWN0OiBmYWxzZSxcbiAgICAgICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogcXVldWVJdGVtLmhhc0NvbmZsaWN0QXdhaXRlciA9PT0gdHJ1ZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKFJ1bkV4cGlyZWRFcnJvci5pcyhlcnIpKSB7XG4gICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ1dvcmtmbG93IHJ1biBhbHJlYWR5IGNvbXBsZXRlZCwgc2tpcHBpbmcgaG9vaycsIHtcbiAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBoYXNIb29rQ29uZmxpY3Q6IGZhbHNlLFxuICAgICAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBmYWxzZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKGlzV29ybGRWYWxpZGF0aW9uRmFpbHVyZShlcnIpKSB7XG4gICAgICBjb25zdCBmYXRhbCA9IG5ldyBGYXRhbEVycm9yKFxuICAgICAgICBgY3JlYXRlSG9vayBmYWlsZWQgV29ybGQgdmFsaWRhdGlvbjogJHtcbiAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycilcbiAgICAgICAgfWBcbiAgICAgICk7XG4gICAgICBmYXRhbC5jYXVzZSA9IGVycjtcbiAgICAgIHRocm93IGZhdGFsO1xuICAgIH1cblxuICAgIHRocm93IGVycjtcbiAgfVxufVxuXG4vKipcbiAqIEhhbmRsZXMgYSB3b3JrZmxvdyBzdXNwZW5zaW9uIGJ5IHByb2Nlc3NpbmcgYWxsIHBlbmRpbmcgb3BlcmF0aW9ucyAoaG9va3MsIHN0ZXBzLCB3YWl0cykuXG4gKiBDcmVhdGVzIGV2ZW50cyBmb3IgYWxsIG9wZXJhdGlvbnMgYnV0IGRvZXMgTk9UIHF1ZXVlIHN0ZXAgbWVzc2FnZXMg4oCUIHJldHVybnMgdGhlIHBlbmRpbmdcbiAqIHN0ZXBzIHNvIHRoZSBjYWxsZXIgY2FuIGRlY2lkZSB3aGljaCB0byBleGVjdXRlIGlubGluZSB2cyBxdWV1ZSB0byBiYWNrZ3JvdW5kLlxuICpcbiAqIFByb2Nlc3Npbmcgb3JkZXI6XG4gKiAxLiBIb29rcyBhcmUgcHJvY2Vzc2VkIGZpcnN0IHRvIHByZXZlbnQgcmFjZSBjb25kaXRpb25zIHdpdGggd2ViaG9vayByZWNlaXZlcnNcbiAqIDIuIFN0ZXAgZXZlbnRzIGFuZCB3YWl0IGV2ZW50cyBhcmUgY3JlYXRlZCBpbiBwYXJhbGxlbFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlU3VzcGVuc2lvbih7XG4gIHN1c3BlbnNpb24sXG4gIHdvcmxkLFxuICBydW4sXG4gIHNwYW4sXG4gIHJlcXVlc3RJZCxcbiAgZXZlbnRMb2csXG4gIHJ1blJlYWR5QmFycmllcixcbiAgcmVwbGF5UmVjb3ZlcnlSZXBvcnRlcixcbn06IFN1c3BlbnNpb25IYW5kbGVyUGFyYW1zKTogUHJvbWlzZTxTdXNwZW5zaW9uSGFuZGxlclJlc3VsdD4ge1xuICBjb25zdCBydW5JZCA9IHJ1bi5ydW5JZDtcblxuICAvLyBUdXJibyBtb2RlOiBob2xkIGV2ZXJ5IHdvcmxkIHdyaXRlIGJlbG93IHVudGlsIHRoZSBiYWNrZ3JvdW5kZWRcbiAgLy8gYHJ1bl9zdGFydGVkYCBoYXMgKnNldHRsZWQqLCBzbyB3ZSBuZXZlciB3cml0ZSBhIHN0ZXAvaG9vay93YWl0IGV2ZW50IGZvciBhXG4gIC8vIHJ1biB0aGF0IGRvZXMgbm90IGV4aXN0IHlldC4gQSBuby1vcCBvdXRzaWRlIHR1cmJvIChiYXJyaWVyIHVuZGVmaW5lZCkgYW5kXG4gIC8vIG9uIHRoZSBwdXJlIGlubGluZSBob3QgcGF0aCwgd2hpY2ggZGVmZXJzIGFsbCBzdGVwcyBhbmQgd3JpdGVzIG5vdGhpbmcuXG4gIC8vIEF3YWl0aW5nIHRoZSBzYW1lICh1c3VhbGx5IGFscmVhZHktc2V0dGxlZCkgcHJvbWlzZSBtb3JlIHRoYW4gb25jZSBpcyBjaGVhcC5cbiAgLy8gQSBiYXJyaWVyIHJlamVjdGlvbiBpcyBzd2FsbG93ZWQgZm9yIG9yZGVyaW5nIG9ubHk6IGlmIGBydW5fc3RhcnRlZGAgdHJ1bHlcbiAgLy8gZmFpbGVkIHRoZSBydW4gZG9lcyBub3QgZXhpc3QsIHNvIHRoZSBzdWJzZXF1ZW50IHdyaXRlIHN1cmZhY2VzIHRoZSByZWFsXG4gIC8vIGVycm9yIChydW4gbm90IGZvdW5kIC8gZ29uZSkgYW5kIHRoZSBtZXNzYWdlIHJlZGVsaXZlcnMuXG4gIGNvbnN0IGVuc3VyZVJ1blJlYWR5ID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmIChydW5SZWFkeUJhcnJpZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHJ1blJlYWR5QmFycmllcjtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBpbnRlbnRpb25hbDogb3JkZXJpbmcgYmFycmllciBvbmx5IOKAlCBzZWUgYWJvdmUuXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBBd2FpdCBldmVyeSBvcGVyYXRpb24gaW4gYSBzdXNwZW5zaW9uIHBoYXNlIGJlZm9yZSBsZXR0aW5nIGEgZmFpbHVyZVxuICAgKiBlc2NhcGUsIHByZWZlcnJpbmcgYSBzdGFsZS1zbmFwc2hvdCAoNDEyKSByZWplY3Rpb24gd2hlbiBvbmUgb2NjdXJyZWQuXG4gICAqXG4gICAqIGBQcm9taXNlLmFsbGAgcmVqZWN0cyBhcyBzb29uIGFzIG9uZSBvcGVyYXRpb24gZG9lcyBhbmQgbGVhdmVzIGl0cyBzaWJsaW5nc1xuICAgKiBpbiBmbGlnaHQuIFRoYXQgbWF0dGVycyBmb3IgYSA0MTI6IHRoZSBjYWxsZXIgcmVhY3RzIGJ5IHJlbG9hZGluZyB0aGUgZXZlbnRcbiAgICogbG9nIGFuZCByZXN0YXJ0aW5nIHRoZSByZXBsYXksIHNvIGEgc2libGluZyBjcmVhdGUgdGhhdCBsYW5kcyBhZnRlciB0aGVcbiAgICogcmVqZWN0aW9uIGVzY2FwZWQgY29tbWl0cyBhbiBldmVudCB3aG9zZSBjb3JyZWxhdGlvbiBpZCBjYW1lIGZyb20gdGhlXG4gICAqIGFiYW5kb25lZCByZXBsYXkncyBzZWVkZWQgc2VxdWVuY2Ug4oCUIGFuIGV2ZW50IHRoZSBmcmVzaCByZXBsYXkgbmV2ZXJcbiAgICogcHJvZHVjZXMg4oCUIGFuZCBpdCByYWNlcyB0aGUgcmVzdGFydCdzIHJlbG9hZCB3aGlsZSBkb2luZyBzby4gU2V0dGxpbmcgZmlyc3RcbiAgICogbWFrZXMgdGhpcyBwaGFzZSdzIHdyaXRlIHNldCBmaW5hbCBiZWZvcmUgdGhlIGNhbGxlciBhY3RzIG9uIHRoZSBmYWlsdXJlLlxuICAgKiBJdCBtaXJyb3JzIHRoZSBydW50aW1lJ3MgaW5saW5lIHN0ZXAgY2xhaW0sIHdoaWNoIHNldHRsZXMgdGhlIGluLWZsaWdodFxuICAgKiBzdGVwIGV4ZWN1dGlvbnMgYmVmb3JlIGVzY2FsYXRpbmcgYSA0MTIuXG4gICAqXG4gICAqIEEgNDEyIGlzIHByZWZlcnJlZCBvdmVyIGFueSBvdGhlciByZWplY3Rpb24gaW4gdGhlIHNhbWUgcGhhc2UgYmVjYXVzZSBpdFxuICAgKiBoYXMgYSBkZWZpbmVkLCBjaGVhcCByZWNvdmVyeSAocmVwbGF5IGZyb20gYSBjb3JyZWN0ZWQgbG9nKSB3aGlsZSB0aGVcbiAgICogb3RoZXJzIGRvIG5vdC4gQSBkZXRlcm1pbmlzdGljIGZhaWx1cmUgc3VjaCBhcyBhbiBhdHRyaWJ1dGUtdmFsaWRhdGlvblxuICAgKiBgRmF0YWxFcnJvcmAgcmVjdXJzIG9uIHRoZSByZXN0YXJ0IGFuZCBmYWlscyB0aGUgcnVuIHRoZW4sIGF0IHRoZSBjb3N0IG9mXG4gICAqIG9uZSBleHRyYSByZXBsYXkuXG4gICAqL1xuICBjb25zdCBzZXR0bGVQaGFzZSA9IGFzeW5jIChvcHM6IFByb21pc2U8dW5rbm93bj5bXSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHJlYXNvbnMgPSAoYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKG9wcykpXG4gICAgICAuZmlsdGVyKChyKTogciBpcyBQcm9taXNlUmVqZWN0ZWRSZXN1bHQgPT4gci5zdGF0dXMgPT09ICdyZWplY3RlZCcpXG4gICAgICAubWFwKChyKSA9PiByLnJlYXNvbik7XG4gICAgaWYgKHJlYXNvbnMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgdGhyb3cgcmVhc29ucy5maW5kKChyKSA9PiBQcmVjb25kaXRpb25GYWlsZWRFcnJvci5pcyhyKSkgPz8gcmVhc29uc1swXTtcbiAgfTtcblxuICAvLyBFdmVyeSBzdXNwZW5zaW9uIHdyaXRlIGNhcnJpZXMgcmVwbGF5LXJlY292ZXJ5IHRlbGVtZXRyeSBvbiB0aGUgZmlyc3Qgb25lXG4gIC8vIHRoYXQgY29tbWl0cyBhZnRlciByZXBsYXkgcmVjb3ZlcmVkLiBBbGwgc3VzcGVuc2lvbiBldmVudHMgYXJlXG4gIC8vIG5vbi1ydW5fY3JlYXRlZCBldmVudHMgb24gdGhpcyBydW4ncyBgcnVuSWRgLlxuICBjb25zdCByZXBvcnRlciA9IHJlcGxheVJlY292ZXJ5UmVwb3J0ZXIgPz8gUmVwbGF5UmVjb3ZlcnlSZXBvcnRlci5pbmVydCgpO1xuICBjb25zdCBjcmVhdGVFdmVudCA9IChkYXRhOiBDcmVhdGVFdmVudFJlcXVlc3QsIHBhcmFtcz86IENyZWF0ZUV2ZW50UGFyYW1zKSA9PlxuICAgIHJlcG9ydGVyLndpdGhFdmVudENyZWF0ZShwYXJhbXMsIChwKSA9PlxuICAgICAgd29ybGQuZXZlbnRzLmNyZWF0ZShydW5JZCwgZGF0YSwgcClcbiAgICApO1xuICAvLyBBZGRzIHRoZSBvcHRpbWlzdGljLWNvbmN1cnJlbmN5IGd1YXJkIHdoZW4gdGhlIGNhbGxlciBzdXBwbGllZCBhIGxvYWRlZFxuICAvLyBldmVudCBsb2c7IHdpdGhvdXQgb25lIGl0IGNyZWF0ZXMgZGlyZWN0bHkgKGNhbGxlcnMgd2l0aCBubyByZXBsYXlcbiAgLy8gc25hcHNob3QsIGUuZy4gdGVzdHMpLiBBIHN0YWxlICg0MTIpIHJlamVjdGlvbiBwcm9wYWdhdGVzIHRvIHRoZSBjYWxsZXIsXG4gIC8vIHdoaWNoIHJlc3RhcnRzIHRoZSByZXBsYXkgZnJvbSBhIGNvcnJlY3RlZCBsb2cg4oCUIGl0IGlzIG5vdCByZXRyaWVkIGhlcmUsXG4gIC8vIGJlY2F1c2UgdGhlIGV2ZW50J3MgY29ycmVsYXRpb24gaWQgd2FzIG1pbnRlZCBieSAqdGhpcyogcmVwbGF5J3Mgc2VlZGVkXG4gIC8vIHNlcXVlbmNlLCBzbyByZS1jb21taXR0aW5nIGl0IGFnYWluc3QgYSBjb3JyZWN0ZWQgbG9nIHdvdWxkIHBlcnNpc3QgYW5cbiAgLy8gZXZlbnQgbm8gY29ycmVjdCByZXBsYXkgcHJvZHVjZXMuXG4gIGxldCByZXBvcnRlZEV2ZW50cyA9IDA7XG4gIGNvbnN0IGNyZWF0ZUd1YXJkZWQ6IEV2ZW50Q3JlYXRvciA9IGFzeW5jIChkYXRhLCBwYXJhbXMpID0+IHtcbiAgICBpZiAoIWV2ZW50TG9nKSB7XG4gICAgICByZXR1cm4gY3JlYXRlRXZlbnQoZGF0YSwgcGFyYW1zKTtcbiAgICB9XG4gICAgY29uc3QgbG9nID0gZXZlbnRMb2c7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY3JlYXRlRXZlbnQoZGF0YSwge1xuICAgICAgLi4ucGFyYW1zLFxuICAgICAgLi4ucHJlY29uZGl0aW9uU25hcHNob3RQYXJhbXMobG9nLmV2ZW50cywgbG9nLmN1cnNvciksXG4gICAgfSk7XG4gICAgLy8gQnVtcC1hbmQtcmVwb3J0OiB0aGUgd3JpdGUgbGFuZGVkIGFib3ZlIHRoZSBzbG90IGl0IGFza2VkIGZvciwgc28gdGhlc2VcbiAgICAvLyBhcmUgdGhlIGV2ZW50cyBpdCB3YXMgZGVjaWRlZCB3aXRob3V0LiBNZXJnaW5nIHRoZW0gaGVyZSByYXRoZXIgdGhhbiBhdFxuICAgIC8vIGVhY2ggY2FsbCBzaXRlIG1lYW5zIHRoZSByZXN0IG9mIHRoaXMgcGhhc2UncyB3cml0ZXMg4oCUIHdoaWNoIHJlYWQgdGhlXG4gICAgLy8gc2FtZSBhcnJheSB0byBidWlsZCB0aGVpciBvd24gc25hcHNob3Qg4oCUIGFzayBmb3IgYSBzbG90IGFib3ZlIHRoZW0sIGFuZFxuICAgIC8vIHRoZSByZXBsYXkgdGhhdCByZXN1bWVzIGZyb20gdGhpcyBsb2cgc2VlcyB0aGVtIHdpdGhvdXQgYSByZWxvYWQuXG4gICAgLy9cbiAgICAvLyBBIHRydW5jYXRlZCByZXBvcnQgKGBoYXNNb3JlYCkgaXMgZHJvcHBlZCB3aG9sZSByYXRoZXIgdGhhbiBtZXJnZWQsIHRoZVxuICAgIC8vIHNhbWUgd2F5IHRoZSB3YWl0IGxvb3AgdHJlYXRzIG9uZS4gSXQgY292ZXJzIGEgc3BhbiBvZiBwb3NpdGlvbnMgYnV0XG4gICAgLy8gY2FycmllcyBvbmx5IHNvbWUgb2YgdGhlIGV2ZW50cyBvbiB0aGVtLCBzbyBtZXJnaW5nIGl0IHdvdWxkIHJhaXNlIHRoZVxuICAgIC8vIGxvZydzIGhpZ2hlc3QgcG9zaXRpb24gcGFzdCBhIHBvc2l0aW9uIHdob3NlIGV2ZW50IGlzIG1pc3NpbmcuIEV2ZXJ5XG4gICAgLy8gbGF0ZXIgd3JpdGUgb2YgdGhpcyBwaGFzZSByZWFkcyB0aGF0IG1heGltdW0gdG8gc2F5IHdoYXQgaXQgaGFzIHNlZW4sIHNvXG4gICAgLy8gZWFjaCB3b3VsZCBjbGFpbSBhIHBvc2l0aW9uIGl0IG5ldmVyIHNhdyBhbmQgdGhlIFdvcmxkLCB3aGljaCBvbmx5XG4gICAgLy8gcmVwb3J0cyB0aGUgc3BhbiBhIHdyaXRlIHNraXBzLCB3b3VsZCBuZXZlciBzZW5kIGl0LiBEcm9wcGluZyB0aGUgcmVwb3J0XG4gICAgLy8gY29zdHMgb25lIG1vcmUgcm91bmQgb2YgdGhlIHNhbWUgZXZlbnRzIG9uIHRoZSBuZXh0IHdyaXRlIGFuZCBrZWVwcyB0aGVcbiAgICAvLyBsb2cgYSBwcmVmaXggb2YgdGhlIHRydXRoLlxuICAgIGlmIChyZXN1bHQuZXZlbnRzPy5sZW5ndGggJiYgcmVzdWx0Lmhhc01vcmUgIT09IHRydWUpIHtcbiAgICAgIGNvbnN0IGFkZGVkID0gbWVyZ2VSZXBvcnRlZEV2ZW50cyhsb2cuZXZlbnRzLCByZXN1bHQuZXZlbnRzKTtcbiAgICAgIHJlcG9ydGVkRXZlbnRzICs9IGFkZGVkO1xuICAgICAgaWYgKGFkZGVkID4gMCkge1xuICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKCdTdXNwZW5zaW9uIHdyaXRlIHNraXBwZWQgb2NjdXBpZWQgc2xvdHMnLCB7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgZXZlbnRUeXBlOiBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgICBldmVudElkOiByZXN1bHQuZXZlbnQ/LmV2ZW50SWQsXG4gICAgICAgICAgcmVwb3J0ZWQ6IGFkZGVkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHJlc3VsdC5ldmVudHM/Lmxlbmd0aCkge1xuICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnRHJvcHBlZCBhIHRydW5jYXRlZCBza2lwcGVkLXNsb3QgcmVwb3J0Jywge1xuICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgZXZlbnRUeXBlOiBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgZXZlbnRJZDogcmVzdWx0LmV2ZW50Py5ldmVudElkLFxuICAgICAgICBvZmZlcmVkOiByZXN1bHQuZXZlbnRzLmxlbmd0aCxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xuICAvLyBTZXBhcmF0ZSBxdWV1ZSBpdGVtcyBieSB0eXBlXG4gIGNvbnN0IHN0ZXBJdGVtcyA9IHN1c3BlbnNpb24uc3RlcHMuZmlsdGVyKFxuICAgIChpdGVtKTogaXRlbSBpcyBTdGVwSW52b2NhdGlvblF1ZXVlSXRlbSA9PiBpdGVtLnR5cGUgPT09ICdzdGVwJ1xuICApO1xuICBjb25zdCBhbGxIb29rSXRlbXMgPSBzdXNwZW5zaW9uLnN0ZXBzLmZpbHRlcihcbiAgICAoaXRlbSk6IGl0ZW0gaXMgSG9va0ludm9jYXRpb25RdWV1ZUl0ZW0gPT4gaXRlbS50eXBlID09PSAnaG9vaydcbiAgKTtcbiAgY29uc3Qgd2FpdEl0ZW1zID0gc3VzcGVuc2lvbi5zdGVwcy5maWx0ZXIoXG4gICAgKGl0ZW0pOiBpdGVtIGlzIFdhaXRJbnZvY2F0aW9uUXVldWVJdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3dhaXQnXG4gICk7XG4gIGNvbnN0IGF0dHJpYnV0ZUl0ZW1zID0gc3VzcGVuc2lvbi5zdGVwcy5maWx0ZXIoXG4gICAgKGl0ZW0pOiBpdGVtIGlzIEF0dHJpYnV0ZUludm9jYXRpb25RdWV1ZUl0ZW0gPT4gaXRlbS50eXBlID09PSAnYXR0cmlidXRlJ1xuICApO1xuXG4gIGNvbnN0IGhvb2tzTmVlZGluZ0NyZWF0aW9uID0gYWxsSG9va0l0ZW1zLmZpbHRlcihcbiAgICAoaXRlbSkgPT4gIWl0ZW0uaGFzQ3JlYXRlZEV2ZW50XG4gICk7XG5cbiAgLy8gR3JvdXAgaG9vayBpdGVtcyB0aGF0IG5lZWQgd29yayBieSB0b2tlbiwgcHJlc2VydmluZyBxdWV1ZS1pbnNlcnRpb25cbiAgLy8gKHdvcmtmbG93IGNvZGUpIG9yZGVyIHdpdGhpbiBlYWNoIHRva2VuLiBPcGVyYXRpb25zIG9uIG9uZSB0b2tlbiBtdXN0XG4gIC8vIGFwcGx5IGluIGNvZGUgb3JkZXI6IGEgZGlzcG9zZSgpIG9mIGFuIGVhcmxpZXIgaG9vayByZWxlYXNlcyB0aGUgdG9rZW5cbiAgLy8gYmVmb3JlIGEgbGF0ZXIgc2FtZS10b2tlbiBob29rJ3MgY3JlYXRpb24gaXMgdmFsaWRhdGVkIOKAlCBvdGhlcndpc2UgdGhlXG4gIC8vIG5ldyBob29rIHJlY29yZHMgYSBzcHVyaW91cyBob29rX2NvbmZsaWN0IGFnYWluc3QgdGhlIHJ1bidzIG93blxuICAvLyBkaXNwb3NlZCBob29rIOKAlCB3aGlsZSBhIGhvb2sgY3JlYXRlZCBhbmQgZGlzcG9zZWQgd2l0aGluIHRoZSBzYW1lXG4gIC8vIHN1c3BlbnNpb24gaXMgc3RpbGwgY3JlYXRlZCBiZWZvcmUgaXQgaXMgZGlzcG9zZWQuIERpZmZlcmVudCB0b2tlbnNcbiAgLy8gaGF2ZSBubyBjbGFpbSBpbnRlcmFjdGlvbiwgc28gdG9rZW4gZ3JvdXBzIGFyZSBwcm9jZXNzZWQgaW4gcGFyYWxsZWwuXG4gIGNvbnN0IGhvb2tJdGVtc0J5VG9rZW4gPSBuZXcgTWFwPHN0cmluZywgSG9va0ludm9jYXRpb25RdWV1ZUl0ZW1bXT4oKTtcbiAgZm9yIChjb25zdCBpdGVtIG9mIGFsbEhvb2tJdGVtcykge1xuICAgIGlmIChpdGVtLmhhc0NyZWF0ZWRFdmVudCAmJiAhaXRlbS5kaXNwb3NlZCkge1xuICAgICAgY29udGludWU7IC8vIGFscmVhZHkgY29tbWl0dGVkIGFuZCBzdGlsbCBsaXZlIOKAlCBub3RoaW5nIHRvIGRvXG4gICAgfVxuICAgIGNvbnN0IGdyb3VwID0gaG9va0l0ZW1zQnlUb2tlbi5nZXQoaXRlbS50b2tlbik7XG4gICAgaWYgKGdyb3VwKSB7XG4gICAgICBncm91cC5wdXNoKGl0ZW0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBob29rSXRlbXNCeVRva2VuLnNldChpdGVtLnRva2VuLCBbaXRlbV0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlc29sdmUgZW5jcnlwdGlvbiBrZXkgZm9yIHRoaXMgcnVuXG4gIGNvbnN0IHJhd0tleSA9IGF3YWl0IHdvcmxkLmdldEVuY3J5cHRpb25LZXlGb3JSdW4/LihydW4pO1xuICBjb25zdCBlbmNyeXB0aW9uS2V5ID0gcmF3S2V5ID8gYXdhaXQgaW1wb3J0S2V5KHJhd0tleSkgOiB1bmRlZmluZWQ7XG5cbiAgLy8gR2F0ZSBwYXlsb2FkIGNvbXByZXNzaW9uIG9uIHRoZSBydW4ncyBzcGVjVmVyc2lvbi5cbiAgY29uc3QgY29tcHJlc3Npb24gPVxuICAgIChydW4uc3BlY1ZlcnNpb24gPz8gMCkgPj0gU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NPTVBSRVNTSU9OO1xuXG4gIGFzeW5jIGZ1bmN0aW9uIGRpc3Bvc2VIb29rKFxuICAgIHF1ZXVlSXRlbTogSG9va0ludm9jYXRpb25RdWV1ZUl0ZW1cbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaG9va0Rpc3Bvc2VkRXZlbnQ6IENyZWF0ZUV2ZW50UmVxdWVzdCA9IHtcbiAgICAgIGV2ZW50VHlwZTogJ2hvb2tfZGlzcG9zZWQnIGFzIGNvbnN0LFxuICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICBldmVudERhdGE6IHtcbiAgICAgICAgdG9rZW46IHF1ZXVlSXRlbS50b2tlbixcbiAgICAgIH0sXG4gICAgfTtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY3JlYXRlR3VhcmRlZChob29rRGlzcG9zZWRFdmVudCwgeyByZXF1ZXN0SWQgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgIC8vIEhvb2sgd2FzIGFscmVhZHkgZGlzcG9zZWQgYnkgYSBjb25jdXJyZW50IGludm9jYXRpb24g4oCUIHNhZmUgdG8gc2tpcFxuICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oXG4gICAgICAgICAgJ0hvb2sgYWxyZWFkeSBkaXNwb3NlZCwgc2tpcHBpbmcgZHVwbGljYXRlIGRpc3Bvc2FsJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChSdW5FeHBpcmVkRXJyb3IuaXMoZXJyKSkge1xuICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oXG4gICAgICAgICAgJ1dvcmtmbG93IHJ1biBhbHJlYWR5IGNvbXBsZXRlZCwgc2tpcHBpbmcgaG9vayBkaXNwb3NhbCcsXG4gICAgICAgICAge1xuICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoSG9va05vdEZvdW5kRXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAvLyBIb29rIG1heSBoYXZlIGFscmVhZHkgYmVlbiBkaXNwb3NlZCBvciBuZXZlciBjcmVhdGVkXG4gICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbygnSG9vayBub3QgZm91bmQgZm9yIGRpc3Bvc2FsLCBjb250aW51aW5nJywge1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBQcm9jZXNzIGhvb2tzIGZpcnN0IHRvIHByZXZlbnQgcmFjZSBjb25kaXRpb25zIHdpdGggd2ViaG9vayByZWNlaXZlcnMuXG4gIC8vIFRyYWNrIGFueSBob29rIGNvbmZsaWN0cyB0aGF0IG9jY3VyIOKAlCB0aGVzZSBhcmUgcmV0dXJuZWQgdG8gdGhlIGNhbGxlclxuICAvLyBzbyB0aGUgVjIgaGFuZGxlciBjYW4gcmUtaW52b2tlIGltbWVkaWF0ZWx5LlxuICBsZXQgaGFzSG9va0NvbmZsaWN0ID0gZmFsc2U7XG4gIGxldCBoYXNBd2FpdGVkSG9va0NyZWF0aW9uID0gZmFsc2U7XG4gIGxldCBob29rQ3JlYXRpb25NcyA9IDA7XG5cbiAgaWYgKGhvb2tJdGVtc0J5VG9rZW4uc2l6ZSA+IDApIHtcbiAgICBjb25zdCBob29rUGhhc2VTdGFydCA9IERhdGUubm93KCk7XG4gICAgYXdhaXQgZW5zdXJlUnVuUmVhZHkoKTtcbiAgICBhd2FpdCBzZXR0bGVQaGFzZShcbiAgICAgIFsuLi5ob29rSXRlbXNCeVRva2VuLnZhbHVlcygpXS5tYXAoYXN5bmMgKGl0ZW1zKSA9PiB7XG4gICAgICAgIGZvciAoY29uc3QgcXVldWVJdGVtIG9mIGl0ZW1zKSB7XG4gICAgICAgICAgbGV0IGNyZWF0aW9uQ29uZmxpY3RlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgaWYgKCFxdWV1ZUl0ZW0uaGFzQ3JlYXRlZEV2ZW50KSB7XG4gICAgICAgICAgICBjb25zdCBob29rTWV0YWRhdGE6IFNlcmlhbGl6ZWREYXRhIHwgdW5kZWZpbmVkID1cbiAgICAgICAgICAgICAgdHlwZW9mIHF1ZXVlSXRlbS5tZXRhZGF0YSA9PT0gJ3VuZGVmaW5lZCdcbiAgICAgICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgICAgIDogKChhd2FpdCBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICAgICAgICAgICAgICAgICAgICBxdWV1ZUl0ZW0ubWV0YWRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICAgICAgICAgICAgICBzdXNwZW5zaW9uLmdsb2JhbFRoaXMsXG4gICAgICAgICAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBjb21wcmVzc2lvblxuICAgICAgICAgICAgICAgICAgKSkgYXMgU2VyaWFsaXplZERhdGEpO1xuICAgICAgICAgICAgY29uc3QgaG9va0V2ZW50OiBDcmVhdGVFdmVudFJlcXVlc3QgPSB7XG4gICAgICAgICAgICAgIGV2ZW50VHlwZTogJ2hvb2tfY3JlYXRlZCcgYXMgY29uc3QsXG4gICAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgICAgICAgIHRva2VuOiBxdWV1ZUl0ZW0udG9rZW4sXG4gICAgICAgICAgICAgICAgdG9rZW5SZXRlbnRpb25VbnRpbDogcXVldWVJdGVtLnRva2VuUmV0ZW50aW9uVW50aWwsXG4gICAgICAgICAgICAgICAgbWV0YWRhdGE6IGhvb2tNZXRhZGF0YSxcbiAgICAgICAgICAgICAgICBpc1dlYmhvb2s6IHF1ZXVlSXRlbS5pc1dlYmhvb2sgPz8gZmFsc2UsXG4gICAgICAgICAgICAgICAgLi4uKHF1ZXVlSXRlbS5pc1N5c3RlbSAmJiB7IGlzU3lzdGVtOiB0cnVlIH0pLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNyZWF0ZUhvb2tFdmVudCh7XG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBob29rRXZlbnQsXG4gICAgICAgICAgICAgIHF1ZXVlSXRlbSxcbiAgICAgICAgICAgICAgcmVxdWVzdElkLFxuICAgICAgICAgICAgICBjcmVhdGVFdmVudDogY3JlYXRlR3VhcmRlZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaGFzSG9va0NvbmZsaWN0IHx8PSByZXN1bHQuaGFzSG9va0NvbmZsaWN0O1xuICAgICAgICAgICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbiB8fD0gcmVzdWx0Lmhhc0F3YWl0ZWRIb29rQ3JlYXRpb247XG4gICAgICAgICAgICBjcmVhdGlvbkNvbmZsaWN0ZWQgPSByZXN1bHQuaGFzSG9va0NvbmZsaWN0O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIERpc3Bvc2UgYWZ0ZXIgY3JlYXRpb24gZm9yIGhvb2tzIGJvcm4gYW5kIGRpc3Bvc2VkIHdpdGhpbiB0aGlzXG4gICAgICAgICAgLy8gYmF0Y2guIEEgaG9vayB3aG9zZSBjcmVhdGlvbiBjb25mbGljdGVkIHdhcyBuZXZlciBjcmVhdGVkLCBzb1xuICAgICAgICAgIC8vIHRoZXJlIGlzIG5vdGhpbmcgdG8gZGlzcG9zZS5cbiAgICAgICAgICBpZiAocXVldWVJdGVtLmRpc3Bvc2VkICYmICFjcmVhdGlvbkNvbmZsaWN0ZWQpIHtcbiAgICAgICAgICAgIGF3YWl0IGRpc3Bvc2VIb29rKHF1ZXVlSXRlbSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gICAgaG9va0NyZWF0aW9uTXMgPSBEYXRlLm5vdygpIC0gaG9va1BoYXNlU3RhcnQ7XG4gIH1cblxuICAvLyBQcm9jZXNzIGFib3J0IHJlcXVlc3RzIOKAlCByZXN1bWUgdGhlIGhvb2sgd2l0aCBhYm9ydCBwYXlsb2FkIGFuZCB3cml0ZSBzdHJlYW0gcGFja2V0XG4gIGNvbnN0IGhvb2tzTmVlZGluZ0Fib3J0ID0gYWxsSG9va0l0ZW1zLmZpbHRlcihcbiAgICAoaXRlbSkgPT4gaXRlbS5hYm9ydFJlcXVlc3RlZCAmJiAhaXRlbS5kaXNwb3NlZFxuICApO1xuXG4gIGlmIChob29rc05lZWRpbmdBYm9ydC5sZW5ndGggPiAwKSB7XG4gICAgYXdhaXQgZW5zdXJlUnVuUmVhZHkoKTtcbiAgICBhd2FpdCBzZXR0bGVQaGFzZShcbiAgICAgIGhvb2tzTmVlZGluZ0Fib3J0Lm1hcChhc3luYyAocXVldWVJdGVtKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gRGVoeWRyYXRlIHRoZSBhYm9ydCBwYXlsb2FkIGZvciBzdG9yYWdlXG4gICAgICAgICAgY29uc3QgYWJvcnRQYXlsb2FkID0gYXdhaXQgZGVoeWRyYXRlU3RlcEFyZ3VtZW50cyhcbiAgICAgICAgICAgIHsgYWJvcnRlZDogdHJ1ZSwgcmVhc29uOiBxdWV1ZUl0ZW0uYWJvcnRSZWFzb24gfSxcbiAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgZW5jcnlwdGlvbktleSxcbiAgICAgICAgICAgIHN1c3BlbnNpb24uZ2xvYmFsVGhpcyxcbiAgICAgICAgICAgIGZhbHNlLFxuICAgICAgICAgICAgY29tcHJlc3Npb25cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgLy8gQ3JlYXRlIGhvb2tfcmVjZWl2ZWQgZXZlbnQgd2l0aCBhYm9ydCBwYXlsb2FkXG4gICAgICAgICAgYXdhaXQgY3JlYXRlR3VhcmRlZCh7XG4gICAgICAgICAgICBldmVudFR5cGU6ICdob29rX3JlY2VpdmVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgIHRva2VuOiBxdWV1ZUl0ZW0udG9rZW4sXG4gICAgICAgICAgICAgIHBheWxvYWQ6IGFib3J0UGF5bG9hZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBXcml0ZSBzdHJlYW0gY2FuY2VsbGF0aW9uIHBhY2tldCBmb3IgcmVhbC10aW1lIHN0ZXAgcHJvcGFnYXRpb24uXG4gICAgICAgICAgLy8gUmV1c2UgdGhlIHNhbWUgZGVoeWRyYXRlZCBwYXlsb2FkIGFzIHRoZSBob29rIGV2ZW50IHNvIHRoZSByZWFzb25cbiAgICAgICAgICAvLyByb3VuZC10cmlwcyB0aHJvdWdoIGBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzYCAvIGBoeWRyYXRlU3RlcEFyZ3VtZW50c2BcbiAgICAgICAgICAvLyAoaGFuZGxlcyBET01FeGNlcHRpb24sIGN1c3RvbSBlcnJvcnMsIGVuY3J5cHRpb24sIGV0Yy4pIGluc3RlYWQgb2ZcbiAgICAgICAgICAvLyBiYXJlIEpTT04uc3RyaW5naWZ5IHdoaWNoIGxvc2VzIHR5cGUgaW5mb3JtYXRpb24gYW5kIGRyb3BzIHVuZGVmaW5lZC5cbiAgICAgICAgICAvLyBzdHJlYW1OYW1lIGlzIHNldCBvbiB0aGUgcXVldWUgaXRlbSBhdCBjb250cm9sbGVyIGNvbnN0cnVjdGlvbiB0aW1lXG4gICAgICAgICAgLy8gKHNlZSB3b3JrZmxvdy9hYm9ydC1jb250cm9sbGVyLnRzKS5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc3RyZWFtTmFtZSA9IGdldEFib3J0U3RyZWFtSWRGcm9tVG9rZW4ocXVldWVJdGVtLnRva2VuKTtcbiAgICAgICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMud3JpdGUoXG4gICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICBzdHJlYW1OYW1lLFxuICAgICAgICAgICAgICBhYm9ydFBheWxvYWQgYXMgVWludDhBcnJheVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGF3YWl0IHdvcmxkLnN0cmVhbXMuY2xvc2UocnVuSWQsIHN0cmVhbU5hbWUpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLy8gQmVzdC1lZmZvcnQgc3RyZWFtIHdyaXRlIOKAlCBob29rIGV2ZW50IHByb3ZpZGVzIHRoZSBkdXJhYmxlIGZhbGxiYWNrXG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICAnRmFpbGVkIHRvIHdyaXRlIGFib3J0IHN0cmVhbSBwYWNrZXQsIGhvb2sgZXZlbnQgd2lsbCBwcm92aWRlIGZhbGxiYWNrJyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSB8fCBSdW5FeHBpcmVkRXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAnV29ya2Zsb3cgcnVuIGFscmVhZHkgY29tcGxldGVkLCBza2lwcGluZyBhYm9ydCcsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLy8gQ3JlYXRlIHN0ZXAgZXZlbnRzIGZvciBzdGVwcyB0aGF0IGRvbid0IGhhdmUgdGhlbSB5ZXQuXG4gIC8vIFVubGlrZSBWMSwgd2UgZG8gTk9UIHF1ZXVlIHN0ZXAgbWVzc2FnZXMgZnJvbSBoZXJlIOKAlCB0aGUgY2FsbGVyXG4gIC8vIGRlY2lkZXMgd2hpY2ggc3RlcHMgdG8gZXhlY3V0ZSBpbmxpbmUgdnMuIHF1ZXVlIHRvIGJhY2tncm91bmQuXG4gIC8vIFdhaXQgZXZlbnRzIGFyZSBhbHNvIGNyZWF0ZWQgaW4gcGFyYWxsZWwgYmVsb3cuXG4gIGNvbnN0IHN0ZXBzTmVlZGluZ0NyZWF0aW9uID0gbmV3IFNldChcbiAgICBzdGVwSXRlbXNcbiAgICAgIC5maWx0ZXIoKHF1ZXVlSXRlbSkgPT4gIXF1ZXVlSXRlbS5oYXNDcmVhdGVkRXZlbnQpXG4gICAgICAubWFwKChxdWV1ZUl0ZW0pID0+IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkKVxuICApO1xuXG4gIC8vIENvcnJlbGF0aW9uIElEcyBmb3Igd2hpY2ggVEhJUyBzdXNwZW5zaW9uIGNhbGwgYWN0dWFsbHkgd3JvdGUgdGhlXG4gIC8vIHN0ZXBfY3JlYXRlZCBldmVudC4gUG9wdWxhdGVkIGJ5IHRoZSBvcHMgYmVsb3cgYWZ0ZXIgYSBzdWNjZXNzZnVsXG4gIC8vIGV2ZW50cy5jcmVhdGUg4oCUIHVzZWQgYnkgdGhlIGNhbGxlciB0byBjbGFpbSBvd25lcnNoaXAgYW5kIGF2b2lkXG4gIC8vIHJhY2luZyB3aXRoIGNvbmN1cnJlbnQgaGFuZGxlcnMgb24gc3RlcCBleGVjdXRpb24uXG4gIGNvbnN0IGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAvLyBTZXJpYWxpemF0aW9uIGFsd2F5cyBydW5zIHRocm91Z2ggdGhlIG9uZSBvcmRpbmFyeSBwYXRoIGJlbG93LCBzbyB0aGVcbiAgLy8gZHVyYWJsZSBieXRlcyBjYW5ub3QgZGVwZW5kIG9uIHJldGVudGlvbi4gV2hhdCByZXRlbnRpb24gbmVlZHMgdG8ga25vdyBpc1xuICAvLyB3aGV0aGVyIHRoYXQgc2VyaWFsaXphdGlvbiAqZXhlY3V0ZWQqIHdvcmtmbG93IGNvZGUgKGdldHRlcnMsIHByb3h5XG4gIC8vIHRyYXBzLCBjdXN0b20gc2VyaWFsaXplcnMpIOKAlCBzaWRlIGVmZmVjdHMgYSBjb2xkIHJlcGxheSB3b3VsZCBub3RcbiAgLy8gcmVwZWF0LCBzaW5jZSBhIHJlcGxheSBza2lwcyBkZWh5ZHJhdGlvbiBmb3IgYWxyZWFkeS1yZWNvcmRlZCBzdGVwcy5cbiAgLy8gVGhlIGhhcmRlbmVkIHNlcmlhbGl6ZXIgcmVjb3JkcyBleGFjdGx5IHRoYXQgaW50byB0aGlzIHNpbmsgKHNlZVxuICAvLyAuLi9zZXJpYWxpemF0aW9uL2hhcmRlbmVkLnRzKTsgd2hlbiBhbnkgaW5wdXQgaW4gdGhlIGJhdGNoIHJlY29yZHMgYW5cbiAgLy8gZXhlY3V0aW9uLCB0aGUgY2FsbGVyIGRlbW90ZXMgdGhlIHNlc3Npb24gc28gdGhlIHNpZGUgZWZmZWN0cyBsYW5kIGluIGFcbiAgLy8gVk0gdGhhdCBpcyBhYm91dCB0byBiZSBkaXNjYXJkZWQsIGV4YWN0bHkgbGlrZSB0aGUgcHJlLXJldGVudGlvblxuICAvLyBydW50aW1lLlxuICBjb25zdCBndWVzdENvZGVTdGF0czogR3Vlc3RDb2RlU3RhdHMgPSB7IGV4ZWN1dGlvbnM6IFtdIH07XG5cbiAgLy8gTGF6eSBpbmxpbmUgc3RhcnQ6IGRlZmVyIHRoZSBzdGVwX2NyZWF0ZWQgd3JpdGUgZm9yIHVwIHRvXG4gIC8vIGBnZXRNYXhJbmxpbmVTdGVwcygpYCBzdGVwcyB0aGUgY2FsbGVyIHdpbGwgcnVuIGlubGluZSAoaW4gcGFyYWxsZWwpLiBFYWNoXG4gIC8vIHN0ZXAgaXMgY3JlYXRlZCBvbiB0aGUgZmx5IGJ5IHRoZSBsYXp5IGBzdGVwX3N0YXJ0ZWRgIGV4ZWN1dGVTdGVwIHNlbmRzXG4gIC8vIChzYXZpbmcgYSByb3VuZC10cmlwIHBlciBzdGVwKS4gV2UgbmV2ZXIgZGVmZXIgd2hlbiBhIGBob29rLmdldENvbmZsaWN0KClgXG4gIC8vIGF3YWl0ZXIgaXMgcHJlc2VudCwgYmVjYXVzZSBpbiB0aGF0IGNhc2UgdGhlIGNhbGxlciBleGVjdXRlcyBub3RoaW5nIGlubGluZVxuICAvLyAoaXQgcmUtaW52b2tlcyBpbW1lZGlhdGVseSB0byByZXNvbHZlIHRoZSBhd2FpdGVyKSwgc28gZGVmZXJyaW5nIHdvdWxkXG4gIC8vIGxlYXZlIHRoZSBzdGVwcyB1bmNyZWF0ZWQgYW5kIHVucXVldWVkLiBXZSBwaWNrIHRoZSBmaXJzdCBOIHVuY3JlYXRlZCBzdGVwc1xuICAvLyDigJQgbWF0Y2hpbmcgdGhlIGNhbGxlcidzIGlubGluZS1jYW5kaWRhdGUgc2VsZWN0aW9uIOKAlCBhbmQgZGVoeWRyYXRlIHRoZWlyXG4gIC8vIGlucHV0IGhlcmUgc28gZXhlY3V0ZVN0ZXAgY2FuIHNoaXAgaXQgYXMgdGhlIHN0ZXBfc3RhcnRlZCBwYXlsb2FkLlxuICBjb25zdCBsYXp5SW5saW5lQ29ycmVsYXRpb25JZHMgPSBuZXcgU2V0PHN0cmluZz4oXG4gICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbiA9PT0gZmFsc2VcbiAgICAgID8gc3RlcEl0ZW1zXG4gICAgICAgICAgLmZpbHRlcigoaXRlbSkgPT4gc3RlcHNOZWVkaW5nQ3JlYXRpb24uaGFzKGl0ZW0uY29ycmVsYXRpb25JZCkpXG4gICAgICAgICAgLnNsaWNlKDAsIGdldE1heElubGluZVN0ZXBzKCkpXG4gICAgICAgICAgLm1hcCgoaXRlbSkgPT4gaXRlbS5jb3JyZWxhdGlvbklkKVxuICAgICAgOiBbXVxuICApO1xuICAvLyBDb2xsZWN0ZWQgYnkgY29ycmVsYXRpb25JZCBiZWNhdXNlIHRoZSBwZXItc3RlcCBvcHMgYmVsb3cgcnVuIGNvbmN1cnJlbnRseVxuICAvLyBhbmQgc2V0dGxlIG91dCBvZiBvcmRlci4gV2UgcmVidWlsZCB0aGUgYXJyYXkgaW4gZGV0ZXJtaW5pc3RpY1xuICAvLyBgbGF6eUlubGluZUNvcnJlbGF0aW9uSWRzYCBvcmRlciAodGhlIG9yZGVyZWQgc2xpY2UgYWJvdmUpIGFmdGVyIHRoZSBvcHNcbiAgLy8gc2V0dGxlLCBzbyB0aGUgaW5saW5lIGJhdGNoIG9yZGVyIGlzIHN0YWJsZSByZWdhcmRsZXNzIG9mIGRlaHlkcmF0aW9uIHRpbWluZy5cbiAgY29uc3QgbGF6eUlubGluZUJ5Q29ycmVsYXRpb25JZCA9IG5ldyBNYXA8XG4gICAgc3RyaW5nLFxuICAgIFN1c3BlbnNpb25IYW5kbGVyUmVzdWx0WydsYXp5SW5saW5lU3RlcHMnXVtudW1iZXJdXG4gID4oKTtcblxuICBjb25zdCBvcHM6IFByb21pc2U8dm9pZD5bXSA9IFtdO1xuXG4gIC8vIFN0ZXBzOiBjcmVhdGUgc3RlcF9jcmVhdGVkIGV2ZW50cyAobm8gcXVldWluZyDigJQgVjIgcmV0dXJucyBwZW5kaW5nIHN0ZXBzIHRvIGNhbGxlcilcbiAgZm9yIChjb25zdCBxdWV1ZUl0ZW0gb2Ygc3RlcEl0ZW1zKSB7XG4gICAgaWYgKHN0ZXBzTmVlZGluZ0NyZWF0aW9uLmhhcyhxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCkpIHtcbiAgICAgIG9wcy5wdXNoKFxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIC8vIFBlci1zdGVwIHNpbmssIG1lcmdlZCBiZWxvdzogdGhlIGRlaHlkcmF0ZSB3cmFwcGVyIGVtaXRzIHNwYW5cbiAgICAgICAgICAvLyBhdHRyaWJ1dGVzIGZyb20gdGhlIHNpbmsgaXQgaXMgaGFuZGVkLCBzbyBzaGFyaW5nIG9uZSBhY3Jvc3NcbiAgICAgICAgICAvLyBzdGVwcyB3b3VsZCByZS1lbWl0IChhbmQgbWlzYXR0cmlidXRlKSBlYXJsaWVyIHN0ZXBzJyBlbnRyaWVzLlxuICAgICAgICAgIGNvbnN0IHN0ZXBHdWVzdENvZGU6IEd1ZXN0Q29kZVN0YXRzID0geyBleGVjdXRpb25zOiBbXSB9O1xuICAgICAgICAgIGNvbnN0IGRlaHlkcmF0ZWRJbnB1dCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFyZ3M6IHF1ZXVlSXRlbS5hcmdzLFxuICAgICAgICAgICAgICBjbG9zdXJlVmFyczogcXVldWVJdGVtLmNsb3N1cmVWYXJzLFxuICAgICAgICAgICAgICB0aGlzVmFsOiBxdWV1ZUl0ZW0udGhpc1ZhbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBydW5JZCxcbiAgICAgICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgICAgICBzdXNwZW5zaW9uLmdsb2JhbFRoaXMsXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICAgIGNvbXByZXNzaW9uLFxuICAgICAgICAgICAgc3RlcEd1ZXN0Q29kZVxuICAgICAgICAgICk7XG4gICAgICAgICAgZ3Vlc3RDb2RlU3RhdHMuZXhlY3V0aW9ucy5wdXNoKC4uLnN0ZXBHdWVzdENvZGUuZXhlY3V0aW9ucyk7XG4gICAgICAgICAgLy8gRGVmZXJyZWQgKGxhenkpIGlubGluZSBzdGVwOiBza2lwIHRoZSBzdGVwX2NyZWF0ZWQgd3JpdGUg4oCUIHRoZVxuICAgICAgICAgIC8vIGNhbGxlcidzIGlubGluZSBleGVjdXRlU3RlcCB3aWxsIHNlbmQgYSBsYXp5IHN0ZXBfc3RhcnRlZCBjYXJyeWluZ1xuICAgICAgICAgIC8vIHRoaXMgaW5wdXQsIGFuZCB0aGUgd29ybGQgY3JlYXRlcyB0aGUgc3RlcCAoZW50aXR5ICsgc3ludGhldGljXG4gICAgICAgICAgLy8gc3RlcF9jcmVhdGVkIGV2ZW50KSBhdG9taWNhbGx5LiBXZSBkbyBOT1QgYWRkIGl0IHRvXG4gICAgICAgICAgLy8gY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkczsgb3duZXJzaGlwIGlzIGRlY2lkZWQgYnkgdGhhdCBsYXp5XG4gICAgICAgICAgLy8gc3RlcF9zdGFydGVkJ3MgYXRvbWljIGNyZWF0ZS1jbGFpbSBpbnN0ZWFkLlxuICAgICAgICAgIGlmIChsYXp5SW5saW5lQ29ycmVsYXRpb25JZHMuaGFzKHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkKSkge1xuICAgICAgICAgICAgbGF6eUlubGluZUJ5Q29ycmVsYXRpb25JZC5zZXQocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsIHtcbiAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICAgIGRlaHlkcmF0ZWRJbnB1dDogZGVoeWRyYXRlZElucHV0IGFzIFNlcmlhbGl6ZWREYXRhLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IHN0ZXBFdmVudDogQ3JlYXRlRXZlbnRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgZXZlbnRUeXBlOiAnc3RlcF9jcmVhdGVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICAgIHdvcmtmbG93TmFtZTogcnVuLndvcmtmbG93TmFtZSxcbiAgICAgICAgICAgICAgaW5wdXQ6IGRlaHlkcmF0ZWRJbnB1dCBhcyBTZXJpYWxpemVkRGF0YSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgZW5zdXJlUnVuUmVhZHkoKTtcbiAgICAgICAgICAgIGF3YWl0IGNyZWF0ZUd1YXJkZWQoc3RlcEV2ZW50LCB7IHJlcXVlc3RJZCB9KTtcbiAgICAgICAgICAgIGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHMuYWRkKHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKCdTdGVwIGFscmVhZHkgZXhpc3RzLCBjb250aW51aW5nJywge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pKClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gQ3JlYXRlIHdhaXQgZXZlbnRzIChzYW1lIGFzIFYxKVxuICBmb3IgKGNvbnN0IHF1ZXVlSXRlbSBvZiB3YWl0SXRlbXMpIHtcbiAgICBpZiAoIXF1ZXVlSXRlbS5oYXNDcmVhdGVkRXZlbnQpIHtcbiAgICAgIG9wcy5wdXNoKFxuICAgICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHdhaXRFdmVudDogQ3JlYXRlRXZlbnRSZXF1ZXN0ID0ge1xuICAgICAgICAgICAgZXZlbnRUeXBlOiAnd2FpdF9jcmVhdGVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgIHJlc3VtZUF0OiBxdWV1ZUl0ZW0ucmVzdW1lQXQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH07XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGVuc3VyZVJ1blJlYWR5KCk7XG4gICAgICAgICAgICBhd2FpdCBjcmVhdGVHdWFyZGVkKHdhaXRFdmVudCwgeyByZXF1ZXN0SWQgfSk7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbygnV2FpdCBhbHJlYWR5IGV4aXN0cywgY29udGludWluZycsIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9KSgpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgcXVldWVJdGVtIG9mIGF0dHJpYnV0ZUl0ZW1zKSB7XG4gICAgb3BzLnB1c2goXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IGVuc3VyZVJ1blJlYWR5KCk7XG4gICAgICAgICAgLy8gR3VhcmRlZCBsaWtlIGV2ZXJ5IG90aGVyIHN1c3BlbnNpb24gd3JpdGU6IGFuIGF0dHJfc2V0IGlzIGFcbiAgICAgICAgICAvLyByZXBsYXktZGVyaXZlZCBldmVudCB3aXRoIGEgY29ycmVsYXRpb24gaWQgZnJvbSB0aGlzIHJlcGxheSdzXG4gICAgICAgICAgLy8gc2VlZGVkIHNlcXVlbmNlLCBzbyBpdCBtdXN0IG5vdCBsYW5kIG9uIGEgbG9nIHRoZSByZXBsYXkgbmV2ZXJcbiAgICAgICAgICAvLyBzYXcuIFJlamVjdGluZyBpdCBpcyBjaGVhcCDigJQgYSBydW4gd2l0aCBhdHRyaWJ1dGUgZXZlbnRzIGFscmVhZHlcbiAgICAgICAgICAvLyBmb3JjZXMgYW4gaW4tcHJvY2VzcyByZXBsYXksIHNvIHRoZSByZXN0YXJ0IGNvc3RzIHRoZSByZXBsYXkgaXRcbiAgICAgICAgICAvLyB3YXMgZ29pbmcgdG8gZG8gYW55d2F5LlxuICAgICAgICAgIGF3YWl0IGNyZWF0ZUd1YXJkZWQoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGV2ZW50VHlwZTogJ2F0dHJfc2V0JyxcbiAgICAgICAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgICAgY2hhbmdlczogcXVldWVJdGVtLmNoYW5nZXMsXG4gICAgICAgICAgICAgICAgd3JpdGVyOiB7IHR5cGU6ICd3b3JrZmxvdycgfSxcbiAgICAgICAgICAgICAgICAuLi4ocXVldWVJdGVtLmFsbG93UmVzZXJ2ZWRBdHRyaWJ1dGVzXG4gICAgICAgICAgICAgICAgICA/IHsgYWxsb3dSZXNlcnZlZEF0dHJpYnV0ZXM6IHRydWUgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeyByZXF1ZXN0SWQgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgJ1dvcmtmbG93IGF0dHJpYnV0ZSBldmVudCBhbHJlYWR5IGV4aXN0cywgY29udGludWluZycsXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzV29ybGRWYWxpZGF0aW9uRmFpbHVyZShlcnIpKSB7XG4gICAgICAgICAgICAvLyBEZXRlcm1pbmlzdGljIHZhbGlkYXRpb24gcmVqZWN0aW9uIGZyb20gdGhlIFdvcmxkIOKAlCBlLmcuIHRoZVxuICAgICAgICAgICAgLy8gY3VtdWxhdGl2ZSBwZXItcnVuIGF0dHJpYnV0ZSBjYXAsIHdoaWNoIG9ubHkgdGhlIFdvcmxkIGNhblxuICAgICAgICAgICAgLy8gY2hlY2sgYWdhaW5zdCB0aGUgcnVuJ3MgZXhpc3RpbmcgYXR0cmlidXRlcy4gUmVkZWxpdmVyaW5nIHRoZVxuICAgICAgICAgICAgLy8gb3JjaGVzdHJhdG9yIG1lc3NhZ2UgcmVwbGF5cyB0aGUgd29ya2Zsb3cgaW50byB0aGUgZXhhY3Qgc2FtZVxuICAgICAgICAgICAgLy8gd3JpdGUgYW5kIHRoZSBleGFjdCBzYW1lIHJlamVjdGlvbiwgc28gcmV0cnlpbmcgY2FuIG5ldmVyXG4gICAgICAgICAgICAvLyBzdWNjZWVkLiBTdXJmYWNlIGl0IGFzIGEgRmF0YWxFcnJvciBzbyB0aGUgY2FsbGVyIGZhaWxzIHRoZVxuICAgICAgICAgICAgLy8gcnVuIHdpdGggYSBjbGVhciBlcnJvciBpbnN0ZWFkIG9mIHdlZGdpbmcgaXQgaW4gcmVkZWxpdmVyeS5cbiAgICAgICAgICAgIGNvbnN0IGZhdGFsID0gbmV3IEZhdGFsRXJyb3IoXG4gICAgICAgICAgICAgIGBzZXRBdHRyaWJ1dGVzIGZhaWxlZCBXb3JsZCB2YWxpZGF0aW9uOiAke1xuICAgICAgICAgICAgICAgIGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKVxuICAgICAgICAgICAgICB9YFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGZhdGFsLmNhdXNlID0gZXJyO1xuICAgICAgICAgICAgdGhyb3cgZmF0YWw7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pKClcbiAgICApO1xuICB9XG5cbiAgLy8gQXdhaXQgdGhlIHN0ZXBfY3JlYXRlZCAvIHdhaXRfY3JlYXRlZCBldmVudCBjcmVhdGVzIGJlZm9yZSByZXR1cm5pbmcuXG4gIC8vIFRoZSBjYWxsZXIgKHdvcmtmbG93RW50cnlwb2ludCkgb25seSBlbnF1ZXVlcyB0aGUgc3RlcC1kaXNwYXRjaCBxdWV1ZVxuICAvLyBtZXNzYWdlcyBBRlRFUiBoYW5kbGVTdXNwZW5zaW9uIHJlc29sdmVzLCBhbmQgdGhlIHF1ZXVlIGhhbmRsZXIgYWNrc1xuICAvLyB0aGUgb3JjaGVzdHJhdG9yIG1lc3NhZ2Ugb25seSBhZnRlciB0aGUgY2FsbGVyIHJlc29sdmVzLiBTbyB0aGUgc3RlcF9jcmVhdGVkXG4gIC8vIGV2ZW50cyBtdXN0IGJlIGR1cmFibGUgaGVyZSwgYW5kIHRoZSBkaXNwYXRjaCBzZW5kcyBtdXN0IGNvbXBsZXRlIGluIHRoZSBjYWxsZXIsXG4gIC8vIGFsbCBiZWZvcmUgYWNrLiBJZiB0aGUgcHJvY2VzcyBjcmFzaGVzIGJlZm9yZSB0aGlzIHJlc29sdmVzLCB0aGUgb3JjaGVzdHJhdG9yXG4gIC8vIG1lc3NhZ2UgaXMgbm90IGFja2VkIGFuZCBWUVMgcmVkZWxpdmVycywgcmUtY3JlYXRlcyB0aGUgKGlkZW1wb3RlbnQpXG4gIC8vIHN0ZXBfY3JlYXRlZCBhbmQgcmUtZGlzcGF0Y2hlcywgYW5kIHJlY292ZXJzIHRoZSBydW4gaW5zdGVhZCBvZiBvcnBoYW5pbmcgaXQuXG4gIGF3YWl0IHNldHRsZVBoYXNlKG9wcyk7XG5cbiAgLy8gVGhlIHN0ZXAtaW5wdXQgZGVoeWRyYXRpb25zIGFib3ZlIGhhdmUgc2V0dGxlZCwgc28gdGhlIHNpbmsgaXMgZmluYWwuXG4gIGNvbnN0IHJldGFpbmVkU3RlcElucHV0c1NhZmUgPSBndWVzdENvZGVTdGF0cy5leGVjdXRpb25zLmxlbmd0aCA9PT0gMDtcbiAgaWYgKCFyZXRhaW5lZFN0ZXBJbnB1dHNTYWZlKSB7XG4gICAgcnVudGltZUxvZ2dlci5kZWJ1ZyhcbiAgICAgICdTZXJpYWxpemluZyBzdGVwIGlucHV0cyBleGVjdXRlZCB3b3JrZmxvdyBjb2RlOyBmYWxsaW5nIGJhY2sgdG8gcmVwbGF5IGluc3RlYWQgb2YgcmV0YWluaW5nIHRoZSBWTScsXG4gICAgICB7XG4gICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICBleGVjdXRpb25zOiBndWVzdENvZGVTdGF0cy5leGVjdXRpb25zXG4gICAgICAgICAgLnNsaWNlKDAsIDUpXG4gICAgICAgICAgLm1hcCgoZSkgPT4gKGUuZGV0YWlsID8gYCR7ZS5raW5kfSgke2UuZGV0YWlsfSlgIDogZS5raW5kKSksXG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8vIFJlYnVpbGQgdGhlIGlubGluZSBiYXRjaCBpbiBkZXRlcm1pbmlzdGljIG9yZGVyLiBgbGF6eUlubGluZUNvcnJlbGF0aW9uSWRzYFxuICAvLyBpcyBhIFNldCBzZWVkZWQgZnJvbSB0aGUgb3JkZXJlZCBmaXJzdC1OIHNsaWNlLCBzbyBpdGVyYXRpbmcgaXQgcHJlc2VydmVzXG4gIC8vIHN0ZXBJdGVtcyBvcmRlcjsgZXZlcnkgaWQgaW4gaXQgd2FzIHNldCBieSB0aGUgbGF6eSBicmFuY2ggYWJvdmUuXG4gIGNvbnN0IGxhenlJbmxpbmVTdGVwczogU3VzcGVuc2lvbkhhbmRsZXJSZXN1bHRbJ2xhenlJbmxpbmVTdGVwcyddID0gW107XG4gIGZvciAoY29uc3QgY29ycmVsYXRpb25JZCBvZiBsYXp5SW5saW5lQ29ycmVsYXRpb25JZHMpIHtcbiAgICBjb25zdCBsYXp5U3RlcCA9IGxhenlJbmxpbmVCeUNvcnJlbGF0aW9uSWQuZ2V0KGNvcnJlbGF0aW9uSWQpO1xuICAgIGlmIChsYXp5U3RlcCkgbGF6eUlubGluZVN0ZXBzLnB1c2gobGF6eVN0ZXApO1xuICB9XG5cbiAgLy8gRmluZCB0aGUgc29vbmVzdCBwZW5kaW5nIHdhaXQgKG1pbmltdW0gdGltZW91dClcbiAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgbGV0IHNvb25lc3RXYWl0OiB7IHNlY29uZHM6IG51bWJlcjsgY29ycmVsYXRpb25JZDogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgcXVldWVJdGVtIG9mIHdhaXRJdGVtcykge1xuICAgIGNvbnN0IHJlc3VtZUF0TXMgPSBxdWV1ZUl0ZW0ucmVzdW1lQXQuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGRlbGF5TXMgPSBNYXRoLm1heCgxMDAwLCByZXN1bWVBdE1zIC0gbm93KTtcbiAgICBjb25zdCB0aW1lb3V0U2Vjb25kcyA9IE1hdGguY2VpbChkZWxheU1zIC8gMTAwMCk7XG4gICAgaWYgKCFzb29uZXN0V2FpdCB8fCB0aW1lb3V0U2Vjb25kcyA8IHNvb25lc3RXYWl0LnNlY29uZHMpIHtcbiAgICAgIHNvb25lc3RXYWl0ID0ge1xuICAgICAgICBzZWNvbmRzOiB0aW1lb3V0U2Vjb25kcyxcbiAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIHNwYW4/LnNldEF0dHJpYnV0ZXMoe1xuICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd1J1blN0YXR1cygnd29ya2Zsb3dfc3VzcGVuZGVkJyksXG4gICAgLi4uQXR0cmlidXRlLldvcmtmbG93U3RlcHNDcmVhdGVkKHN0ZXBJdGVtcy5sZW5ndGgpLFxuICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd0hvb2tzQ3JlYXRlZChob29rc05lZWRpbmdDcmVhdGlvbi5sZW5ndGgpLFxuICAgIC4uLkF0dHJpYnV0ZS5Xb3JrZmxvd1dhaXRzQ3JlYXRlZCh3YWl0SXRlbXMubGVuZ3RoKSxcbiAgfSk7XG5cbiAgcmV0dXJuIHtcbiAgICBwZW5kaW5nU3RlcHM6IHN0ZXBJdGVtcyxcbiAgICBjcmVhdGVkU3RlcENvcnJlbGF0aW9uSWRzLFxuICAgIGxhenlJbmxpbmVTdGVwcyxcbiAgICAvLyBPbiBob29rIGNvbmZsaWN0IHRoZSBjYWxsZXIgcmUtaW52b2tlcyBpbW1lZGlhdGVseSBhbmQgbmV2ZXIgcmVhZHNcbiAgICAvLyB0aGUgd2FpdCB0aW1lb3V0LCBzbyBkb24ndCByZXBvcnQgb25lLlxuICAgIHdhaXRUaW1lb3V0OiBoYXNIb29rQ29uZmxpY3QgPyB1bmRlZmluZWQgOiBzb29uZXN0V2FpdCxcbiAgICBoYXNIb29rQ29uZmxpY3QsXG4gICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbixcbiAgICBoYXNBdHRyaWJ1dGVFdmVudHM6IGF0dHJpYnV0ZUl0ZW1zLmxlbmd0aCA+IDAsXG4gICAgaGFzSG9va0V2ZW50czogaG9va3NOZWVkaW5nQ3JlYXRpb24ubGVuZ3RoID4gMCxcbiAgICBob29rQ3JlYXRpb25NcyxcbiAgICByZXRhaW5lZFN0ZXBJbnB1dHNTYWZlLFxuICAgIHJlcG9ydGVkRXZlbnRDb3VudDogcmVwb3J0ZWRFdmVudHMsXG4gIH07XG59XG5cbi8qKlxuICogV2hldGhlciBhbiBgZXZlbnRzLmNyZWF0ZWAgcmVqZWN0aW9uIGlzIGRldGVybWluaXN0aWMgV29ybGQgdmFsaWRhdGlvblxuICogcmF0aGVyIHRoYW4gYSB0cmFuc2llbnQvc3RvcmFnZSBlcnJvci4gTG9jYWwgV29ybGRzXG4gKiAod29ybGQtbG9jYWwsIHdvcmxkLXBvc3RncmVzKSB0aHJvdyBgQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yYCBkaXJlY3RseTtcbiAqIHJlbW90ZSBXb3JsZHMgc3VyZmFjZSB0aGUgZXF1aXZhbGVudCBzZXJ2ZXItc2lkZSByZWplY3Rpb24gYXMgYVxuICogYFdvcmtmbG93V29ybGRFcnJvcmAgd2l0aCBIVFRQIHN0YXR1cyA0MDAuIFRoZSBuYW1lIGNoZWNrIGNvdmVyc1xuICogYEF0dHJpYnV0ZVZhbGlkYXRpb25FcnJvcmAgaW5zdGFuY2VzIGZyb20gYSBkaWZmZXJlbnQgY29weSBvZlxuICogYEB3b3JrZmxvdy93b3JsZGAgdGhhbiB0aGUgb25lIHRoaXMgcGFja2FnZSByZXNvbHZlZC5cbiAqL1xuZnVuY3Rpb24gaXNXb3JsZFZhbGlkYXRpb25GYWlsdXJlKGVycjogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAoZXJyIGluc3RhbmNlb2YgQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmIGVyci5uYW1lID09PSAnQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBXb3JrZmxvd1dvcmxkRXJyb3IuaXMoZXJyKSAmJiBlcnIuc3RhdHVzID09PSA0MDA7XG59XG4iXX0=
|
|
1209
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VzcGVuc2lvbi1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvc3VzcGVuc2lvbi1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsVUFBVSxFQUNWLGlCQUFpQixFQUNqQix1QkFBdUIsRUFDdkIsZUFBZSxFQUNmLGtCQUFrQixHQUNuQixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLE9BQU8sRUFDTCx3QkFBd0IsRUFLeEIsb0JBQW9CLEVBQ3BCLDBDQUEwQyxFQUMxQyxpQ0FBaUMsRUFDakMsbUNBQW1DLEdBTXBDLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBUTdDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFN0MsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDN0QsT0FBTyxLQUFLLFNBQVMsTUFBTSxzQ0FBc0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdkQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUNMLGlCQUFpQixFQUNqQix5QkFBeUIsRUFDekIsOEJBQThCLEVBQzlCLHVCQUF1QixFQUN2Qiw4QkFBOEIsR0FDL0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQ0wsdUJBQXVCLEVBR3ZCLFlBQVksRUFDWixZQUFZLEVBQ1osa0JBQWtCLEVBQ2xCLDBCQUEwQixHQUMzQixNQUFNLGNBQWMsQ0FBQztBQUN0QixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQThOdkUsS0FBSyxVQUFVLGVBQWUsQ0FBQyxF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LEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEdBQUcsQ0FBQztBQUMxRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBTcGFuIH0gZnJvbSAnQG9wZW50ZWxlbWV0cnkvYXBpJztcbmltcG9ydCB7XG4gIEVudGl0eUNvbmZsaWN0RXJyb3IsXG4gIEZhdGFsRXJyb3IsXG4gIEhvb2tOb3RGb3VuZEVycm9yLFxuICBQcmVjb25kaXRpb25GYWlsZWRFcnJvcixcbiAgUnVuRXhwaXJlZEVycm9yLFxuICBXb3JrZmxvd1dvcmxkRXJyb3IsXG59IGZyb20gJ0B3b3JrZmxvdy9lcnJvcnMnO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yLFxuICB0eXBlIENyZWF0ZUV2ZW50UGFyYW1zLFxuICB0eXBlIENyZWF0ZUV2ZW50UmVxdWVzdCxcbiAgdHlwZSBFdmVudFJlc3VsdCxcbiAgdHlwZSBTZXJpYWxpemVkRGF0YSxcbiAgU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gIFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DQk9SX1FVRVVFX1RSQU5TUE9SVCxcbiAgU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NPTVBSRVNTSU9OLFxuICBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfU0xPVF9JREVOVElUWSxcbiAgdHlwZSBTdGFydGVkU3RlcCxcbiAgdHlwZSBUcmFjZUNhcnJpZXIsXG4gIHR5cGUgVmFsaWRRdWV1ZU5hbWUsXG4gIHR5cGUgV29ya2Zsb3dSdW4sXG4gIHR5cGUgV29ybGQsXG59IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBpc1JldHJ5YWJsZVdvcmxkRXJyb3IgfSBmcm9tICcuLi9jbGFzc2lmeS1lcnJvci5qcyc7XG5pbXBvcnQgeyBpbXBvcnRLZXkgfSBmcm9tICcuLi9lbmNyeXB0aW9uLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgQXR0cmlidXRlSW52b2NhdGlvblF1ZXVlSXRlbSxcbiAgSG9va0ludm9jYXRpb25RdWV1ZUl0ZW0sXG4gIFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtLFxuICBXYWl0SW52b2NhdGlvblF1ZXVlSXRlbSxcbiAgV29ya2Zsb3dTdXNwZW5zaW9uLFxufSBmcm9tICcuLi9nbG9iYWwuanMnO1xuaW1wb3J0IHsgcnVudGltZUxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlci5qcyc7XG5pbXBvcnQgdHlwZSB7IEd1ZXN0Q29kZVN0YXRzIH0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi9oYXJkZW5lZC5qcyc7XG5pbXBvcnQgeyBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzIH0gZnJvbSAnLi4vc2VyaWFsaXphdGlvbi5qcyc7XG5pbXBvcnQgKiBhcyBBdHRyaWJ1dGUgZnJvbSAnLi4vdGVsZW1ldHJ5L3NlbWFudGljLWNvbnZlbnRpb25zLmpzJztcbmltcG9ydCB7IGdldEFib3J0U3RyZWFtSWRGcm9tVG9rZW4gfSBmcm9tICcuLi91dGlsLmpzJztcbmltcG9ydCB7IENPTVBVVEVfSU5TVEFOQ0VfSUQgfSBmcm9tICcuL2NvbXB1dGUtaW5zdGFuY2UuanMnO1xuaW1wb3J0IHtcbiAgZ2V0TWF4SW5saW5lU3RlcHMsXG4gIGlzQmF0Y2hUcmFuc2l0aW9uc0VuYWJsZWQsXG4gIGlzUmVzaWxpZW50U3RlcERpc3BhdGNoRW5hYmxlZCxcbiAgTUFYX0JBVENIX0ZBTk9VVF9FVkVOVFMsXG4gIE1BWF9SRVNJTElFTlRfU1RFUF9JTlBVVF9CWVRFUyxcbn0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuaW1wb3J0IHtcbiAgYWJzb3JiU2tpcHBlZFNsb3RSZXBvcnQsXG4gIHR5cGUgRXZlbnRDcmVhdG9yLFxuICB0eXBlIExvYWRlZEV2ZW50TG9nLFxuICBtYXhFdmVudFNsb3QsXG4gIHF1ZXVlTWVzc2FnZSxcbiAgc2xvdFNuYXBzaG90UGFyYW1zLFxuICBzdGVwRGlzcGF0Y2hJZGVtcG90ZW5jeUtleSxcbn0gZnJvbSAnLi9oZWxwZXJzLmpzJztcbmltcG9ydCB7IFJlcGxheVJlY292ZXJ5UmVwb3J0ZXIgfSBmcm9tICcuL3JlcGxheS1yZWNvdmVyeS1yZXBvcnRlci5qcyc7XG5pbXBvcnQgdHlwZSB7IFByZWNsYWltZWRJbmxpbmVTdGFydCB9IGZyb20gJy4vc3RlcC1leGVjdXRvci5qcyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3VzcGVuc2lvbkhhbmRsZXJQYXJhbXMge1xuICBzdXNwZW5zaW9uOiBXb3JrZmxvd1N1c3BlbnNpb247XG4gIHdvcmxkOiBXb3JsZDtcbiAgcnVuOiBXb3JrZmxvd1J1bjtcbiAgc3Bhbj86IFNwYW47XG4gIHJlcXVlc3RJZD86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBydW50aW1lJ3MgbG9hZGVkIGV2ZW50IGxvZy4gRXZlcnkgZXZlbnQgY3JlYXRpb24gdGhpcyBzdXNwZW5zaW9uIG1ha2VzXG4gICAqIG5hbWVzIHRoZSBwb3NpdGlvbiBpdCB3YXMgZGVyaXZlZCBmcm9tLCBzbyBhIGJhY2tlbmQgdGhhdCBoYXMgcmVjb3JkZWRcbiAgICogZXZlbnRzIHRoZSByZXBsYXkgZGlkIG5vdCBzZWUgY2FuIHJlcG9ydCB0aGVtIGJhY2sgb24gdGhlIHdyaXRlIOKAlCBvciwgaWZcbiAgICogaXQgd291bGQgcmF0aGVyIHJlZnVzZSB0aGFuIHJlcG9ydCwgcmVqZWN0IGl0IHdpdGggYSA0MTIuIEEgcmVqZWN0aW9uIGlzXG4gICAqIG5vdCByZXRyaWVkIGhlcmU6IHRoZSBldmVudCdzIGNvcnJlbGF0aW9uIGlkIHdhcyBtaW50ZWQgYnkgKnRoaXMqIHJlcGxheSdzXG4gICAqIHNlZWRlZCBzZXF1ZW5jZSwgc28gcmUtY29tbWl0dGluZyBpdCBhZ2FpbnN0IGEgY29ycmVjdGVkIGxvZyB3b3VsZCBwZXJzaXN0XG4gICAqIGFuIGV2ZW50IG5vIGNvcnJlY3QgcmVwbGF5IHByb2R1Y2VzLiBUaGUgY2FsbGVyIHJlc3RhcnRzIHRoZSByZXBsYXlcbiAgICogaW5zdGVhZC5cbiAgICovXG4gIGV2ZW50TG9nPzogTG9hZGVkRXZlbnRMb2c7XG4gIC8qKlxuICAgKiBUdXJibyBtb2RlIG9ubHk6IGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIGJhY2tncm91bmRlZFxuICAgKiBgcnVuX3N0YXJ0ZWRgIGhhcyBsYW5kZWQgKHRoZSBydW4gZXhpc3RzKS4gV2hlbiBwcmVzZW50LCBldmVyeSB3b3JsZCB3cml0ZVxuICAgKiB0aGlzIHN1c3BlbnNpb24gcGVyZm9ybXMgKGBob29rX2NyZWF0ZWRgLCBgd2FpdF9jcmVhdGVkYCwgZWFnZXIgb3ZlcmZsb3dcbiAgICogYHN0ZXBfY3JlYXRlZGAsIOKApikgaXMgZ2F0ZWQgb24gaXQgc28gdGhlIHdyaXRlIG5ldmVyIHJhY2VzIGFoZWFkIG9mIHRoZVxuICAgKiBydW4ncyBjcmVhdGlvbi4gVGhlIHB1cmUgaW5saW5lIGhvdCBwYXRoIGRlZmVycyBhbGwgb2YgaXRzIHN0ZXBzIGFuZCB3cml0ZXNcbiAgICogbm90aGluZyBoZXJlLCBzbyBpdCBuZXZlciBhd2FpdHMgdGhpcyBiYXJyaWVyLiBgdW5kZWZpbmVkYCBvdXRzaWRlIHR1cmJvLFxuICAgKiB3aGVyZSBgcnVuX3N0YXJ0ZWRgIHdhcyBhbHJlYWR5IGF3YWl0ZWQgdXAgZnJvbnQuXG4gICAqL1xuICBydW5SZWFkeUJhcnJpZXI/OiBQcm9taXNlPHVua25vd24+O1xuICAvKiogT25lLXNob3QgdGVsZW1ldHJ5IHJlcG9ydGVyLCBhY3RpdmF0ZWQgb25seSBhZnRlciByZXBsYXkgaGFzIHJlY292ZXJlZC4gKi9cbiAgcmVwbGF5UmVjb3ZlcnlSZXBvcnRlcj86IFJlcGxheVJlY292ZXJ5UmVwb3J0ZXI7XG4gIC8qKlxuICAgKiBSZXNpbGllbnQgc3RlcCBkaXNwYXRjaDogd2hlbiBwcm92aWRlZCAoYW5kIHRoZSBwZXItc3RlcCBlbGlnaWJpbGl0eSBnYXRlc1xuICAgKiBwYXNzIOKAlCBzZWUgdGhlIHN0ZXAgb3BzIGJlbG93KSwgZWFjaCBuZXdseSBjcmVhdGVkIG5vbi1pbmxpbmUgc3RlcCdzXG4gICAqIGBzdGVwX2NyZWF0ZWRgIHdyaXRlIGlzIHBhcmFsbGVsaXplZCB3aXRoIGl0cyBzdGVwLWV4ZWN1dGlvbiBxdWV1ZVxuICAgKiBwdWJsaXNoLCBhbmQgdGhlIHF1ZXVlIG1lc3NhZ2UgY2FycmllcyB0aGUgc2VyaWFsaXplZCBzdGVwIGlucHV0XG4gICAqIChgc3RlcElucHV0YCkgc28gdGhlIGNvbnN1bWVyIGNhbiBpZGVtcG90ZW50bHkgcmUtZW5zdXJlIHRoZSBldmVudCBpZiB0aGVcbiAgICogZGlyZWN0IHdyaXRlIGZhaWxlZCB0cmFuc2llbnRseS4gU3RlcHMgcXVldWVkIHRoaXMgd2F5IGFyZSByZXBvcnRlZCBpblxuICAgKiB7QGxpbmsgU3VzcGVuc2lvbkhhbmRsZXJSZXN1bHQucXVldWVkU3RlcENvcnJlbGF0aW9uSWRzfSBzbyB0aGUgY2FsbGVyXG4gICAqIHNraXBzIHRoZW0gaW4gaXRzIG93biBkaXNwYXRjaCBwYXNzLiBPbWl0dGVkIGJ5IGNhbGxlcnMgdGhhdCBtdXN0IG5vdFxuICAgKiBxdWV1ZSAodGVybWluYWwgZHJhaW4sIHRlc3RzKSDigJQgY3JlYXRlcyB0aGVuIGJlaGF2ZSBleGFjdGx5IGFzIGJlZm9yZS5cbiAgICovXG4gIHN0ZXBEaXNwYXRjaD86IHtcbiAgICAvKiogVGhlIHVuaWZpZWQgd29ya2Zsb3cgcXVldWUgdGhpcyBydW4ncyBzdGVwIG1lc3NhZ2VzIGFyZSBwdWJsaXNoZWQgdG8uICovXG4gICAgcXVldWVOYW1lOiBWYWxpZFF1ZXVlTmFtZTtcbiAgICAvKipcbiAgICAgKiBMYXppbHkgcmVzb2x2ZXMgdGhlIHRyYWNlIGNhcnJpZXIgdG8gc3RhbXAgb24gdGhlIHN0ZXAgbWVzc2FnZXMuXG4gICAgICogQ2FsbGVkIGF0IG1vc3Qgb25jZSBwZXIgc3VzcGVuc2lvbiAobWVtb2l6ZWQgaGVyZSkuXG4gICAgICovXG4gICAgZ2V0VHJhY2VDYXJyaWVyOiAoKSA9PiBQcm9taXNlPFRyYWNlQ2Fycmllcj47XG4gIH07XG4gIC8qKlxuICAgKiBJbmxpbmUgc3RlcCBvd25lcnNoaXA6IHRoZSBxdWV1ZSBtZXNzYWdlIElEIG9mIHRoZSBpbnZvY2F0aW9uIHRoaXNcbiAgICogc3VzcGVuc2lvbiBydW5zIGluICh0aGUgcXVldWUgaGFuZGxlcidzIG1ldGEpLiBXaGVuIHByZXNlbnQgQU5EIHRoZVxuICAgKiBiYXRjaGVkIGZhbi1vdXQgZW5nYWdlcywgdGhlIGxhenktaW5saW5lIHN0ZXBzJyBkZWZlcnJlZCB3cml0ZXMgYXJlXG4gICAqIGZvbGRlZCBpbnRvIHRoZSBiYXRjaCBhcyBgc3RlcF9jcmVhdGVkYCArIGBzdGVwX3N0YXJ0ZWRgIHBhaXJzIOKAlCB0aGVcbiAgICogc3RhcnRlZCByb3cgc3RhbXBlZCB3aXRoIHRoaXMgSUQsIGV4YWN0bHkgbGlrZSB0aGUgbGF6eSBjbGFpbSBpdFxuICAgKiByZXBsYWNlcyDigJQgcHJlLWNsYWltaW5nIHRoZSBzdGVwcyB0aGUgY2FsbGVyIGlzIGFib3V0IHRvIHJ1biBpbmxpbmUuIFNlZVxuICAgKiB7QGxpbmsgU3VzcGVuc2lvbkhhbmRsZXJSZXN1bHQuaW5saW5lQ2xhaW1zfS4gQ2FsbGVycyB0aGF0IG5ldmVyXG4gICAqIGlubGluZS1leGVjdXRlICh0ZXJtaW5hbCBkcmFpbikgb21pdCBpdCwga2VlcGluZyB0aGVpciBsYXp5IHN0ZXBzIG9uIHRoZVxuICAgKiBwbGFpbiBkZWZlcnJlZCBwYXRoLlxuICAgKi9cbiAgb3duZXJNZXNzYWdlSWQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBMZXRzIHRoZSBiYXRjaGVkIGZhbi1vdXQgcmV0dXJuIGJlZm9yZSBldmVyeSBjaHVuayBoYXMgY29tbWl0dGVkOiBvbmx5XG4gICAqIHRoZSBjaHVuayBjYXJyeWluZyB0aGUgcHJlLWNsYWltZWQgaW5saW5lIHBhaXJzIGdhdGVzIHRoZSBoYW5kbGVyJ3NcbiAgICogcmV0dXJuIChpdHMgY2xhaW1zIGFyZSB3aGF0IHRoZSBjYWxsZXIgc3RhcnRzIGJvZGllcyBmcm9tKSwgd2hpbGUgdGhlXG4gICAqIHRyYWlsaW5nIGNodW5rcycgY29tbWl0cyDigJQgYW5kIGV2ZXJ5IGNodW5rJ3MgaW4tZmx1c2ggc3RlcC1tZXNzYWdlXG4gICAqIHB1Ymxpc2hlcyDigJQgcmlkZSB7QGxpbmsgU3VzcGVuc2lvbkhhbmRsZXJSZXN1bHQuZGVmZXJyZWRCYXRjaFdvcmt9LiBBXG4gICAqIGNhbGxlciB0aGF0IG9wdHMgaW4gTVVTVCBhd2FpdCB0aGF0IHByb21pc2UgYmVmb3JlIGFja2luZyBpdHMgZGVsaXZlcnk6XG4gICAqIHRoZSBkdXJhYmlsaXR5IGNvbnRyYWN0IChcImV2ZXJ5IGNyZWF0ZSBkdXJhYmxlIGJlZm9yZSBhY2tcIikgbW92ZXMgZnJvbVxuICAgKiB0aGUgaGFuZGxlcidzIHJldHVybiB0byB0aGF0IGpvaW4sIGFuZCBub3RoaW5nIGVsc2UgcmUtZHJpdmVzIGEgbG9zdFxuICAgKiB0cmFpbGluZyBjaHVuay4gQ2FsbGVycyB0aGF0IGRvbid0IG9wdCBpbiAodGVybWluYWwgZHJhaW4sIGRlZmF1bHQpXG4gICAqIGtlZXAgdGhlIGV2ZXJ5dGhpbmctZHVyYWJsZS1hdC1yZXR1cm4gYmVoYXZpb3IuXG4gICAqL1xuICBhbGxvd0RlZmVycmVkQmF0Y2hXb3JrPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgaGFuZGxpbmcgYSBzdXNwZW5zaW9uLiBSZXR1cm5zIHBlbmRpbmcgc3RlcCBpdGVtcyBzbyB0aGUgY2FsbGVyXG4gKiBjYW4gZGVjaWRlIHdoaWNoIHRvIGV4ZWN1dGUgaW5saW5lIHZzIHF1ZXVlIHRvIGJhY2tncm91bmQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3VzcGVuc2lvbkhhbmRsZXJSZXN1bHQge1xuICAvKiogUGVuZGluZyBzdGVwIGl0ZW1zIHdpdGggZXZlbnRzIGNyZWF0ZWQgYnV0IE5PVCBxdWV1ZWQgKi9cbiAgcGVuZGluZ1N0ZXBzOiBTdGVwSW52b2NhdGlvblF1ZXVlSXRlbVtdO1xuICAvKipcbiAgICogQ29ycmVsYXRpb24gSURzIGZvciB3aGljaCB0aGlzIHN1c3BlbnNpb24gY2FsbCBhY3R1YWxseSB3cm90ZSB0aGVcbiAgICogc3RlcF9jcmVhdGVkIGV2ZW50IChhcyBvcHBvc2VkIHRvIGNhdGNoaW5nIEVudGl0eUNvbmZsaWN0RXJyb3IgYmVjYXVzZVxuICAgKiBhIGNvbmN1cnJlbnQgaGFuZGxlciB3cm90ZSBpdCBmaXJzdCkuIE9ubHkgdGhlIGhhbmRsZXIgdGhhdCB3cm90ZSB0aGVcbiAgICogc3RlcF9jcmVhdGVkIGV2ZW50IHNob3VsZCBxdWV1ZSAvIGlubGluZS1leGVjdXRlIHRoZSBzdGVwIOKAlCB0aGlzXG4gICAqIGd1YXJhbnRlZXMgYSBzaW5nbGUgb3duZXIgcGVyIHN0ZXAsIGV2ZW4gd2hlbiBtdWx0aXBsZSBoYW5kbGVycyByYWNlXG4gICAqIGludG8gdGhlIHNhbWUgYmF0Y2ggYm91bmRhcnkuXG4gICAqL1xuICBjcmVhdGVkU3RlcENvcnJlbGF0aW9uSWRzOiBTZXQ8c3RyaW5nPjtcbiAgLyoqXG4gICAqIENvcnJlbGF0aW9uIElEcyBvZiBzdGVwcyB0aGlzIHN1c3BlbnNpb24gY2FsbCBhbHJlYWR5IHB1Ymxpc2hlZFxuICAgKiBzdGVwLWV4ZWN1dGlvbiBxdWV1ZSBtZXNzYWdlcyBmb3IsIHZpYSByZXNpbGllbnQgc3RlcCBkaXNwYXRjaCAodGhlXG4gICAqIGBzdGVwX2NyZWF0ZWRgIHdyaXRlIHBhcmFsbGVsaXplZCB3aXRoIGEgYHN0ZXBJbnB1dGAtY2FycnlpbmcgcXVldWVcbiAgICogcHVibGlzaCkuIFRoZSBjYWxsZXIgTVVTVCBOT1QgZGlzcGF0Y2ggdGhlc2UgYWdhaW4g4oCUIHRoZSBtZXNzYWdlIGlzXG4gICAqIGFscmVhZHkgb3V0IChhIGR1cGxpY2F0ZSB3b3VsZCBiZSBkZWR1cGVkIGJ5IGl0cyBpZGVtcG90ZW5jeSBrZXksIGJ1dFxuICAgKiBjb3N0cyBhIHdhc3RlZCByb3VuZC10cmlwKS4gRW1wdHkgd2hlbiB7QGxpbmsgU3VzcGVuc2lvbkhhbmRsZXJQYXJhbXMuc3RlcERpc3BhdGNofVxuICAgKiB3YXMgbm90IHByb3ZpZGVkIG9yIG5vIHN0ZXAgd2FzIGVsaWdpYmxlLlxuICAgKi9cbiAgcXVldWVkU3RlcENvcnJlbGF0aW9uSWRzOiBTZXQ8c3RyaW5nPjtcbiAgLyoqXG4gICAqIEhvdyBtYW55IGV2ZW50cyB0aGlzIHBoYXNlJ3Mgd3JpdGVzIHJlcG9ydGVkIGJhY2sgYXMgb2NjdXB5aW5nIHNsb3RzIHRoZXlcbiAgICogc2tpcHBlZCBvdmVyLCBhbHJlYWR5IG1lcmdlZCBpbnRvIHRoZSBjYWxsZXIncyBgZXZlbnRMb2cuZXZlbnRzYC4gTm9uemVyb1xuICAgKiBtZWFucyB0aGUgYXJyYXkgd2FzIHJlb3JkZXJlZCB0byByZXN0b3JlIHNsb3Qgb3JkZXIsIHNvIGFueSBpbmRleCB0aGVcbiAgICogY2FsbGVyIGNhY2hlZCBpbnRvIGl0IChwYXlsb2FkIHByZXdhcm0gc2NhbiBwb3NpdGlvbikgaXMgc3RhbGUuXG4gICAqL1xuICByZXBvcnRlZEV2ZW50Q291bnQ6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBzdGVwcyB3aG9zZSBgc3RlcF9jcmVhdGVkYCB3cml0ZXMgd2VyZSBpbnRlbnRpb25hbGx5IGRlZmVycmVkIHNvIHRoZVxuICAgKiBjYWxsZXIgY2FuIHJ1biB0aGVtIGlubGluZSB2aWEgbGF6eSBgc3RlcF9zdGFydGVkYCBldmVudHMgKHdoaWNoIGNyZWF0ZVxuICAgKiB0aGUgc3RlcCBvbiB0aGUgZmx5KSwgc2F2aW5nIG9uZSB3b3JsZCByb3VuZC10cmlwIHBlciBpbmxpbmUgc3RlcC4gVXAgdG9cbiAgICogYGdldE1heElubGluZVN0ZXBzKClgIHN0ZXBzIGFyZSBkZWZlcnJlZDsgdGhlIGNhbGxlciBydW5zIHRoZW0gaW5saW5lIGluXG4gICAqIHBhcmFsbGVsIGFuZCBxdWV1ZXMgdGhlIHJlc3QuIEVtcHR5IHdoZW4gbm8gc3RlcCB3YXMgZGVmZXJyZWQgKG5vdGhpbmdcbiAgICogcGVuZGluZywgb3IgYSBgaG9vay5nZXRDb25mbGljdCgpYCBhd2FpdGVyIGlzIHByZXNlbnQgc28gbm90aGluZyBpc1xuICAgKiBleGVjdXRlZCBpbmxpbmUpLiBUaGUgY2FsbGVyIHBhc3NlcyBlYWNoIGBkZWh5ZHJhdGVkSW5wdXRgIHN0cmFpZ2h0IHRvXG4gICAqIGBleGVjdXRlU3RlcGAsIHdoaWNoIHNlbmRzIGl0IGFzIHRoZSBgc3RlcF9zdGFydGVkYCBwYXlsb2FkLiBUaGUgYXRvbWljXG4gICAqIGNyZWF0ZS1jbGFpbSBpbnNpZGUgZWFjaCBgc3RlcF9zdGFydGVkYCBpcyB0aGUgZXhhY3RseS1vbmUtb3duZXIgZ2F0ZSB0aGF0XG4gICAqIHRoZSBzdGFuZGFsb25lIGBzdGVwX2NyZWF0ZWRgIHByb3ZpZGVkIGJlZm9yZTogdGhlIGxvc2VyIG9mIHRoZSByYWNlIGdldHNcbiAgICogYEVudGl0eUNvbmZsaWN0RXJyb3JgIOKGkiBgc2tpcHBlZGAgYW5kIGRvZXMgbm90IHJ1biB0aGUgYm9keS5cbiAgICovXG4gIGxhenlJbmxpbmVTdGVwczogQXJyYXk8e1xuICAgIGNvcnJlbGF0aW9uSWQ6IHN0cmluZztcbiAgICBzdGVwTmFtZTogc3RyaW5nO1xuICAgIGRlaHlkcmF0ZWRJbnB1dDogU2VyaWFsaXplZERhdGE7XG4gIH0+O1xuICAvKipcbiAgICogUHJlLWNsYWltZWQgaW5saW5lIHN0YXJ0cywgYnkgY29ycmVsYXRpb24gaWQ6IHRoZSBwZXItc3RlcCB2ZXJkaWN0cyBvZlxuICAgKiB0aGUgYHN0ZXBfY3JlYXRlZGAgKyBgc3RlcF9zdGFydGVkYCBwYWlycyB0aGUgYmF0Y2hlZCBmYW4tb3V0IGNvbW1pdHRlZFxuICAgKiBmb3IgdGhlIGxhenktaW5saW5lIHN0ZXBzLiBBIHN0ZXAgd2l0aCBhbiBlbnRyeSBoZXJlIGlzIHBhc3NlZCB0b1xuICAgKiBgZXhlY3V0ZVN0ZXBgIGFzIGBwcmVjbGFpbWVkU3RhcnRgIElOU1RFQUQgb2YgYGxhenlTdGVwSW5wdXRgIOKAlCBpdHNcbiAgICogaW5wdXQgYWxyZWFkeSByb2RlIHRoZSBwYWlyLCBhbmQgdGhlIGNsYWltIGlzIHNldHRsZWQ6IGBvd25lZDogdHJ1ZWBcbiAgICogY2FycmllcyB0aGUgc3RhcnRlZCBhdHRlbXB0LTEgZW50aXR5IChpbnB1dCByZS1hdHRhY2hlZCkgc28gdGhlIGJvZHlcbiAgICogcnVucyBzdHJhaWdodCBvZmYgdGhlIGJhdGNoIGNvbW1pdCB3aXRoIG5vIHN0YXJ0IHdyaXRlIG9mIGl0cyBvd247XG4gICAqIGBvd25lZDogZmFsc2VgIGxvc3QgdGhlIHBhaXIncyBhdG9taWMgY3JlYXRlLWNsYWltIHRvIGEgY29uY3VycmVudFxuICAgKiB3cml0ZXIsIGFuZCBleGVjdXRlU3RlcCByZXR1cm5zIGBza2lwcGVkYCB3aXRob3V0IHJ1bm5pbmcgdGhlIGJvZHkg4oCUXG4gICAqIHRoZSBzYW1lIG91dGNvbWUgYXMgbG9zaW5nIHRoZSBsYXp5IGNsYWltLiBFbXB0eSB3aGVuZXZlciB0aGUgZm9sZCBkaWRcbiAgICogbm90IGVuZ2FnZSAoYmF0Y2hpbmcgb2ZmLCBubyBgb3duZXJNZXNzYWdlSWRgLCBvciB0aGUgbG9uZS1pbmxpbmUgY2FzZSxcbiAgICogd2hpY2gga2VlcHMgdGhlIG9wdGltaXN0aWMgbGF6eSBwYXRoIGFuZCBpdHMgY2xhaW0vYm9keSBvdmVybGFwKS5cbiAgICpcbiAgICogQ3Jhc2ggd2luZG93OiB0aGUgcGFpciBjb21taXRzIGJlZm9yZSB0aGUgY2FsbGVyIHJ1bnMgdGhlIGJvZHksIHNvIGFcbiAgICogY3Jhc2ggYmV0d2VlbiB0aGVtIGxlYXZlcyBhIHN0YXJ0ZWQgc3RlcCBzdGFtcGVkIHdpdGggdGhpcyBtZXNzYWdlJ3NcbiAgICogSUQuIFJlZGVsaXZlcnkgb2YgdGhlIHNhbWUgbWVzc2FnZSByZS1leGVjdXRlcyBpdCB2aWEgdGhlIG93bmVkLXJlY292ZXJ5XG4gICAqIHBhdGgg4oCUIHRoZSBleGFjdCBtYWNoaW5lcnkgdGhlIGxhenkgY2xhaW0ncyBjcmFzaCB3aW5kb3cgYWxyZWFkeSB1c2VzLlxuICAgKi9cbiAgaW5saW5lQ2xhaW1zOiBNYXA8c3RyaW5nLCBQcmVjbGFpbWVkSW5saW5lU3RhcnQ+O1xuICAvKipcbiAgICogVGhlIGhpZ2hlc3Qgc2xvdCB0aGUgYmF0Y2hlZCBmYW4tb3V0IGNvbW1pdHRlZCwgd2hlbiBpdCByYW4uIFRoZSBiYXRjaCdzXG4gICAqIG93biBldmVudHMgYXJlIG5vdCBpbiB0aGUgY2FsbGVyJ3MgbG9hZGVkIGxvZyAodGhlIG5leHQgcmVsb2FkIHBpY2tzXG4gICAqIHRoZW0gdXApLCBzbyB0aGUgY2FsbGVyIGZvbGRzIHRoaXMgY2VpbGluZyBpbnRvIHRoZSBzbG90IHNuYXBzaG90IGl0XG4gICAqIGhhbmRzIHRoZSBpbmxpbmUgZXhlY3V0aW9ucyDigJQgb3RoZXJ3aXNlIGV2ZXJ5IGlubGluZSB0ZXJtaW5hbCB3cml0ZVxuICAgKiB3b3VsZCBuYW1lIGEgcHJlLWJhdGNoIHBvc2l0aW9uIGFuZCBiZSBhbnN3ZXJlZCB3aXRoIGEgc2tpcHBlZC1zbG90XG4gICAqIHJlcG9ydCBlY2hvaW5nIHRoZSBldmVudHMgdGhpcyBzdXNwZW5zaW9uIGp1c3Qgd3JvdGUuIFVuZGVyXG4gICAqIHtAbGluayBTdXNwZW5zaW9uSGFuZGxlclBhcmFtcy5hbGxvd0RlZmVycmVkQmF0Y2hXb3JrfSB0aGlzIGNvdmVycyB0aGVcbiAgICogY2h1bmtzIHRoYXQgaGFkIGNvbW1pdHRlZCBieSB0aGUgaGFuZGxlcidzIHJldHVybiAoYWx3YXlzIHRoZSBwYWlyXG4gICAqIGNodW5rKTsgYSB0cmFpbGluZyBjaHVuayB0aGF0IGNvbW1pdHMgbGF0ZXIgaXMgZWNob2VkIGJhY2sgb24gdGhlXG4gICAqIHRlcm1pbmFsIHdyaXRlcyBsaWtlIGFueSBmb3JlaWduIGV2ZW50IOKAlCByZXBvcnRzIHRoZSBleGVjdXRvciByZWFkcyBmb3JcbiAgICogcG9zaXRpb24gYW5kIGRpc2NhcmRzLlxuICAgKlxuICAgKiBTbyB0aGUgZWNobyBpcyBvbmx5IGZ1bGx5IHN1cHByZXNzZWQgZm9yIGEgU0lOR0xFLWNodW5rIGZvbGQuIE9uIGFcbiAgICogbXVsdGktY2h1bmsgZmFuLW91dCB0aGUgYm9kaWVzIHN0YXJ0IG9mZiB0aGUgcGFpciBjaHVuayB3aGlsZSB0cmFpbGluZ1xuICAgKiBjaHVua3MgYXJlIHN0aWxsIGluIGZsaWdodCwgYW5kIGFuIGlubGluZSB0ZXJtaW5hbCB3cml0ZSBpc3N1ZWQgaW4gdGhhdFxuICAgKiB3aW5kb3cgc3RpbGwgbmFtZXMgYSBwb3NpdGlvbiBiZWxvdyB0aGVtIGFuZCBzdGlsbCBkcmF3cyBhIHJlcG9ydCBmb3JcbiAgICogdGhlaXIgZXZlbnRzLiBCb3VuZGVkICh0cmFpbGluZyBjaHVua3Mgb25seSwgbGFyZ2UgZmFuLW91dHMgb25seSkgYW5kXG4gICAqIHNlbGYtY29ycmVjdGluZyBvbiB0aGUgbmV4dCByZWxvYWQg4oCUIHJlY29yZGVkIHNvIGEgcmVwb3J0IHNlZW4gdGhlcmVcbiAgICogcmVhZHMgYXMgZXhwZWN0ZWQgcmF0aGVyIHRoYW4gYXMgYSBidWcuXG4gICAqL1xuICBiYXRjaENvbW1pdHRlZFNsb3RDZWlsaW5nPzogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGJhdGNoZWQgZmFuLW91dCdzIGRlZmVycmVkIHdvcmssIHByZXNlbnQgb25seSB3aGVuIHRoZSBjYWxsZXIgb3B0ZWRcbiAgICogaW4gdmlhIHtAbGluayBTdXNwZW5zaW9uSGFuZGxlclBhcmFtcy5hbGxvd0RlZmVycmVkQmF0Y2hXb3JrfSBhbmRcbiAgICogdHJhaWxpbmcgd29yayBleGlzdHM6IHRoZSBjb21taXRzIG9mIGV2ZXJ5IGNodW5rIGV4Y2VwdCB0aGUgcGFpciBjaHVuayxcbiAgICogcGx1cyBldmVyeSBjaHVuaydzIHN0ZXAtbWVzc2FnZSBwdWJsaXNoZXMgKGVhY2ggY2hhaW5lZCBvbiBJVFMgT1dOXG4gICAqIGNodW5rJ3MgY29tbWl0LCBzbyBwdWJsaXNoLWFmdGVyLWNyZWF0ZSBob2xkcyBwZXIgc3RlcCkuIFRoZSBjYWxsZXJcbiAgICogTVVTVCBhd2FpdCBpdCBiZWZvcmUgYWNraW5nIOKAlCBhIHJlamVjdGlvbiBoZXJlIGlzIGEgZmFpbGVkIHN1c3BlbnNpb25cbiAgICogd3JpdGUgYW5kIGZhaWxzIHRoZSBkZWxpdmVyeSBleGFjdGx5IGFzIGl0IHdvdWxkIGhhdmUgYXQgdGhlIGhhbmRsZXInc1xuICAgKiByZXR1cm4uIFN0ZXBzIHdob3NlIG1lc3NhZ2VzIHRoaXMgd29yayBwdWJsaXNoZXMgYXJlIGFscmVhZHkgaW5cbiAgICoge0BsaW5rIHF1ZXVlZFN0ZXBDb3JyZWxhdGlvbklkc30gYXQgcmV0dXJuIHRpbWUuXG4gICAqL1xuICBkZWZlcnJlZEJhdGNoV29yaz86IFByb21pc2U8dm9pZD47XG4gIC8qKlxuICAgKiBUaGUgc29vbmVzdCBwZW5kaW5nIHdhaXQsIGlmIGFueTogc2Vjb25kcyB1bnRpbCBpdCBlbGFwc2VzIGFuZCB0aGVcbiAgICogY29ycmVsYXRpb25JZCBvZiB0aGUgd2FpdCB0aGF0IHByb2R1Y2VkIHRoYXQgdGltZW91dC4gVGhlXG4gICAqIGNvcnJlbGF0aW9uSWQgc2VlZHMgdGhlIGlkZW1wb3RlbmN5IGtleSBmb3IgdGhlIHdhaXQtY29udGludWF0aW9uXG4gICAqIHF1ZXVlIG1lc3NhZ2Ugc28gdGhhdCByZXBlYXRlZCBzdXNwZW5zaW9uIHBhc3NlcyBvdmVyIHRoZSBzYW1lXG4gICAqIHBlbmRpbmcgd2FpdCBjb2xsYXBzZSBpbnRvIGEgc2luZ2xlIGRlbGF5ZWQgY29udGludWF0aW9uLlxuICAgKi9cbiAgd2FpdFRpbWVvdXQ/OiB7IHNlY29uZHM6IG51bWJlcjsgY29ycmVsYXRpb25JZDogc3RyaW5nIH07XG4gIC8qKiBXaGV0aGVyIGEgaG9vayBjb25mbGljdCB3YXMgZGV0ZWN0ZWQgKHNob3VsZCByZS1pbnZva2UgaW1tZWRpYXRlbHkpICovXG4gIGhhc0hvb2tDb25mbGljdDogYm9vbGVhbjtcbiAgLyoqIFdoZXRoZXIgYSBgaG9vay5nZXRDb25mbGljdCgpYCBhd2FpdGVyIG5lZWRzIHRoZSB3b3JrZmxvdyB0byBjb250aW51ZSBpbW1lZGlhdGVseSAqL1xuICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBib29sZWFuO1xuICAvKiogV2hldGhlciBuYXRpdmUgd29ya2Zsb3cgYXR0cmlidXRlIGV2ZW50cyB3ZXJlIHdyaXR0ZW4gZm9yIHJlcGxheS4gKi9cbiAgaGFzQXR0cmlidXRlRXZlbnRzOiBib29sZWFuO1xuICAvKipcbiAgICogV2hldGhlciB0aGlzIHN1c3BlbnNpb24gY3JlYXRlZCBhbnkgaG9vayAoYGhvb2tfY3JlYXRlZGApIGV2ZW50cy4gVW5saWtlXG4gICAqIGBoYXNIb29rQ29uZmxpY3RgIC8gYGhhc0F3YWl0ZWRIb29rQ3JlYXRpb25gLCB0aGlzIGlzIHRydWUgZXZlbiBmb3IgYSBwbGFpblxuICAgKiBmaXJlLWFuZC1mb3JnZXQgaG9vayB3aXRoIG5vIGNvbmZsaWN0IGFuZCBubyBhd2FpdGVyLiBUdXJibyBtb2RlIHVzZXMgaXQgdG9cbiAgICogZGV0ZWN0IFwiYSBob29rIHdhcyBjcmVhdGVkIHRoaXMgc3VzcGVuc2lvblwiIGFuZCBzdG9wIGZvcmNpbmcgb3B0aW1pc3RpY1xuICAgKiBpbmxpbmUgc3RhcnQgKGEgaG9vayBpbnRyb2R1Y2VzIGxhdGVyIHJlc3VtZSBpbnZvY2F0aW9ucyB0aGF0IGNvdWxkIHJhY2UpLlxuICAgKi9cbiAgaGFzSG9va0V2ZW50czogYm9vbGVhbjtcbiAgLyoqXG4gICAqIFdhbGwtY2xvY2sgbXMgc3BlbnQgY29tbWl0dGluZyB0aGlzIHN1c3BlbnNpb24ncyBgaG9va19jcmVhdGVkYCBldmVudHNcbiAgICogKDAgd2hlbiBpdCBjcmVhdGVkIG5vbmUpLiBUaGUgY2FsbGVyIGFjY3VtdWxhdGVzIHRoaXMgYWNyb3NzIGl0ZXJhdGlvbnNcbiAgICogYW5kIHN1YnRyYWN0cyBpdCBmcm9tIHRoZSBUVEZTIGxhdGVuY3kgbWVhc3VyZW1lbnQsIHNvIHRpbWUgc3BlbnRcbiAgICogZHVyYWJseSBjcmVhdGluZyB0aGUgdXNlcidzIGhvb2tzIGRvZXNuJ3QgY291bnQgYXMgcnVudGltZSBvdmVyaGVhZC5cbiAgICovXG4gIGhvb2tDcmVhdGlvbk1zOiBudW1iZXI7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHNlcmlhbGl6aW5nIHRoaXMgc3VzcGVuc2lvbidzIG5ldyBzdGVwIGlucHV0cyB3YXMgcGFzc2l2ZSAoZGlkXG4gICAqIG5vdCBleGVjdXRlIHdvcmtmbG93LW93bmVkIGNvZGUgc3VjaCBhcyBnZXR0ZXJzLCBwcm94eSB0cmFwcywgb3IgY3VzdG9tXG4gICAqIHNlcmlhbGl6ZXJzKS4gYGZhbHNlYCBtZWFucyB0aGUgcmV0YWluZWQgVk0gbWF5IGhhdmUgZGl2ZXJnZWQgZnJvbSB3aGF0XG4gICAqIGEgY29sZCByZXBsYXkgd291bGQgY29tcHV0ZSwgc28gdGhlIGNhbGxlciBtdXN0IGRlbW90ZSB0byByZXBsYXkuXG4gICAqL1xuICByZXRhaW5lZFN0ZXBJbnB1dHNTYWZlOiBib29sZWFuO1xufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVIb29rRXZlbnQoe1xuICBydW5JZCxcbiAgaG9va0V2ZW50LFxuICBxdWV1ZUl0ZW0sXG4gIHJlcXVlc3RJZCxcbiAgY3JlYXRlRXZlbnQsXG59OiB7XG4gIHJ1bklkOiBzdHJpbmc7XG4gIGhvb2tFdmVudDogQ3JlYXRlRXZlbnRSZXF1ZXN0O1xuICBxdWV1ZUl0ZW06IEhvb2tJbnZvY2F0aW9uUXVldWVJdGVtO1xuICByZXF1ZXN0SWQ/OiBzdHJpbmc7XG4gIGNyZWF0ZUV2ZW50OiAoXG4gICAgZGF0YTogQ3JlYXRlRXZlbnRSZXF1ZXN0LFxuICAgIHBhcmFtcz86IENyZWF0ZUV2ZW50UGFyYW1zXG4gICkgPT4gUHJvbWlzZTxFdmVudFJlc3VsdD47XG59KTogUHJvbWlzZTx7XG4gIGhhc0hvb2tDb25mbGljdDogYm9vbGVhbjtcbiAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogYm9vbGVhbjtcbn0+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjcmVhdGVFdmVudChob29rRXZlbnQsIHtcbiAgICAgIHJlcXVlc3RJZCxcbiAgICB9KTtcblxuICAgIC8vIENoZWNrIGlmIHRoZSB3b3JsZCByZXR1cm5lZCBhIGhvb2tfY29uZmxpY3QgZXZlbnQgaW5zdGVhZCBvZiBob29rX2NyZWF0ZWQuXG4gICAgLy8gVGhlIGhvb2tfY29uZmxpY3QgZXZlbnQgaXMgc3RvcmVkIGluIHRoZSBldmVudCBsb2cgYW5kIHdpbGwgYmUgcmVwbGF5ZWRcbiAgICAvLyBvbiB0aGUgbmV4dCB3b3JrZmxvdyBpbnZvY2F0aW9uLCBjYXVzaW5nIHRoZSBob29rJ3MgcHJvbWlzZSB0byByZWplY3QuXG4gICAgaWYgKHJlc3VsdC5ldmVudD8uZXZlbnRUeXBlID09PSAnaG9va19jb25mbGljdCcpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGhhc0hvb2tDb25mbGljdDogdHJ1ZSxcbiAgICAgICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogZmFsc2UsXG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBoYXNIb29rQ29uZmxpY3Q6IGZhbHNlLFxuICAgICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogcXVldWVJdGVtLmhhc0NvbmZsaWN0QXdhaXRlciA9PT0gdHJ1ZSxcbiAgICB9O1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpKSB7XG4gICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ0hvb2sgYWxyZWFkeSBleGlzdHMsIGNvbnRpbnVpbmcnLCB7XG4gICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaGFzSG9va0NvbmZsaWN0OiBmYWxzZSxcbiAgICAgICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjogcXVldWVJdGVtLmhhc0NvbmZsaWN0QXdhaXRlciA9PT0gdHJ1ZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKFJ1bkV4cGlyZWRFcnJvci5pcyhlcnIpKSB7XG4gICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ1dvcmtmbG93IHJ1biBhbHJlYWR5IGNvbXBsZXRlZCwgc2tpcHBpbmcgaG9vaycsIHtcbiAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBoYXNIb29rQ29uZmxpY3Q6IGZhbHNlLFxuICAgICAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uOiBmYWxzZSxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKGlzV29ybGRWYWxpZGF0aW9uRmFpbHVyZShlcnIpKSB7XG4gICAgICBjb25zdCBmYXRhbCA9IG5ldyBGYXRhbEVycm9yKFxuICAgICAgICBgY3JlYXRlSG9vayBmYWlsZWQgV29ybGQgdmFsaWRhdGlvbjogJHtcbiAgICAgICAgICBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVycilcbiAgICAgICAgfWBcbiAgICAgICk7XG4gICAgICBmYXRhbC5jYXVzZSA9IGVycjtcbiAgICAgIHRocm93IGZhdGFsO1xuICAgIH1cblxuICAgIHRocm93IGVycjtcbiAgfVxufVxuXG4vKipcbiAqIEhhbmRsZXMgYSB3b3JrZmxvdyBzdXNwZW5zaW9uIGJ5IHByb2Nlc3NpbmcgYWxsIHBlbmRpbmcgb3BlcmF0aW9ucyAoaG9va3MsIHN0ZXBzLCB3YWl0cykuXG4gKiBDcmVhdGVzIGV2ZW50cyBmb3IgYWxsIG9wZXJhdGlvbnMgYnV0IGRvZXMgTk9UIHF1ZXVlIHN0ZXAgbWVzc2FnZXMg4oCUIHJldHVybnMgdGhlIHBlbmRpbmdcbiAqIHN0ZXBzIHNvIHRoZSBjYWxsZXIgY2FuIGRlY2lkZSB3aGljaCB0byBleGVjdXRlIGlubGluZSB2cyBxdWV1ZSB0byBiYWNrZ3JvdW5kLlxuICpcbiAqIFByb2Nlc3Npbmcgb3JkZXI6XG4gKiAxLiBIb29rcyBhcmUgcHJvY2Vzc2VkIGZpcnN0IHRvIHByZXZlbnQgcmFjZSBjb25kaXRpb25zIHdpdGggd2ViaG9vayByZWNlaXZlcnNcbiAqIDIuIFN0ZXAgZXZlbnRzIGFuZCB3YWl0IGV2ZW50cyBhcmUgY3JlYXRlZCBpbiBwYXJhbGxlbFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlU3VzcGVuc2lvbih7XG4gIHN1c3BlbnNpb24sXG4gIHdvcmxkLFxuICBydW4sXG4gIHNwYW4sXG4gIHJlcXVlc3RJZCxcbiAgZXZlbnRMb2csXG4gIHJ1blJlYWR5QmFycmllcixcbiAgcmVwbGF5UmVjb3ZlcnlSZXBvcnRlcixcbiAgc3RlcERpc3BhdGNoLFxuICBvd25lck1lc3NhZ2VJZCxcbiAgYWxsb3dEZWZlcnJlZEJhdGNoV29yayxcbn06IFN1c3BlbnNpb25IYW5kbGVyUGFyYW1zKTogUHJvbWlzZTxTdXNwZW5zaW9uSGFuZGxlclJlc3VsdD4ge1xuICBjb25zdCBydW5JZCA9IHJ1bi5ydW5JZDtcblxuICAvLyBUdXJibyBtb2RlOiBob2xkIGV2ZXJ5IHdvcmxkIHdyaXRlIGJlbG93IHVudGlsIHRoZSBiYWNrZ3JvdW5kZWRcbiAgLy8gYHJ1bl9zdGFydGVkYCBoYXMgKnNldHRsZWQqLCBzbyB3ZSBuZXZlciB3cml0ZSBhIHN0ZXAvaG9vay93YWl0IGV2ZW50IGZvciBhXG4gIC8vIHJ1biB0aGF0IGRvZXMgbm90IGV4aXN0IHlldC4gQSBuby1vcCBvdXRzaWRlIHR1cmJvIChiYXJyaWVyIHVuZGVmaW5lZCkgYW5kXG4gIC8vIG9uIHRoZSBwdXJlIGlubGluZSBob3QgcGF0aCwgd2hpY2ggZGVmZXJzIGFsbCBzdGVwcyBhbmQgd3JpdGVzIG5vdGhpbmcuXG4gIC8vIEF3YWl0aW5nIHRoZSBzYW1lICh1c3VhbGx5IGFscmVhZHktc2V0dGxlZCkgcHJvbWlzZSBtb3JlIHRoYW4gb25jZSBpcyBjaGVhcC5cbiAgLy8gQSBiYXJyaWVyIHJlamVjdGlvbiBpcyBzd2FsbG93ZWQgZm9yIG9yZGVyaW5nIG9ubHk6IGlmIGBydW5fc3RhcnRlZGAgdHJ1bHlcbiAgLy8gZmFpbGVkIHRoZSBydW4gZG9lcyBub3QgZXhpc3QsIHNvIHRoZSBzdWJzZXF1ZW50IHdyaXRlIHN1cmZhY2VzIHRoZSByZWFsXG4gIC8vIGVycm9yIChydW4gbm90IGZvdW5kIC8gZ29uZSkgYW5kIHRoZSBtZXNzYWdlIHJlZGVsaXZlcnMuXG4gIGNvbnN0IGVuc3VyZVJ1blJlYWR5ID0gYXN5bmMgKCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmIChydW5SZWFkeUJhcnJpZXIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHJ1blJlYWR5QmFycmllcjtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBpbnRlbnRpb25hbDogb3JkZXJpbmcgYmFycmllciBvbmx5IOKAlCBzZWUgYWJvdmUuXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIC8qKlxuICAgKiBBd2FpdCBldmVyeSBvcGVyYXRpb24gaW4gYSBzdXNwZW5zaW9uIHBoYXNlIGJlZm9yZSBsZXR0aW5nIGEgZmFpbHVyZVxuICAgKiBlc2NhcGUsIHByZWZlcnJpbmcgYSBzdGFsZS1zbmFwc2hvdCAoNDEyKSByZWplY3Rpb24gd2hlbiBvbmUgb2NjdXJyZWQuXG4gICAqXG4gICAqIGBQcm9taXNlLmFsbGAgcmVqZWN0cyBhcyBzb29uIGFzIG9uZSBvcGVyYXRpb24gZG9lcyBhbmQgbGVhdmVzIGl0cyBzaWJsaW5nc1xuICAgKiBpbiBmbGlnaHQuIFRoYXQgbWF0dGVycyBmb3IgYSA0MTI6IHRoZSBjYWxsZXIgcmVhY3RzIGJ5IHJlbG9hZGluZyB0aGUgZXZlbnRcbiAgICogbG9nIGFuZCByZXN0YXJ0aW5nIHRoZSByZXBsYXksIHNvIGEgc2libGluZyBjcmVhdGUgdGhhdCBsYW5kcyBhZnRlciB0aGVcbiAgICogcmVqZWN0aW9uIGVzY2FwZWQgY29tbWl0cyBhbiBldmVudCB3aG9zZSBjb3JyZWxhdGlvbiBpZCBjYW1lIGZyb20gdGhlXG4gICAqIGFiYW5kb25lZCByZXBsYXkncyBzZWVkZWQgc2VxdWVuY2Ug4oCUIGFuIGV2ZW50IHRoZSBmcmVzaCByZXBsYXkgbmV2ZXJcbiAgICogcHJvZHVjZXMg4oCUIGFuZCBpdCByYWNlcyB0aGUgcmVzdGFydCdzIHJlbG9hZCB3aGlsZSBkb2luZyBzby4gU2V0dGxpbmcgZmlyc3RcbiAgICogbWFrZXMgdGhpcyBwaGFzZSdzIHdyaXRlIHNldCBmaW5hbCBiZWZvcmUgdGhlIGNhbGxlciBhY3RzIG9uIHRoZSBmYWlsdXJlLlxuICAgKiBJdCBtaXJyb3JzIHRoZSBydW50aW1lJ3MgaW5saW5lIHN0ZXAgY2xhaW0sIHdoaWNoIHNldHRsZXMgdGhlIGluLWZsaWdodFxuICAgKiBzdGVwIGV4ZWN1dGlvbnMgYmVmb3JlIGVzY2FsYXRpbmcgYSA0MTIuXG4gICAqXG4gICAqIEEgNDEyIGlzIHByZWZlcnJlZCBvdmVyIGFueSBvdGhlciByZWplY3Rpb24gaW4gdGhlIHNhbWUgcGhhc2UgYmVjYXVzZSBpdFxuICAgKiBoYXMgYSBkZWZpbmVkLCBjaGVhcCByZWNvdmVyeSAocmVwbGF5IGZyb20gYSBjb3JyZWN0ZWQgbG9nKSB3aGlsZSB0aGVcbiAgICogb3RoZXJzIGRvIG5vdC4gQSBkZXRlcm1pbmlzdGljIGZhaWx1cmUgc3VjaCBhcyBhbiBhdHRyaWJ1dGUtdmFsaWRhdGlvblxuICAgKiBgRmF0YWxFcnJvcmAgcmVjdXJzIG9uIHRoZSByZXN0YXJ0IGFuZCBmYWlscyB0aGUgcnVuIHRoZW4sIGF0IHRoZSBjb3N0IG9mXG4gICAqIG9uZSBleHRyYSByZXBsYXkuXG4gICAqL1xuICBjb25zdCBzZXR0bGVQaGFzZSA9IGFzeW5jIChvcHM6IFByb21pc2U8dW5rbm93bj5bXSk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IHJlYXNvbnMgPSAoYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKG9wcykpXG4gICAgICAuZmlsdGVyKChyKTogciBpcyBQcm9taXNlUmVqZWN0ZWRSZXN1bHQgPT4gci5zdGF0dXMgPT09ICdyZWplY3RlZCcpXG4gICAgICAubWFwKChyKSA9PiByLnJlYXNvbik7XG4gICAgaWYgKHJlYXNvbnMubGVuZ3RoID09PSAwKSByZXR1cm47XG4gICAgdGhyb3cgcmVhc29ucy5maW5kKChyKSA9PiBQcmVjb25kaXRpb25GYWlsZWRFcnJvci5pcyhyKSkgPz8gcmVhc29uc1swXTtcbiAgfTtcblxuICAvLyBFdmVyeSBzdXNwZW5zaW9uIHdyaXRlIGNhcnJpZXMgcmVwbGF5LXJlY292ZXJ5IHRlbGVtZXRyeSBvbiB0aGUgZmlyc3Qgb25lXG4gIC8vIHRoYXQgY29tbWl0cyBhZnRlciByZXBsYXkgcmVjb3ZlcmVkLiBBbGwgc3VzcGVuc2lvbiBldmVudHMgYXJlXG4gIC8vIG5vbi1ydW5fY3JlYXRlZCBldmVudHMgb24gdGhpcyBydW4ncyBgcnVuSWRgLlxuICBjb25zdCByZXBvcnRlciA9IHJlcGxheVJlY292ZXJ5UmVwb3J0ZXIgPz8gUmVwbGF5UmVjb3ZlcnlSZXBvcnRlci5pbmVydCgpO1xuICBjb25zdCBjcmVhdGVFdmVudCA9IChkYXRhOiBDcmVhdGVFdmVudFJlcXVlc3QsIHBhcmFtcz86IENyZWF0ZUV2ZW50UGFyYW1zKSA9PlxuICAgIHJlcG9ydGVyLndpdGhFdmVudENyZWF0ZShwYXJhbXMsIChwKSA9PlxuICAgICAgd29ybGQuZXZlbnRzLmNyZWF0ZShydW5JZCwgZGF0YSwgcClcbiAgICApO1xuICAvLyBBZGRzIHRoZSBvcHRpbWlzdGljLWNvbmN1cnJlbmN5IGd1YXJkIHdoZW4gdGhlIGNhbGxlciBzdXBwbGllZCBhIGxvYWRlZFxuICAvLyBldmVudCBsb2c7IHdpdGhvdXQgb25lIGl0IGNyZWF0ZXMgZGlyZWN0bHkgKGNhbGxlcnMgd2l0aCBubyByZXBsYXlcbiAgLy8gc25hcHNob3QsIGUuZy4gdGVzdHMpLiBBIHN0YWxlICg0MTIpIHJlamVjdGlvbiBwcm9wYWdhdGVzIHRvIHRoZSBjYWxsZXIsXG4gIC8vIHdoaWNoIHJlc3RhcnRzIHRoZSByZXBsYXkgZnJvbSBhIGNvcnJlY3RlZCBsb2cg4oCUIGl0IGlzIG5vdCByZXRyaWVkIGhlcmUsXG4gIC8vIGJlY2F1c2UgdGhlIGV2ZW50J3MgY29ycmVsYXRpb24gaWQgd2FzIG1pbnRlZCBieSAqdGhpcyogcmVwbGF5J3Mgc2VlZGVkXG4gIC8vIHNlcXVlbmNlLCBzbyByZS1jb21taXR0aW5nIGl0IGFnYWluc3QgYSBjb3JyZWN0ZWQgbG9nIHdvdWxkIHBlcnNpc3QgYW5cbiAgLy8gZXZlbnQgbm8gY29ycmVjdCByZXBsYXkgcHJvZHVjZXMuXG4gIGxldCByZXBvcnRlZEV2ZW50cyA9IDA7XG4gIGNvbnN0IGNyZWF0ZUd1YXJkZWQ6IEV2ZW50Q3JlYXRvciA9IGFzeW5jIChkYXRhLCBwYXJhbXMpID0+IHtcbiAgICBpZiAoIWV2ZW50TG9nKSB7XG4gICAgICByZXR1cm4gY3JlYXRlRXZlbnQoZGF0YSwgcGFyYW1zKTtcbiAgICB9XG4gICAgY29uc3QgbG9nID0gZXZlbnRMb2c7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY3JlYXRlRXZlbnQoZGF0YSwge1xuICAgICAgLi4ucGFyYW1zLFxuICAgICAgLi4uc2xvdFNuYXBzaG90UGFyYW1zKGxvZy5ldmVudHMpLFxuICAgIH0pO1xuICAgIC8vIEJ1bXAtYW5kLXJlcG9ydDogdGhlIHdyaXRlIGxhbmRlZCBhYm92ZSB0aGUgc2xvdCBpdCBhc2tlZCBmb3IsIHNvIHRoZVxuICAgIC8vIHJlcG9ydCBob2xkcyB0aGUgZXZlbnRzIGl0IHdhcyBkZWNpZGVkIHdpdGhvdXQuIEFic29yYmluZyBoZXJlIHJhdGhlclxuICAgIC8vIHRoYW4gYXQgZWFjaCBjYWxsIHNpdGUgbWVhbnMgdGhlIHJlc3Qgb2YgdGhpcyBwaGFzZSdzIHdyaXRlcyDigJQgd2hpY2ggcmVhZFxuICAgIC8vIHRoZSBzYW1lIGFycmF5IHRvIGJ1aWxkIHRoZWlyIG93biBzbmFwc2hvdCDigJQgYXNrIGZvciBhIHNsb3QgYWJvdmUgdGhlbSxcbiAgICAvLyBhbmQgdGhlIHJlcGxheSB0aGF0IHJlc3VtZXMgZnJvbSB0aGlzIGxvZyBzZWVzIHRoZW0gd2l0aG91dCBhIHJlbG9hZC5cbiAgICBjb25zdCByZXBvcnQgPSBhYnNvcmJTa2lwcGVkU2xvdFJlcG9ydChsb2cuZXZlbnRzLCByZXN1bHQpO1xuICAgIHJlcG9ydGVkRXZlbnRzICs9IHJlcG9ydC5hZGRlZDtcbiAgICBpZiAocmVwb3J0LnRydW5jYXRlZCkge1xuICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnRHJvcHBlZCBhIHRydW5jYXRlZCBza2lwcGVkLXNsb3QgcmVwb3J0Jywge1xuICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgZXZlbnRUeXBlOiBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgZXZlbnRJZDogcmVzdWx0LmV2ZW50Py5ldmVudElkLFxuICAgICAgICBvZmZlcmVkOiByZXBvcnQub2ZmZXJlZCxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAocmVwb3J0LmFkZGVkID4gMCkge1xuICAgICAgcnVudGltZUxvZ2dlci5kZWJ1ZygnU3VzcGVuc2lvbiB3cml0ZSBza2lwcGVkIG9jY3VwaWVkIHNsb3RzJywge1xuICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgZXZlbnRUeXBlOiBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgZXZlbnRJZDogcmVzdWx0LmV2ZW50Py5ldmVudElkLFxuICAgICAgICByZXBvcnRlZDogcmVwb3J0LmFkZGVkLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIC8vIFNlcGFyYXRlIHF1ZXVlIGl0ZW1zIGJ5IHR5cGVcbiAgY29uc3Qgc3RlcEl0ZW1zID0gc3VzcGVuc2lvbi5zdGVwcy5maWx0ZXIoXG4gICAgKGl0ZW0pOiBpdGVtIGlzIFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3N0ZXAnXG4gICk7XG4gIGNvbnN0IGFsbEhvb2tJdGVtcyA9IHN1c3BlbnNpb24uc3RlcHMuZmlsdGVyKFxuICAgIChpdGVtKTogaXRlbSBpcyBIb29rSW52b2NhdGlvblF1ZXVlSXRlbSA9PiBpdGVtLnR5cGUgPT09ICdob29rJ1xuICApO1xuICBjb25zdCB3YWl0SXRlbXMgPSBzdXNwZW5zaW9uLnN0ZXBzLmZpbHRlcihcbiAgICAoaXRlbSk6IGl0ZW0gaXMgV2FpdEludm9jYXRpb25RdWV1ZUl0ZW0gPT4gaXRlbS50eXBlID09PSAnd2FpdCdcbiAgKTtcbiAgY29uc3QgYXR0cmlidXRlSXRlbXMgPSBzdXNwZW5zaW9uLnN0ZXBzLmZpbHRlcihcbiAgICAoaXRlbSk6IGl0ZW0gaXMgQXR0cmlidXRlSW52b2NhdGlvblF1ZXVlSXRlbSA9PiBpdGVtLnR5cGUgPT09ICdhdHRyaWJ1dGUnXG4gICk7XG5cbiAgY29uc3QgaG9va3NOZWVkaW5nQ3JlYXRpb24gPSBhbGxIb29rSXRlbXMuZmlsdGVyKFxuICAgIChpdGVtKSA9PiAhaXRlbS5oYXNDcmVhdGVkRXZlbnRcbiAgKTtcblxuICAvLyBHcm91cCBob29rIGl0ZW1zIHRoYXQgbmVlZCB3b3JrIGJ5IHRva2VuLCBwcmVzZXJ2aW5nIHF1ZXVlLWluc2VydGlvblxuICAvLyAod29ya2Zsb3cgY29kZSkgb3JkZXIgd2l0aGluIGVhY2ggdG9rZW4uIE9wZXJhdGlvbnMgb24gb25lIHRva2VuIG11c3RcbiAgLy8gYXBwbHkgaW4gY29kZSBvcmRlcjogYSBkaXNwb3NlKCkgb2YgYW4gZWFybGllciBob29rIHJlbGVhc2VzIHRoZSB0b2tlblxuICAvLyBiZWZvcmUgYSBsYXRlciBzYW1lLXRva2VuIGhvb2sncyBjcmVhdGlvbiBpcyB2YWxpZGF0ZWQg4oCUIG90aGVyd2lzZSB0aGVcbiAgLy8gbmV3IGhvb2sgcmVjb3JkcyBhIHNwdXJpb3VzIGhvb2tfY29uZmxpY3QgYWdhaW5zdCB0aGUgcnVuJ3Mgb3duXG4gIC8vIGRpc3Bvc2VkIGhvb2sg4oCUIHdoaWxlIGEgaG9vayBjcmVhdGVkIGFuZCBkaXNwb3NlZCB3aXRoaW4gdGhlIHNhbWVcbiAgLy8gc3VzcGVuc2lvbiBpcyBzdGlsbCBjcmVhdGVkIGJlZm9yZSBpdCBpcyBkaXNwb3NlZC4gRGlmZmVyZW50IHRva2Vuc1xuICAvLyBoYXZlIG5vIGNsYWltIGludGVyYWN0aW9uLCBzbyB0b2tlbiBncm91cHMgYXJlIHByb2Nlc3NlZCBpbiBwYXJhbGxlbC5cbiAgY29uc3QgaG9va0l0ZW1zQnlUb2tlbiA9IG5ldyBNYXA8c3RyaW5nLCBIb29rSW52b2NhdGlvblF1ZXVlSXRlbVtdPigpO1xuICBmb3IgKGNvbnN0IGl0ZW0gb2YgYWxsSG9va0l0ZW1zKSB7XG4gICAgaWYgKGl0ZW0uaGFzQ3JlYXRlZEV2ZW50ICYmICFpdGVtLmRpc3Bvc2VkKSB7XG4gICAgICBjb250aW51ZTsgLy8gYWxyZWFkeSBjb21taXR0ZWQgYW5kIHN0aWxsIGxpdmUg4oCUIG5vdGhpbmcgdG8gZG9cbiAgICB9XG4gICAgY29uc3QgZ3JvdXAgPSBob29rSXRlbXNCeVRva2VuLmdldChpdGVtLnRva2VuKTtcbiAgICBpZiAoZ3JvdXApIHtcbiAgICAgIGdyb3VwLnB1c2goaXRlbSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhvb2tJdGVtc0J5VG9rZW4uc2V0KGl0ZW0udG9rZW4sIFtpdGVtXSk7XG4gICAgfVxuICB9XG5cbiAgLy8gUmVzb2x2ZSBlbmNyeXB0aW9uIGtleSBmb3IgdGhpcyBydW5cbiAgY29uc3QgcmF3S2V5ID0gYXdhaXQgd29ybGQuZ2V0RW5jcnlwdGlvbktleUZvclJ1bj8uKHJ1bik7XG4gIGNvbnN0IGVuY3J5cHRpb25LZXkgPSByYXdLZXkgPyBhd2FpdCBpbXBvcnRLZXkocmF3S2V5KSA6IHVuZGVmaW5lZDtcblxuICAvLyBHYXRlIHBheWxvYWQgY29tcHJlc3Npb24gb24gdGhlIHJ1bidzIHNwZWNWZXJzaW9uLlxuICBjb25zdCBjb21wcmVzc2lvbiA9XG4gICAgKHJ1bi5zcGVjVmVyc2lvbiA/PyAwKSA+PSBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQ09NUFJFU1NJT047XG5cbiAgYXN5bmMgZnVuY3Rpb24gZGlzcG9zZUhvb2soXG4gICAgcXVldWVJdGVtOiBIb29rSW52b2NhdGlvblF1ZXVlSXRlbVxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBob29rRGlzcG9zZWRFdmVudDogQ3JlYXRlRXZlbnRSZXF1ZXN0ID0ge1xuICAgICAgZXZlbnRUeXBlOiAnaG9va19kaXNwb3NlZCcgYXMgY29uc3QsXG4gICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICB0b2tlbjogcXVldWVJdGVtLnRva2VuLFxuICAgICAgfSxcbiAgICB9O1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjcmVhdGVHdWFyZGVkKGhvb2tEaXNwb3NlZEV2ZW50LCB7IHJlcXVlc3RJZCB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgLy8gSG9vayB3YXMgYWxyZWFkeSBkaXNwb3NlZCBieSBhIGNvbmN1cnJlbnQgaW52b2NhdGlvbiDigJQgc2FmZSB0byBza2lwXG4gICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAnSG9vayBhbHJlYWR5IGRpc3Bvc2VkLCBza2lwcGluZyBkdXBsaWNhdGUgZGlzcG9zYWwnLFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICBtZXNzYWdlOiBlcnIubWVzc2FnZSxcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKFJ1bkV4cGlyZWRFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAnV29ya2Zsb3cgcnVuIGFscmVhZHkgY29tcGxldGVkLCBza2lwcGluZyBob29rIGRpc3Bvc2FsJyxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmIChIb29rTm90Rm91bmRFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgIC8vIEhvb2sgbWF5IGhhdmUgYWxyZWFkeSBiZWVuIGRpc3Bvc2VkIG9yIG5ldmVyIGNyZWF0ZWRcbiAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKCdIb29rIG5vdCBmb3VuZCBmb3IgZGlzcG9zYWwsIGNvbnRpbnVpbmcnLCB7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFByb2Nlc3MgaG9va3MgZmlyc3QgdG8gcHJldmVudCByYWNlIGNvbmRpdGlvbnMgd2l0aCB3ZWJob29rIHJlY2VpdmVycy5cbiAgLy8gVHJhY2sgYW55IGhvb2sgY29uZmxpY3RzIHRoYXQgb2NjdXIg4oCUIHRoZXNlIGFyZSByZXR1cm5lZCB0byB0aGUgY2FsbGVyXG4gIC8vIHNvIHRoZSBWMiBoYW5kbGVyIGNhbiByZS1pbnZva2UgaW1tZWRpYXRlbHkuXG4gIGxldCBoYXNIb29rQ29uZmxpY3QgPSBmYWxzZTtcbiAgbGV0IGhhc0F3YWl0ZWRIb29rQ3JlYXRpb24gPSBmYWxzZTtcbiAgbGV0IGhvb2tDcmVhdGlvbk1zID0gMDtcblxuICBpZiAoaG9va0l0ZW1zQnlUb2tlbi5zaXplID4gMCkge1xuICAgIGNvbnN0IGhvb2tQaGFzZVN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICBhd2FpdCBlbnN1cmVSdW5SZWFkeSgpO1xuICAgIGF3YWl0IHNldHRsZVBoYXNlKFxuICAgICAgWy4uLmhvb2tJdGVtc0J5VG9rZW4udmFsdWVzKCldLm1hcChhc3luYyAoaXRlbXMpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBxdWV1ZUl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICBsZXQgY3JlYXRpb25Db25mbGljdGVkID0gZmFsc2U7XG5cbiAgICAgICAgICBpZiAoIXF1ZXVlSXRlbS5oYXNDcmVhdGVkRXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IGhvb2tNZXRhZGF0YTogU2VyaWFsaXplZERhdGEgfCB1bmRlZmluZWQgPVxuICAgICAgICAgICAgICB0eXBlb2YgcXVldWVJdGVtLm1ldGFkYXRhID09PSAndW5kZWZpbmVkJ1xuICAgICAgICAgICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgOiAoKGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAgICAgICAgICAgIHF1ZXVlSXRlbS5tZXRhZGF0YSxcbiAgICAgICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgICAgIGVuY3J5cHRpb25LZXksXG4gICAgICAgICAgICAgICAgICAgIHN1c3BlbnNpb24uZ2xvYmFsVGhpcyxcbiAgICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNvbXByZXNzaW9uXG4gICAgICAgICAgICAgICAgICApKSBhcyBTZXJpYWxpemVkRGF0YSk7XG4gICAgICAgICAgICBjb25zdCBob29rRXZlbnQ6IENyZWF0ZUV2ZW50UmVxdWVzdCA9IHtcbiAgICAgICAgICAgICAgZXZlbnRUeXBlOiAnaG9va19jcmVhdGVkJyBhcyBjb25zdCxcbiAgICAgICAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgZXZlbnREYXRhOiB7XG4gICAgICAgICAgICAgICAgdG9rZW46IHF1ZXVlSXRlbS50b2tlbixcbiAgICAgICAgICAgICAgICB0b2tlblJldGVudGlvblVudGlsOiBxdWV1ZUl0ZW0udG9rZW5SZXRlbnRpb25VbnRpbCxcbiAgICAgICAgICAgICAgICBtZXRhZGF0YTogaG9va01ldGFkYXRhLFxuICAgICAgICAgICAgICAgIGlzV2ViaG9vazogcXVldWVJdGVtLmlzV2ViaG9vayA/PyBmYWxzZSxcbiAgICAgICAgICAgICAgICAuLi4ocXVldWVJdGVtLmlzU3lzdGVtICYmIHsgaXNTeXN0ZW06IHRydWUgfSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY3JlYXRlSG9va0V2ZW50KHtcbiAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgIGhvb2tFdmVudCxcbiAgICAgICAgICAgICAgcXVldWVJdGVtLFxuICAgICAgICAgICAgICByZXF1ZXN0SWQsXG4gICAgICAgICAgICAgIGNyZWF0ZUV2ZW50OiBjcmVhdGVHdWFyZGVkLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBoYXNIb29rQ29uZmxpY3QgfHw9IHJlc3VsdC5oYXNIb29rQ29uZmxpY3Q7XG4gICAgICAgICAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uIHx8PSByZXN1bHQuaGFzQXdhaXRlZEhvb2tDcmVhdGlvbjtcbiAgICAgICAgICAgIGNyZWF0aW9uQ29uZmxpY3RlZCA9IHJlc3VsdC5oYXNIb29rQ29uZmxpY3Q7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gRGlzcG9zZSBhZnRlciBjcmVhdGlvbiBmb3IgaG9va3MgYm9ybiBhbmQgZGlzcG9zZWQgd2l0aGluIHRoaXNcbiAgICAgICAgICAvLyBiYXRjaC4gQSBob29rIHdob3NlIGNyZWF0aW9uIGNvbmZsaWN0ZWQgd2FzIG5ldmVyIGNyZWF0ZWQsIHNvXG4gICAgICAgICAgLy8gdGhlcmUgaXMgbm90aGluZyB0byBkaXNwb3NlLlxuICAgICAgICAgIGlmIChxdWV1ZUl0ZW0uZGlzcG9zZWQgJiYgIWNyZWF0aW9uQ29uZmxpY3RlZCkge1xuICAgICAgICAgICAgYXdhaXQgZGlzcG9zZUhvb2socXVldWVJdGVtKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKTtcbiAgICBob29rQ3JlYXRpb25NcyA9IERhdGUubm93KCkgLSBob29rUGhhc2VTdGFydDtcbiAgfVxuXG4gIC8vIFByb2Nlc3MgYWJvcnQgcmVxdWVzdHMg4oCUIHJlc3VtZSB0aGUgaG9vayB3aXRoIGFib3J0IHBheWxvYWQgYW5kIHdyaXRlIHN0cmVhbSBwYWNrZXRcbiAgY29uc3QgaG9va3NOZWVkaW5nQWJvcnQgPSBhbGxIb29rSXRlbXMuZmlsdGVyKFxuICAgIChpdGVtKSA9PiBpdGVtLmFib3J0UmVxdWVzdGVkICYmICFpdGVtLmRpc3Bvc2VkXG4gICk7XG5cbiAgaWYgKGhvb2tzTmVlZGluZ0Fib3J0Lmxlbmd0aCA+IDApIHtcbiAgICBhd2FpdCBlbnN1cmVSdW5SZWFkeSgpO1xuICAgIGF3YWl0IHNldHRsZVBoYXNlKFxuICAgICAgaG9va3NOZWVkaW5nQWJvcnQubWFwKGFzeW5jIChxdWV1ZUl0ZW0pID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBEZWh5ZHJhdGUgdGhlIGFib3J0IHBheWxvYWQgZm9yIHN0b3JhZ2VcbiAgICAgICAgICBjb25zdCBhYm9ydFBheWxvYWQgPSBhd2FpdCBkZWh5ZHJhdGVTdGVwQXJndW1lbnRzKFxuICAgICAgICAgICAgeyBhYm9ydGVkOiB0cnVlLCByZWFzb246IHF1ZXVlSXRlbS5hYm9ydFJlYXNvbiB9LFxuICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICAgICAgc3VzcGVuc2lvbi5nbG9iYWxUaGlzLFxuICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICBjb21wcmVzc2lvblxuICAgICAgICAgICk7XG5cbiAgICAgICAgICAvLyBDcmVhdGUgaG9va19yZWNlaXZlZCBldmVudCB3aXRoIGFib3J0IHBheWxvYWRcbiAgICAgICAgICBhd2FpdCBjcmVhdGVHdWFyZGVkKHtcbiAgICAgICAgICAgIGV2ZW50VHlwZTogJ2hvb2tfcmVjZWl2ZWQnIGFzIGNvbnN0LFxuICAgICAgICAgICAgc3BlY1ZlcnNpb246IFNQRUNfVkVSU0lPTl9DVVJSRU5ULFxuICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgICAgdG9rZW46IHF1ZXVlSXRlbS50b2tlbixcbiAgICAgICAgICAgICAgcGF5bG9hZDogYWJvcnRQYXlsb2FkLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIFdyaXRlIHN0cmVhbSBjYW5jZWxsYXRpb24gcGFja2V0IGZvciByZWFsLXRpbWUgc3RlcCBwcm9wYWdhdGlvbi5cbiAgICAgICAgICAvLyBSZXVzZSB0aGUgc2FtZSBkZWh5ZHJhdGVkIHBheWxvYWQgYXMgdGhlIGhvb2sgZXZlbnQgc28gdGhlIHJlYXNvblxuICAgICAgICAgIC8vIHJvdW5kLXRyaXBzIHRocm91Z2ggYGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHNgIC8gYGh5ZHJhdGVTdGVwQXJndW1lbnRzYFxuICAgICAgICAgIC8vIChoYW5kbGVzIERPTUV4Y2VwdGlvbiwgY3VzdG9tIGVycm9ycywgZW5jcnlwdGlvbiwgZXRjLikgaW5zdGVhZCBvZlxuICAgICAgICAgIC8vIGJhcmUgSlNPTi5zdHJpbmdpZnkgd2hpY2ggbG9zZXMgdHlwZSBpbmZvcm1hdGlvbiBhbmQgZHJvcHMgdW5kZWZpbmVkLlxuICAgICAgICAgIC8vIHN0cmVhbU5hbWUgaXMgc2V0IG9uIHRoZSBxdWV1ZSBpdGVtIGF0IGNvbnRyb2xsZXIgY29uc3RydWN0aW9uIHRpbWVcbiAgICAgICAgICAvLyAoc2VlIHdvcmtmbG93L2Fib3J0LWNvbnRyb2xsZXIudHMpLlxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzdHJlYW1OYW1lID0gZ2V0QWJvcnRTdHJlYW1JZEZyb21Ub2tlbihxdWV1ZUl0ZW0udG9rZW4pO1xuICAgICAgICAgICAgYXdhaXQgd29ybGQuc3RyZWFtcy53cml0ZShcbiAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgIHN0cmVhbU5hbWUsXG4gICAgICAgICAgICAgIGFib3J0UGF5bG9hZCBhcyBVaW50OEFycmF5XG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgYXdhaXQgd29ybGQuc3RyZWFtcy5jbG9zZShydW5JZCwgc3RyZWFtTmFtZSk7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBCZXN0LWVmZm9ydCBzdHJlYW0gd3JpdGUg4oCUIGhvb2sgZXZlbnQgcHJvdmlkZXMgdGhlIGR1cmFibGUgZmFsbGJhY2tcbiAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoXG4gICAgICAgICAgICAgICdGYWlsZWQgdG8gd3JpdGUgYWJvcnQgc3RyZWFtIHBhY2tldCwgaG9vayBldmVudCB3aWxsIHByb3ZpZGUgZmFsbGJhY2snLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpIHx8IFJ1bkV4cGlyZWRFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICdXb3JrZmxvdyBydW4gYWxyZWFkeSBjb21wbGV0ZWQsIHNraXBwaW5nIGFib3J0JyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvLyBDcmVhdGUgc3RlcCBldmVudHMgZm9yIHN0ZXBzIHRoYXQgZG9uJ3QgaGF2ZSB0aGVtIHlldC5cbiAgLy8gVW5saWtlIFYxLCB3ZSBkbyBOT1QgcXVldWUgc3RlcCBtZXNzYWdlcyBmcm9tIGhlcmUg4oCUIHRoZSBjYWxsZXJcbiAgLy8gZGVjaWRlcyB3aGljaCBzdGVwcyB0byBleGVjdXRlIGlubGluZSB2cy4gcXVldWUgdG8gYmFja2dyb3VuZC5cbiAgLy8gV2FpdCBldmVudHMgYXJlIGFsc28gY3JlYXRlZCBpbiBwYXJhbGxlbCBiZWxvdy5cbiAgY29uc3Qgc3RlcHNOZWVkaW5nQ3JlYXRpb24gPSBuZXcgU2V0KFxuICAgIHN0ZXBJdGVtc1xuICAgICAgLmZpbHRlcigocXVldWVJdGVtKSA9PiAhcXVldWVJdGVtLmhhc0NyZWF0ZWRFdmVudClcbiAgICAgIC5tYXAoKHF1ZXVlSXRlbSkgPT4gcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQpXG4gICk7XG5cbiAgLy8gQ29ycmVsYXRpb24gSURzIGZvciB3aGljaCBUSElTIHN1c3BlbnNpb24gY2FsbCBhY3R1YWxseSB3cm90ZSB0aGVcbiAgLy8gc3RlcF9jcmVhdGVkIGV2ZW50LiBQb3B1bGF0ZWQgYnkgdGhlIG9wcyBiZWxvdyBhZnRlciBhIHN1Y2Nlc3NmdWxcbiAgLy8gZXZlbnRzLmNyZWF0ZSDigJQgdXNlZCBieSB0aGUgY2FsbGVyIHRvIGNsYWltIG93bmVyc2hpcCBhbmQgYXZvaWRcbiAgLy8gcmFjaW5nIHdpdGggY29uY3VycmVudCBoYW5kbGVycyBvbiBzdGVwIGV4ZWN1dGlvbi5cbiAgY29uc3QgY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIC8vIFNlcmlhbGl6YXRpb24gYWx3YXlzIHJ1bnMgdGhyb3VnaCB0aGUgb25lIG9yZGluYXJ5IHBhdGggYmVsb3csIHNvIHRoZVxuICAvLyBkdXJhYmxlIGJ5dGVzIGNhbm5vdCBkZXBlbmQgb24gcmV0ZW50aW9uLiBXaGF0IHJldGVudGlvbiBuZWVkcyB0byBrbm93IGlzXG4gIC8vIHdoZXRoZXIgdGhhdCBzZXJpYWxpemF0aW9uICpleGVjdXRlZCogd29ya2Zsb3cgY29kZSAoZ2V0dGVycywgcHJveHlcbiAgLy8gdHJhcHMsIGN1c3RvbSBzZXJpYWxpemVycykg4oCUIHNpZGUgZWZmZWN0cyBhIGNvbGQgcmVwbGF5IHdvdWxkIG5vdFxuICAvLyByZXBlYXQsIHNpbmNlIGEgcmVwbGF5IHNraXBzIGRlaHlkcmF0aW9uIGZvciBhbHJlYWR5LXJlY29yZGVkIHN0ZXBzLlxuICAvLyBUaGUgaGFyZGVuZWQgc2VyaWFsaXplciByZWNvcmRzIGV4YWN0bHkgdGhhdCBpbnRvIHRoaXMgc2luayAoc2VlXG4gIC8vIC4uL3NlcmlhbGl6YXRpb24vaGFyZGVuZWQudHMpOyB3aGVuIGFueSBpbnB1dCBpbiB0aGUgYmF0Y2ggcmVjb3JkcyBhblxuICAvLyBleGVjdXRpb24sIHRoZSBjYWxsZXIgZGVtb3RlcyB0aGUgc2Vzc2lvbiBzbyB0aGUgc2lkZSBlZmZlY3RzIGxhbmQgaW4gYVxuICAvLyBWTSB0aGF0IGlzIGFib3V0IHRvIGJlIGRpc2NhcmRlZCwgZXhhY3RseSBsaWtlIHRoZSBwcmUtcmV0ZW50aW9uXG4gIC8vIHJ1bnRpbWUuXG4gIGNvbnN0IGd1ZXN0Q29kZVN0YXRzOiBHdWVzdENvZGVTdGF0cyA9IHsgZXhlY3V0aW9uczogW10gfTtcblxuICAvLyBMYXp5IGlubGluZSBzdGFydDogZGVmZXIgdGhlIHN0ZXBfY3JlYXRlZCB3cml0ZSBmb3IgdXAgdG9cbiAgLy8gYGdldE1heElubGluZVN0ZXBzKClgIHN0ZXBzIHRoZSBjYWxsZXIgd2lsbCBydW4gaW5saW5lIChpbiBwYXJhbGxlbCkuIEVhY2hcbiAgLy8gc3RlcCBpcyBjcmVhdGVkIG9uIHRoZSBmbHkgYnkgdGhlIGxhenkgYHN0ZXBfc3RhcnRlZGAgZXhlY3V0ZVN0ZXAgc2VuZHNcbiAgLy8gKHNhdmluZyBhIHJvdW5kLXRyaXAgcGVyIHN0ZXApLiBXZSBuZXZlciBkZWZlciB3aGVuIGEgYGhvb2suZ2V0Q29uZmxpY3QoKWBcbiAgLy8gYXdhaXRlciBpcyBwcmVzZW50LCBiZWNhdXNlIGluIHRoYXQgY2FzZSB0aGUgY2FsbGVyIGV4ZWN1dGVzIG5vdGhpbmcgaW5saW5lXG4gIC8vIChpdCByZS1pbnZva2VzIGltbWVkaWF0ZWx5IHRvIHJlc29sdmUgdGhlIGF3YWl0ZXIpLCBzbyBkZWZlcnJpbmcgd291bGRcbiAgLy8gbGVhdmUgdGhlIHN0ZXBzIHVuY3JlYXRlZCBhbmQgdW5xdWV1ZWQuIFdlIHBpY2sgdGhlIGZpcnN0IE4gdW5jcmVhdGVkIHN0ZXBzXG4gIC8vIOKAlCBtYXRjaGluZyB0aGUgY2FsbGVyJ3MgaW5saW5lLWNhbmRpZGF0ZSBzZWxlY3Rpb24g4oCUIGFuZCBkZWh5ZHJhdGUgdGhlaXJcbiAgLy8gaW5wdXQgaGVyZSBzbyBleGVjdXRlU3RlcCBjYW4gc2hpcCBpdCBhcyB0aGUgc3RlcF9zdGFydGVkIHBheWxvYWQuXG4gIGNvbnN0IGxhenlJbmxpbmVDb3JyZWxhdGlvbklkcyA9IG5ldyBTZXQ8c3RyaW5nPihcbiAgICBoYXNBd2FpdGVkSG9va0NyZWF0aW9uID09PSBmYWxzZVxuICAgICAgPyBzdGVwSXRlbXNcbiAgICAgICAgICAuZmlsdGVyKChpdGVtKSA9PiBzdGVwc05lZWRpbmdDcmVhdGlvbi5oYXMoaXRlbS5jb3JyZWxhdGlvbklkKSlcbiAgICAgICAgICAuc2xpY2UoMCwgZ2V0TWF4SW5saW5lU3RlcHMoKSlcbiAgICAgICAgICAubWFwKChpdGVtKSA9PiBpdGVtLmNvcnJlbGF0aW9uSWQpXG4gICAgICA6IFtdXG4gICk7XG4gIC8vIENvbGxlY3RlZCBieSBjb3JyZWxhdGlvbklkIGJlY2F1c2UgdGhlIHBlci1zdGVwIG9wcyBiZWxvdyBydW4gY29uY3VycmVudGx5XG4gIC8vIGFuZCBzZXR0bGUgb3V0IG9mIG9yZGVyLiBXZSByZWJ1aWxkIHRoZSBhcnJheSBpbiBkZXRlcm1pbmlzdGljXG4gIC8vIGBsYXp5SW5saW5lQ29ycmVsYXRpb25JZHNgIG9yZGVyICh0aGUgb3JkZXJlZCBzbGljZSBhYm92ZSkgYWZ0ZXIgdGhlIG9wc1xuICAvLyBzZXR0bGUsIHNvIHRoZSBpbmxpbmUgYmF0Y2ggb3JkZXIgaXMgc3RhYmxlIHJlZ2FyZGxlc3Mgb2YgZGVoeWRyYXRpb24gdGltaW5nLlxuICBjb25zdCBsYXp5SW5saW5lQnlDb3JyZWxhdGlvbklkID0gbmV3IE1hcDxcbiAgICBzdHJpbmcsXG4gICAgU3VzcGVuc2lvbkhhbmRsZXJSZXN1bHRbJ2xhenlJbmxpbmVTdGVwcyddW251bWJlcl1cbiAgPigpO1xuXG4gIGNvbnN0IG9wczogUHJvbWlzZTx2b2lkPltdID0gW107XG5cbiAgLy8gQ29ycmVsYXRpb24gSURzIG9mIHN0ZXBzIHdob3NlIHN0ZXAtZXhlY3V0aW9uIHF1ZXVlIG1lc3NhZ2Ugd2FzIGFscmVhZHlcbiAgLy8gcHVibGlzaGVkIGJ5IHRoZSByZXNpbGllbnQtZGlzcGF0Y2ggb3BzIGJlbG93IChhbG9uZ3NpZGUgdGhlIHN0ZXBfY3JlYXRlZFxuICAvLyB3cml0ZSkuIFJlcG9ydGVkIHRvIHRoZSBjYWxsZXIgc28gaXRzIGRpc3BhdGNoIHBhc3Mgc2tpcHMgdGhlbS5cbiAgY29uc3QgcXVldWVkU3RlcENvcnJlbGF0aW9uSWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgLy8gUmVzaWxpZW50IHN0ZXAgZGlzcGF0Y2ggZWxpZ2liaWxpdHksIHNoYXJlZCBieSBldmVyeSBzdGVwIG9wIGJlbG93ICh0aGVcbiAgLy8gcGVyLXN0ZXAgaW5wdXQtc2l6ZSBjaGVjayBpcyBhcHBsaWVkIGluc2lkZSB0aGUgb3ApLiBBbGwgbXVzdCBob2xkOlxuICAvL1xuICAvLyAgLSBUaGUgY2FsbGVyIHByb3ZpZGVkIGEgZGlzcGF0Y2ggdGFyZ2V0IChgc3RlcERpc3BhdGNoYCkg4oCUIHRlcm1pbmFsXG4gIC8vICAgIGRyYWlucyBhbmQgb3RoZXIgY3JlYXRlLW9ubHkgY2FsbGVycyBuZXZlciBxdWV1ZS5cbiAgLy8gIC0gVGhlIGZlYXR1cmUgaXMgZW5hYmxlZCAoYFdPUktGTE9XX1JFU0lMSUVOVF9TVEVQX0RJU1BBVENIYCBvcHQtaW4pLlxuICAvLyAgICBJdCBpcyBvZmYgYnkgZGVmYXVsdCBiZWNhdXNlIHRoZSBwdWJsaXNoIHJhY2VzIHRoZSBjcmVhdGUncyB2ZXJkaWN0LFxuICAvLyAgICBhbmQgYSBjcmVhdGUgY2FuIGNvbWUgYmFjayByZWZ1c2VkOiBhcyBhIGR1cGxpY2F0ZSB0aGUgcmVwbGF5IHNob3VsZFxuICAvLyAgICBzdG9wIHB1cnN1aW5nLCBvciDigJQgb24gYSBXb3JsZCB0aGF0IHdvdWxkIHJhdGhlciByZWZ1c2UgYSBzdGFsZSB3cml0ZVxuICAvLyAgICB0aGFuIHJlcG9ydCB3aGF0IGl0IG1pc3NlZCDigJQgYXMgYSA0MTIuIEVpdGhlciB3YXkgdGhlIHF1ZXVlIG1lc3NhZ2VcbiAgLy8gICAgY2FycnlpbmcgdGhlIHBheWxvYWQgaXMgYWxyZWFkeSBvdXQsIGFuZCB0aGUgY29uc3VtZXIgY2FuIG1hdGVyaWFsaXplIGFcbiAgLy8gICAgc3RlcCB3aG9zZSBjcmVhdGUgd2FzIHJlZnVzZWQuIE5vdGhpbmcgb3JkZXJzIHRoYXQgdmVyZGljdCBiZWZvcmUgdGhlXG4gIC8vICAgIGNvbnN1bWVyJ3MgcmVkZWxpdmVyeSByZS1lbnN1cmUsIHNvIG5vIGJhY2tlbmQtc2lkZSByZXZvY2F0aW9uXG4gIC8vICAgIGJvb2trZWVwaW5nIGNhbiBjbG9zZSB0aGUgd2luZG93OiBhIGJlc3QtZWZmb3J0IG1hcmtlciB0aGF0IGZhaWxzIG9wZW5cbiAgLy8gICAgY2Fubm90IGNhcnJ5IGEgY29ycmVjdG5lc3MgcHJvcGVydHkuIFRoZSBzZXF1ZW50aWFsIHBhdGggaXMgdGhlIG9ubHlcbiAgLy8gICAgdGhpbmcgdGhhdCBnaXZlcyB0aGUgbWVzc2FnZSBhIGhhcHBlbnMtYWZ0ZXIgZWRnZSBvdmVyIHRoZSB2ZXJkaWN0LlxuICAvLyAgLSBUaGUgcnVuJ3MgcXVldWUgdHJhbnNwb3J0IHByZXNlcnZlcyBiaW5hcnkgcGF5bG9hZHMgKENCT1IsXG4gIC8vICAgIHNwZWNWZXJzaW9uID49IDMpOiBgc3RlcElucHV0LmlucHV0YCBpcyB0aGUgc2VyaWFsaXplZCAocG9zc2libHlcbiAgLy8gICAgZW5jcnlwdGVkKSBpbnB1dCBieXRlcywgd2hpY2ggdGhlIEpTT04gdHJhbnNwb3J0IHdvdWxkIG1hbmdsZS5cbiAgY29uc3QgcmVzaWxpZW50RGlzcGF0Y2hFbGlnaWJsZSA9XG4gICAgc3RlcERpc3BhdGNoICE9PSB1bmRlZmluZWQgJiZcbiAgICBpc1Jlc2lsaWVudFN0ZXBEaXNwYXRjaEVuYWJsZWQoKSAmJlxuICAgIChydW4uc3BlY1ZlcnNpb24gPz8gMCkgPj0gU1BFQ19WRVJTSU9OX1NVUFBPUlRTX0NCT1JfUVVFVUVfVFJBTlNQT1JUO1xuXG4gIC8vIEJhdGNoZWQgZmFuLW91dDogZm9sZCB0aGlzIHN1c3BlbnNpb24ncyBzdGVwX2NyZWF0ZWQgKyB3YWl0X2NyZWF0ZWRcbiAgLy8gd3JpdGVzIGludG8gb25lIGBldmVudHMuY3JlYXRlQmF0Y2hgIGNhbGwgKG9uZSBkdXJhYmxlIHdyaXRlLCBwZXItZXZlbnRcbiAgLy8gb3V0Y29tZXMpIGluc3RlYWQgb2Ygb25lIHdyaXRlIHBlciBldmVudC4gRW5nYWdlcyBvbmx5IGZvciBhIENMRUFOXG4gIC8vIGZhbi1vdXQg4oCUIG5vIGF0dHJpYnV0ZSB3cml0ZXMsIG5vIGhvb2sgd3JpdGVzLCBubyByZXNpbGllbnQgZGlzcGF0Y2hcbiAgLy8gKHdob3NlIGNyZWF0ZXMgYXJlIGVhY2ggcGFpcmVkIHdpdGggYSBxdWV1ZSBwdWJsaXNoKSDigJQgb24gYSBXb3JsZCB0aGF0XG4gIC8vIGltcGxlbWVudHMgdGhlIG9wdGlvbmFsIG1ldGhvZCBhbmQgYSBydW4gd2hvc2UgZXZlbnRzIGFyZSBzbG90LW51bWJlcmVkLlxuICAvLyBFdmVyeXRoaW5nIG91dHNpZGUgdGhlIGdhdGUga2VlcHMgdGhlIHNpbmdsZS1ldmVudCBwYXRoIGJ5dGUtZm9yLWJ5dGUuXG4gIGNvbnN0IGJhdGNoRmFub3V0RWxpZ2libGUgPVxuICAgIGlzQmF0Y2hUcmFuc2l0aW9uc0VuYWJsZWQoKSAmJlxuICAgIHR5cGVvZiB3b3JsZC5ldmVudHMuY3JlYXRlQmF0Y2ggPT09ICdmdW5jdGlvbicgJiZcbiAgICAocnVuLnNwZWNWZXJzaW9uID8/IDApID49IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19TTE9UX0lERU5USVRZICYmXG4gICAgIXJlc2lsaWVudERpc3BhdGNoRWxpZ2libGUgJiZcbiAgICBhbGxIb29rSXRlbXMubGVuZ3RoID09PSAwICYmXG4gICAgYXR0cmlidXRlSXRlbXMubGVuZ3RoID09PSAwO1xuICAvKipcbiAgICogVGhlIGZvbGQncyBjb2xsZWN0aW9uLCBpbiBzY2hlZHVsaW5nIG9yZGVyIChzdGVwcyBpbiBzdGVwSXRlbXMgb3JkZXIsXG4gICAqIHRoZW4gd2FpdHMpLiBTdGVwIGVudHJpZXMgYXJlIGVucXVldWVkIGJ5IHRoZWlyIHByZXAgcHJvbWlzZXMgKGlucHV0XG4gICAqIGRlaHlkcmF0aW9uIHJ1bnMgY29uY3VycmVudGx5LCBzbyBlbnRyaWVzIGFyZSBvcmRlcmVkIGJ5IGBvcmRlcmAsIG5vdCBieVxuICAgKiBjb21wbGV0aW9uKTsgdGhlIHNpbmdsZSBmbHVzaCBvcCBiZWxvdyBhd2FpdHMgZXZlcnkgcHJlcCwgc29ydHMsIGFuZFxuICAgKiBjb21taXRzIHRoZSB3aG9sZSBzZXQgdGhyb3VnaCBgY3JlYXRlQmF0Y2hgLlxuICAgKi9cbiAgY29uc3QgYmF0Y2hRdWV1ZToge1xuICAgIG9yZGVyOiBudW1iZXI7XG4gICAga2luZDogJ3N0ZXAnIHwgJ3dhaXQnIHwgJ2lubGluZS1jcmVhdGVkJyB8ICdpbmxpbmUtc3RhcnRlZCc7XG4gICAgY29ycmVsYXRpb25JZDogc3RyaW5nO1xuICAgIC8qKiBUaGUgc3RlcCdzIG5hbWUsIHNldCBvbiBzdGVwLWNhcnJ5aW5nIGtpbmRzICh0aGUgaW4tZmx1c2ggcHVibGlzaGVzXG4gICAgICogIGFuZCB0aGUgZGlzcGF0Y2ggaWRlbXBvdGVuY3kga2V5IG5lZWQgaXQpLiAqL1xuICAgIHN0ZXBOYW1lPzogc3RyaW5nO1xuICAgIGV2ZW50OiBDcmVhdGVFdmVudFJlcXVlc3Q7XG4gIH1bXSA9IFtdO1xuICBjb25zdCBiYXRjaFByZXBzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcblxuICAvLyBQcmUtY2xhaW1lZCBpbmxpbmUgcGFpcnM6IGZvbGQgZWFjaCBsYXp5LWlubGluZSBzdGVwJ3MgZGVmZXJyZWRcbiAgLy8gYHN0ZXBfY3JlYXRlZGAgKGNhcnJ5aW5nIGl0cyBpbnB1dCkgQU5EIGl0cyBgc3RlcF9zdGFydGVkYCBjbGFpbSAoYmFyZSxcbiAgLy8gb3duZXJzaGlwLXN0YW1wZWQpIGludG8gdGhlIGJhdGNoLCBzbyB0aGUgd2hvbGUgZmFuLW91dCDigJQgdGhlIGlubGluZVxuICAvLyBzdGVwcycgY2xhaW1zIGluY2x1ZGVkIOKAlCBjb21taXRzIGluIHRoZSBvbmUgZHVyYWJsZSB3cml0ZSBhbmQgdGhlIGNhbGxlclxuICAvLyBzdGFydHMgdGhlIGJvZGllcyBzdHJhaWdodCBvZmYgdGhhdCBjb21taXQgaW5zdGVhZCBvZiBwb3N0aW5nIG9uZSBjbGFpbVxuICAvLyBwZXIgaW5saW5lIHN0ZXAuIFRoZSBsb25lLWlubGluZSBjYXNlIChub3RoaW5nIGVsc2UgdG8gYmF0Y2ggd2l0aCkgaXNcbiAgLy8gZXhjbHVkZWQ6IGEgcGFpci1vbmx5IGJhdGNoIGNvc3RzIHRoZSBzYW1lIHJvdW5kIHRyaXAgYXMgdGhlIHNpbmdsZSBsYXp5XG4gIC8vIGNsYWltIHdoaWxlIGdpdmluZyB1cCB0aGUgb3B0aW1pc3RpYyBjbGFpbS9ib2R5IG92ZXJsYXAgYW5kIHRoZVxuICAvLyBidW1wLWFuZC1yZXBvcnQgdGhhdCBgY3JlYXRlR3VhcmRlZGAgcHJvdmlkZXMsIHNvIGl0IHN0YXlzIG9uIHRoZSBsYXp5XG4gIC8vIHBhdGguIFJlcXVpcmVzIHRoZSBjYWxsZXIncyBgb3duZXJNZXNzYWdlSWRgIOKAlCB0aGUgc3RhcnRlZCByb3cgbXVzdFxuICAvLyBzdGFtcCBvd25lcnNoaXAgZXhhY3RseSBsaWtlIHRoZSBsYXp5IGNsYWltIGl0IHJlcGxhY2VzIChhbmQgYSBjYWxsZXJcbiAgLy8gdGhhdCBkb2VzIG5vdCBpbmxpbmUtZXhlY3V0ZSBuZXZlciBwcm92aWRlcyBvbmUpLlxuICBjb25zdCB1bmNyZWF0ZWRXYWl0Q291bnQgPSB3YWl0SXRlbXMuZmlsdGVyKFxuICAgIChpdGVtKSA9PiAhaXRlbS5oYXNDcmVhdGVkRXZlbnRcbiAgKS5sZW5ndGg7XG4gIGNvbnN0IGlubGluZVBhaXJGb2xkRWxpZ2libGUgPVxuICAgIGJhdGNoRmFub3V0RWxpZ2libGUgJiZcbiAgICBvd25lck1lc3NhZ2VJZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgbGF6eUlubGluZUNvcnJlbGF0aW9uSWRzLnNpemUgPiAwICYmXG4gICAgKGxhenlJbmxpbmVDb3JyZWxhdGlvbklkcy5zaXplID49IDIgfHxcbiAgICAgIHN0ZXBzTmVlZGluZ0NyZWF0aW9uLnNpemUgLVxuICAgICAgICBsYXp5SW5saW5lQ29ycmVsYXRpb25JZHMuc2l6ZSArXG4gICAgICAgIHVuY3JlYXRlZFdhaXRDb3VudCA+PVxuICAgICAgICAxKTtcbiAgY29uc3QgaW5saW5lQ2xhaW1zOiBTdXNwZW5zaW9uSGFuZGxlclJlc3VsdFsnaW5saW5lQ2xhaW1zJ10gPSBuZXcgTWFwKCk7XG4gIGxldCBiYXRjaENvbW1pdHRlZFNsb3RDZWlsaW5nOiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgLy8gVGhlIHRyYWNlIGNhcnJpZXIgZm9yIHJlc2lsaWVudCBzdGVwIGRpc3BhdGNoZXMsIHJlc29sdmVkIGF0IG1vc3Qgb25jZSBwZXJcbiAgLy8gc3VzcGVuc2lvbiAodGhlIHBlci1zdGVwIG9wcyBydW4gY29uY3VycmVudGx5IGFuZCBzaGFyZSBpdCkuXG4gIGxldCBzdGVwRGlzcGF0Y2hUcmFjZUNhcnJpZXI6IFByb21pc2U8VHJhY2VDYXJyaWVyPiB8IHVuZGVmaW5lZDtcbiAgY29uc3QgZ2V0U3RlcERpc3BhdGNoVHJhY2VDYXJyaWVyID0gKCk6IFByb21pc2U8VHJhY2VDYXJyaWVyPiA9PiB7XG4gICAgc3RlcERpc3BhdGNoVHJhY2VDYXJyaWVyID8/PVxuICAgICAgc3RlcERpc3BhdGNoPy5nZXRUcmFjZUNhcnJpZXIoKSA/PyBQcm9taXNlLnJlc29sdmUoe30pO1xuICAgIHJldHVybiBzdGVwRGlzcGF0Y2hUcmFjZUNhcnJpZXI7XG4gIH07XG5cbiAgLy8gUHJvZHVjZXItc2lkZSByZXNpbGllbnQgcmVjb3ZlcnkgY291bnQgZm9yIHRoZSBzdXNwZW5zaW9uIHNwYW4gYXR0cmlidXRlLlxuICBsZXQgcmVzaWxpZW50RGlzcGF0Y2hSZWNvdmVyZWQgPSAwO1xuXG4gIC8vIFN0ZXBzOiBjcmVhdGUgc3RlcF9jcmVhdGVkIGV2ZW50cyAobm8gcXVldWluZyDigJQgVjIgcmV0dXJucyBwZW5kaW5nIHN0ZXBzXG4gIC8vIHRvIGNhbGxlciDigJQgRVhDRVBUIG9uIHRoZSByZXNpbGllbnQgZGlzcGF0Y2ggcGF0aCwgd2hpY2ggcGFyYWxsZWxpemVzIHRoZVxuICAvLyBjcmVhdGUgd2l0aCB0aGUgc3RlcCdzIHF1ZXVlIHB1Ymxpc2ggYW5kIHJlcG9ydHMgaXQgaW5cbiAgLy8gYHF1ZXVlZFN0ZXBDb3JyZWxhdGlvbklkc2ApLlxuICBsZXQgYmF0Y2hPcmRlckNvdW50ZXIgPSAwO1xuICBmb3IgKGNvbnN0IHF1ZXVlSXRlbSBvZiBzdGVwSXRlbXMpIHtcbiAgICBpZiAoc3RlcHNOZWVkaW5nQ3JlYXRpb24uaGFzKHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkKSkge1xuICAgICAgLy8gRGV0ZXJtaW5pc3RpYyBwb3NpdGlvbiBpbiB0aGUgYmF0Y2hlZCBmb2xkIChhc3NpZ25lZCBpbiBzdGVwSXRlbXNcbiAgICAgIC8vIG9yZGVyLCBiZWZvcmUgdGhlIGNvbmN1cnJlbnQgZGVoeWRyYXRpb24gcnVucykuIEEgcGFpci1mb2xkZWQgaW5saW5lXG4gICAgICAvLyBzdGVwIG9jY3VwaWVzIHR3byBjb25zZWN1dGl2ZSBwb3NpdGlvbnMg4oCUIGNyZWF0ZWQgcm93IHRoZW4gc3RhcnRlZFxuICAgICAgLy8gcm93IOKAlCB3aGljaCB0aGUgZmx1c2gga2VlcHMgYWRqYWNlbnQgYW5kIG5ldmVyIHNwbGl0cyBhY3Jvc3MgY2h1bmtzLFxuICAgICAgLy8gc28gYSBXb3JsZCBjYW4gZm9sZCB0aGVtIGludG8gb25lIGJvcm4tcnVubmluZyBjcmVhdGUuXG4gICAgICBjb25zdCBwYWlyRm9sZGVkID1cbiAgICAgICAgaW5saW5lUGFpckZvbGRFbGlnaWJsZSAmJlxuICAgICAgICBsYXp5SW5saW5lQ29ycmVsYXRpb25JZHMuaGFzKHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkKTtcbiAgICAgIGNvbnN0IHN0ZXBPcmRlciA9IGJhdGNoT3JkZXJDb3VudGVyO1xuICAgICAgYmF0Y2hPcmRlckNvdW50ZXIgKz0gcGFpckZvbGRlZCA/IDIgOiAxO1xuICAgICAgY29uc3Qgc3RlcE9wID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gUGVyLXN0ZXAgc2luaywgbWVyZ2VkIGJlbG93OiB0aGUgZGVoeWRyYXRlIHdyYXBwZXIgZW1pdHMgc3BhblxuICAgICAgICAvLyBhdHRyaWJ1dGVzIGZyb20gdGhlIHNpbmsgaXQgaXMgaGFuZGVkLCBzbyBzaGFyaW5nIG9uZSBhY3Jvc3NcbiAgICAgICAgLy8gc3RlcHMgd291bGQgcmUtZW1pdCAoYW5kIG1pc2F0dHJpYnV0ZSkgZWFybGllciBzdGVwcycgZW50cmllcy5cbiAgICAgICAgY29uc3Qgc3RlcEd1ZXN0Q29kZTogR3Vlc3RDb2RlU3RhdHMgPSB7IGV4ZWN1dGlvbnM6IFtdIH07XG4gICAgICAgIGNvbnN0IGRlaHlkcmF0ZWRJbnB1dCA9IGF3YWl0IGRlaHlkcmF0ZVN0ZXBBcmd1bWVudHMoXG4gICAgICAgICAge1xuICAgICAgICAgICAgYXJnczogcXVldWVJdGVtLmFyZ3MsXG4gICAgICAgICAgICBjbG9zdXJlVmFyczogcXVldWVJdGVtLmNsb3N1cmVWYXJzLFxuICAgICAgICAgICAgdGhpc1ZhbDogcXVldWVJdGVtLnRoaXNWYWwsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBydW5JZCxcbiAgICAgICAgICBlbmNyeXB0aW9uS2V5LFxuICAgICAgICAgIHN1c3BlbnNpb24uZ2xvYmFsVGhpcyxcbiAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICBjb21wcmVzc2lvbixcbiAgICAgICAgICBzdGVwR3Vlc3RDb2RlXG4gICAgICAgICk7XG4gICAgICAgIGd1ZXN0Q29kZVN0YXRzLmV4ZWN1dGlvbnMucHVzaCguLi5zdGVwR3Vlc3RDb2RlLmV4ZWN1dGlvbnMpO1xuICAgICAgICAvLyBEZWZlcnJlZCAobGF6eSkgaW5saW5lIHN0ZXA6IHNraXAgdGhlIHN0ZXBfY3JlYXRlZCB3cml0ZSDigJQgdGhlXG4gICAgICAgIC8vIGNhbGxlcidzIGlubGluZSBleGVjdXRlU3RlcCB3aWxsIHNlbmQgYSBsYXp5IHN0ZXBfc3RhcnRlZCBjYXJyeWluZ1xuICAgICAgICAvLyB0aGlzIGlucHV0LCBhbmQgdGhlIHdvcmxkIGNyZWF0ZXMgdGhlIHN0ZXAgKGVudGl0eSArIHN5bnRoZXRpY1xuICAgICAgICAvLyBzdGVwX2NyZWF0ZWQgZXZlbnQpIGF0b21pY2FsbHkuIFdlIGRvIE5PVCBhZGQgaXQgdG9cbiAgICAgICAgLy8gY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkczsgb3duZXJzaGlwIGlzIGRlY2lkZWQgYnkgdGhhdCBsYXp5XG4gICAgICAgIC8vIHN0ZXBfc3RhcnRlZCdzIGF0b21pYyBjcmVhdGUtY2xhaW0gaW5zdGVhZC5cbiAgICAgICAgaWYgKGxhenlJbmxpbmVDb3JyZWxhdGlvbklkcy5oYXMocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQpKSB7XG4gICAgICAgICAgbGF6eUlubGluZUJ5Q29ycmVsYXRpb25JZC5zZXQocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsIHtcbiAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgc3RlcE5hbWU6IHF1ZXVlSXRlbS5zdGVwTmFtZSxcbiAgICAgICAgICAgIGRlaHlkcmF0ZWRJbnB1dDogZGVoeWRyYXRlZElucHV0IGFzIFNlcmlhbGl6ZWREYXRhLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChwYWlyRm9sZGVkKSB7XG4gICAgICAgICAgICAvLyBFbnF1ZXVlIHRoZSBwYWlyIHRoZSBkZWZlcnJhbCB3b3VsZCBvdGhlcndpc2UgbGVhdmUgdG8gdGhlXG4gICAgICAgICAgICAvLyBjYWxsZXIncyBsYXp5IGBzdGVwX3N0YXJ0ZWRgOiB0aGUgY3JlYXRlZCByb3cgY2FycmllcyB0aGVcbiAgICAgICAgICAgIC8vIGlucHV0IChwYXlsb2FkcyByaWRlIGNyZWF0ZXMgaW4gYSBiYXRjaCksIHRoZSBzdGFydGVkIHJvdyBpc1xuICAgICAgICAgICAgLy8gYmFyZSBhbmQgc3RhbXBzIHRoaXMgaW52b2NhdGlvbidzIG93bmVyc2hpcCDigJQgdGhlIHNhbWUgY2xhaW1cbiAgICAgICAgICAgIC8vIHNoYXBlIHRoZSBsYXp5IHN0YXJ0IHdvdWxkIGhhdmUgc2VudCwgc2V0dGxlZCBieSB0aGUgYmF0Y2guXG4gICAgICAgICAgICBiYXRjaFF1ZXVlLnB1c2goe1xuICAgICAgICAgICAgICBvcmRlcjogc3RlcE9yZGVyLFxuICAgICAgICAgICAgICBraW5kOiAnaW5saW5lLWNyZWF0ZWQnLFxuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgZXZlbnQ6IHtcbiAgICAgICAgICAgICAgICBldmVudFR5cGU6ICdzdGVwX2NyZWF0ZWQnLFxuICAgICAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICAgICAgICB3b3JrZmxvd05hbWU6IHJ1bi53b3JrZmxvd05hbWUsXG4gICAgICAgICAgICAgICAgICBpbnB1dDogZGVoeWRyYXRlZElucHV0IGFzIFNlcmlhbGl6ZWREYXRhLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGJhdGNoUXVldWUucHVzaCh7XG4gICAgICAgICAgICAgIG9yZGVyOiBzdGVwT3JkZXIgKyAxLFxuICAgICAgICAgICAgICBraW5kOiAnaW5saW5lLXN0YXJ0ZWQnLFxuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgZXZlbnQ6IHtcbiAgICAgICAgICAgICAgICBldmVudFR5cGU6ICdzdGVwX3N0YXJ0ZWQnLFxuICAgICAgICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICAgICAgICAvLyBDaGVja2VkIGJ5IGlubGluZVBhaXJGb2xkRWxpZ2libGU7IHNwcmVhZCBrZWVwcyB0aGVcbiAgICAgICAgICAgICAgICAgIC8vIG5hcnJvdy10aHJvdWdoLWNsb3N1cmUgcHJvYmxlbSBhd2F5IGZyb20gdGhlIHR5cGUuXG4gICAgICAgICAgICAgICAgICAuLi4ob3duZXJNZXNzYWdlSWQgIT09IHVuZGVmaW5lZCA/IHsgb3duZXJNZXNzYWdlSWQgfSA6IHt9KSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzdGVwRXZlbnQ6IENyZWF0ZUV2ZW50UmVxdWVzdCA9IHtcbiAgICAgICAgICBldmVudFR5cGU6ICdzdGVwX2NyZWF0ZWQnIGFzIGNvbnN0LFxuICAgICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICB3b3JrZmxvd05hbWU6IHJ1bi53b3JrZmxvd05hbWUsXG4gICAgICAgICAgICBpbnB1dDogZGVoeWRyYXRlZElucHV0IGFzIFNlcmlhbGl6ZWREYXRhLFxuICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmVzaWxpZW50IHN0ZXAgZGlzcGF0Y2g6IGZpcmUgdGhlIHN0ZXBfY3JlYXRlZCB3cml0ZSBhbmQgdGhlXG4gICAgICAgIC8vIHN0ZXAtZXhlY3V0aW9uIHF1ZXVlIHB1Ymxpc2ggaW4gcGFyYWxsZWwg4oCUIHRoZSBtZXNzYWdlIGNhcnJpZXMgdGhlXG4gICAgICAgIC8vIHNhbWUgc2VyaWFsaXplZCBpbnB1dCAoYHN0ZXBJbnB1dGApIHNvIHRoZSBjb25zdW1lciBjYW5cbiAgICAgICAgLy8gaWRlbXBvdGVudGx5IHJlLWVuc3VyZSB0aGUgZXZlbnQgaWYgdGhlIGRpcmVjdCB3cml0ZSBmYWlsZWRcbiAgICAgICAgLy8gdHJhbnNpZW50bHkuIE1pcnJvcnMgdGhlIHJlc2lsaWVudCBzdGFydCAoYHJ1bklucHV0YCkgYW5kXG4gICAgICAgIC8vIHJlc2lsaWVudCBob29rIHJlc3VtZSAoYGhvb2tJbnB1dGApIHBhdHRlcm5zLiBPbmx5IGZvciBpbnB1dHMgdGhlXG4gICAgICAgIC8vIHF1ZXVlIG1lc3NhZ2UgY2FuIHNhZmVseSBjYXJyeSAoYmluYXJ5LCB1bmRlciB0aGUgVlFTIHNpemUgY2FwKS5cbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlc2lsaWVudERpc3BhdGNoRWxpZ2libGUgJiZcbiAgICAgICAgICBkZWh5ZHJhdGVkSW5wdXQgaW5zdGFuY2VvZiBVaW50OEFycmF5ICYmXG4gICAgICAgICAgZGVoeWRyYXRlZElucHV0LmJ5dGVMZW5ndGggPD0gTUFYX1JFU0lMSUVOVF9TVEVQX0lOUFVUX0JZVEVTXG4gICAgICAgICkge1xuICAgICAgICAgIGF3YWl0IGVuc3VyZVJ1blJlYWR5KCk7XG4gICAgICAgICAgY29uc3QgdHJhY2VDYXJyaWVyID0gYXdhaXQgZ2V0U3RlcERpc3BhdGNoVHJhY2VDYXJyaWVyKCk7XG4gICAgICAgICAgY29uc3QgW2NyZWF0ZVJlc3VsdCwgcXVldWVSZXN1bHRdID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgICAgICAgIGNyZWF0ZUd1YXJkZWQoc3RlcEV2ZW50LCB7IHJlcXVlc3RJZCB9KSxcbiAgICAgICAgICAgIHF1ZXVlTWVzc2FnZShcbiAgICAgICAgICAgICAgd29ybGQsXG4gICAgICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N0eWxlL25vTm9uTnVsbEFzc2VydGlvbjogaW1wbGllZCBieSByZXNpbGllbnREaXNwYXRjaEVsaWdpYmxlXG4gICAgICAgICAgICAgIHN0ZXBEaXNwYXRjaCEucXVldWVOYW1lLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICAgICAgc3RlcElkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICBzdGVwTmFtZTogcXVldWVJdGVtLnN0ZXBOYW1lLFxuICAgICAgICAgICAgICAgIHRyYWNlQ2FycmllcixcbiAgICAgICAgICAgICAgICByZXF1ZXN0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICAgICAgICBzdGVwSW5wdXQ6IHsgaW5wdXQ6IGRlaHlkcmF0ZWRJbnB1dCB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAvLyBTYW1lIGtleSBhcyB0aGUgY2FsbGVyJ3MgZGlzcGF0Y2ggcGFzcyBhbmQgYW55IGNvbmN1cnJlbnRcbiAgICAgICAgICAgICAgLy8gaGFuZGxlcidzIOKAlCByZWR1bmRhbnQgcHVibGlzaGVzIGZvciB0aGlzIHN0ZXAgZGVkdXBlLiBUaGVcbiAgICAgICAgICAgICAgLy8ga2V5IGlzIHN0ZXAtaWRlbnRpdHktc2NvcGVkIHNvIGEgcmV2b2tlZCBtZXNzYWdlIGZvciBhXG4gICAgICAgICAgICAgIC8vIHJlYXNzaWduZWQgY29ycmVsYXRpb24gaWQgY2Fubm90IGFic29yYiB0aGUgY29ycmVjdGVkXG4gICAgICAgICAgICAgIC8vIHNjaGVkdWxlJ3MgZGlzcGF0Y2gg4oCUIHNlZSBzdGVwRGlzcGF0Y2hJZGVtcG90ZW5jeUtleS5cbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlkZW1wb3RlbmN5S2V5OiBzdGVwRGlzcGF0Y2hJZGVtcG90ZW5jeUtleShcbiAgICAgICAgICAgICAgICAgIHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgICAgcXVldWVJdGVtLnN0ZXBOYW1lXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICBdKTtcbiAgICAgICAgICAvLyBRdWV1ZSBmYWlsdXJlIGlzIGFsd2F5cyBmYXRhbCBmb3IgdGhpcyBzdXNwZW5zaW9uIHBhc3M6IHdpdGhvdXRcbiAgICAgICAgICAvLyB0aGUgbWVzc2FnZSB0aGUgc3RlcCB3b3VsZCByZWx5IG9uIHRoZSBjcmVhdGUgYWxvbmUsIGFuZCBpZiB0aGVcbiAgICAgICAgICAvLyBjcmVhdGUgQUxTTyBmYWlsZWQgdGhlcmUgd291bGQgYmUgbm8gZHVyYWJsZSByZWNvcmQgYXQgYWxsLlxuICAgICAgICAgIC8vIFByb3BhZ2F0aW5nIHJlZGVsaXZlcnMgdGhlIG9yY2hlc3RyYXRvciBtZXNzYWdlLCB3aGljaFxuICAgICAgICAgIC8vIHJlLWNyZWF0ZXMgdGhlIChpZGVtcG90ZW50KSBzdGVwX2NyZWF0ZWQgYW5kIHJlLWRpc3BhdGNoZXMg4oCUXG4gICAgICAgICAgLy8gdGhlIHNhbWUgcmVjb3ZlcnkgYXMgdGhlIHNlcXVlbnRpYWwgcGF0aC5cbiAgICAgICAgICBpZiAocXVldWVSZXN1bHQuc3RhdHVzID09PSAncmVqZWN0ZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBxdWV1ZVJlc3VsdC5yZWFzb247XG4gICAgICAgICAgfVxuICAgICAgICAgIHF1ZXVlZFN0ZXBDb3JyZWxhdGlvbklkcy5hZGQocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQpO1xuICAgICAgICAgIGlmIChjcmVhdGVSZXN1bHQuc3RhdHVzID09PSAncmVqZWN0ZWQnKSB7XG4gICAgICAgICAgICBjb25zdCBlcnIgPSBjcmVhdGVSZXN1bHQucmVhc29uO1xuICAgICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgICAvLyBDb25jdXJyZW50IGhhbmRsZXIgd3JvdGUgaXQgZmlyc3Qg4oCUIHNhbWUgYXMgdGhlIHNlcXVlbnRpYWxcbiAgICAgICAgICAgICAgLy8gcGF0aC4gVGhlIHN0ZXAgbWVzc2FnZSBpcyBhbHJlYWR5IG91dDsgYSBkdXBsaWNhdGUgcHVibGlzaFxuICAgICAgICAgICAgICAvLyBieSB0aGF0IGhhbmRsZXIgZGVkdXBlcyBvbiB0aGUgc2hhcmVkIGlkZW1wb3RlbmN5IGtleS5cbiAgICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKCdTdGVwIGFscmVhZHkgZXhpc3RzLCBjb250aW51aW5nJywge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaXNSZXRyeWFibGVXb3JsZEVycm9yKGVycikpIHtcbiAgICAgICAgICAgICAgLy8gUmVzaWxpZW50OiB0aGUgd3JpdGUgZmFpbGVkIHRyYW5zaWVudGx5ICg0MjkgLyA1eHggL1xuICAgICAgICAgICAgICAvLyB0cmFuc3BvcnQpIGJ1dCB0aGUgc3RlcCBtZXNzYWdlIOKAlCBjYXJyeWluZyB0aGUgc2FtZVxuICAgICAgICAgICAgICAvLyBzZXJpYWxpemVkIGlucHV0IOKAlCB3YXMgcHVibGlzaGVkLCBzbyB0aGUgY29uc3VtZXJcbiAgICAgICAgICAgICAgLy8gaWRlbXBvdGVudGx5IHJlLWVuc3VyZXMgdGhlIHN0ZXBfY3JlYXRlZCBiZWZvcmUgZXhlY3V0aW5nLlxuICAgICAgICAgICAgICByZXNpbGllbnREaXNwYXRjaFJlY292ZXJlZCsrO1xuICAgICAgICAgICAgICBydW50aW1lTG9nZ2VyLndhcm4oXG4gICAgICAgICAgICAgICAgJ1N0ZXAgY3JlYXRpb24gZXZlbnQgd3JpdGUgZmFpbGVkLCBidXQgdGhlIHN0ZXAgd2FzICcgK1xuICAgICAgICAgICAgICAgICAgJ2Rpc3BhdGNoZWQgdmlhIHRoZSBxdWV1ZS4gVGhlIHN0ZXBfY3JlYXRlZCBldmVudCB3aWxsICcgK1xuICAgICAgICAgICAgICAgICAgJ2JlIGVuc3VyZWQgYnkgdGhlIHF1ZXVlIGNvbnN1bWVyLicsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkcy5hZGQocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYmF0Y2hGYW5vdXRFbGlnaWJsZSkge1xuICAgICAgICAgIC8vIEZvbGQgaW50byB0aGUgYmF0Y2ggaW5zdGVhZCBvZiB3cml0aW5nIGhlcmUuIFRoZSBlbmNsb3NpbmdcbiAgICAgICAgICAvLyBwcm9taXNlIGpvaW5zIGBiYXRjaFByZXBzYCAoc2VlIHRoZSBsb29wIGJlbG93KSwgc28gdGhlIGZsdXNoXG4gICAgICAgICAgLy8gb3AgY2Fubm90IHJ1biBiZWZvcmUgdGhpcyBzdGVwJ3MgaW5wdXQgZmluaXNoZWQgZGVoeWRyYXRpbmcuXG4gICAgICAgICAgYmF0Y2hRdWV1ZS5wdXNoKHtcbiAgICAgICAgICAgIG9yZGVyOiBzdGVwT3JkZXIsXG4gICAgICAgICAgICBraW5kOiAnc3RlcCcsXG4gICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgIHN0ZXBOYW1lOiBxdWV1ZUl0ZW0uc3RlcE5hbWUsXG4gICAgICAgICAgICBldmVudDogc3RlcEV2ZW50LFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZW5zdXJlUnVuUmVhZHkoKTtcbiAgICAgICAgICBhd2FpdCBjcmVhdGVHdWFyZGVkKHN0ZXBFdmVudCwgeyByZXF1ZXN0SWQgfSk7XG4gICAgICAgICAgY3JlYXRlZFN0ZXBDb3JyZWxhdGlvbklkcy5hZGQocXVldWVJdGVtLmNvcnJlbGF0aW9uSWQpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBpZiAoRW50aXR5Q29uZmxpY3RFcnJvci5pcyhlcnIpKSB7XG4gICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oJ1N0ZXAgYWxyZWFkeSBleGlzdHMsIGNvbnRpbnVpbmcnLCB7XG4gICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSkoKTtcbiAgICAgIG9wcy5wdXNoKHN0ZXBPcCk7XG4gICAgICBpZiAoYmF0Y2hGYW5vdXRFbGlnaWJsZSkge1xuICAgICAgICAvLyBUaGUgZmx1c2ggb3Agd2FpdHMgZm9yIGV2ZXJ5IHByZXAgYmVmb3JlIGNvbW1pdHRpbmc7IGEgcHJlcCB0aGF0XG4gICAgICAgIC8vIHJlamVjdGVkIGFscmVhZHkgc3VyZmFjZXMgdGhyb3VnaCBgb3BzYCwgc28gdGhlIGZsdXNoJ3Mgb3duIHdhaXRcbiAgICAgICAgLy8gc3dhbGxvd3MgaXQgYW5kIGNvbW1pdHMgd2hhdGV2ZXIgd2FzIHN1Y2Nlc3NmdWxseSBlbnF1ZXVlZCDigJRcbiAgICAgICAgLy8gcHJlc2VydmluZyB0b2RheSdzIHBlci1vcCBpbmRlcGVuZGVuY2UuXG4gICAgICAgIGJhdGNoUHJlcHMucHVzaChzdGVwT3AuY2F0Y2goKCkgPT4ge30pKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBDcmVhdGUgd2FpdCBldmVudHMgKHNhbWUgYXMgVjEpXG4gIGZvciAoY29uc3QgcXVldWVJdGVtIG9mIHdhaXRJdGVtcykge1xuICAgIGlmICghcXVldWVJdGVtLmhhc0NyZWF0ZWRFdmVudCkge1xuICAgICAgY29uc3Qgd2FpdEV2ZW50OiBDcmVhdGVFdmVudFJlcXVlc3QgPSB7XG4gICAgICAgIGV2ZW50VHlwZTogJ3dhaXRfY3JlYXRlZCcgYXMgY29uc3QsXG4gICAgICAgIHNwZWNWZXJzaW9uOiBTUEVDX1ZFUlNJT05fQ1VSUkVOVCxcbiAgICAgICAgY29ycmVsYXRpb25JZDogcXVldWVJdGVtLmNvcnJlbGF0aW9uSWQsXG4gICAgICAgIGV2ZW50RGF0YToge1xuICAgICAgICAgIHJlc3VtZUF0OiBxdWV1ZUl0ZW0ucmVzdW1lQXQsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgaWYgKGJhdGNoRmFub3V0RWxpZ2libGUpIHtcbiAgICAgICAgLy8gV2FpdHMgbmVlZCBubyBkZWh5ZHJhdGlvbiwgc28gdGhleSBlbnF1ZXVlIHN5bmNocm9ub3VzbHkg4oCUIGFmdGVyXG4gICAgICAgIC8vIGV2ZXJ5IHN0ZXAncyBvcmRlciBzbG90LCBwcmVzZXJ2aW5nIHN0ZXBzLXRoZW4td2FpdHMgc2NoZWR1bGluZ1xuICAgICAgICAvLyBvcmRlciBpbiB0aGUgbG9nLlxuICAgICAgICBiYXRjaFF1ZXVlLnB1c2goe1xuICAgICAgICAgIG9yZGVyOiBiYXRjaE9yZGVyQ291bnRlcisrLFxuICAgICAgICAgIGtpbmQ6ICd3YWl0JyxcbiAgICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgICAgICBldmVudDogd2FpdEV2ZW50LFxuICAgICAgICB9KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBvcHMucHVzaChcbiAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgZW5zdXJlUnVuUmVhZHkoKTtcbiAgICAgICAgICAgIGF3YWl0IGNyZWF0ZUd1YXJkZWQod2FpdEV2ZW50LCB7IHJlcXVlc3RJZCB9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGlmIChFbnRpdHlDb25mbGljdEVycm9yLmlzKGVycikpIHtcbiAgICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKCdXYWl0IGFscmVhZHkgZXhpc3RzLCBjb250aW51aW5nJywge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pKClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLy8gVGhlIGJhdGNoZWQgZm9sZCdzIGZsdXNoOiB0aGUgY2xlYW4gZmFuLW91dCBjb21taXRzIHRocm91Z2hcbiAgLy8gYGNyZWF0ZUJhdGNoYCBpbiBjaHVua3Mgb2YgTUFYX0JBVENIX0ZBTk9VVF9FVkVOVFMg4oCUIGFsbCBjaHVua3MgSU5cbiAgLy8gRkxJR0hUIENPTkNVUlJFTlRMWS4gU2xvdCBhc3NpZ25tZW50IGlzIHRoZSBzZXJ2ZXIncywgc28gcGFyYWxsZWxcbiAgLy8gY2h1bmtzIHJhY2UgZm9yIHNsb3QgcmFuZ2VzIGV4YWN0bHkgbGlrZSB0aGUgcHJlLWZvbGQgcGF0aCdzIHBhcmFsbGVsXG4gIC8vIHNpbmdsZSB3cml0ZXMgZGlkOyBlbnRpdHkgY29uZGl0aW9ucywgbm90IGNvbW1pdCBvcmRlciwgY2FycnlcbiAgLy8gY29ycmVjdG5lc3MgKHNpYmxpbmcgZmFuLW91dCBldmVudHMgaGF2ZSBubyBjcm9zcy1vcmRlciB0aGUgcmVwbGF5XG4gIC8vIGRlcGVuZHMgb24g4oCUIGl0IG1hdGNoZXMgYnkgY29ycmVsYXRpb24gaWQpLiBFYWNoIGV2ZW50IHJlcG9ydHMgdGhlXG4gIC8vIG91dGNvbWUgaXRzIG93biBzaW5nbGUgY3JlYXRlIHdvdWxkIGhhdmUgaGFkOiBhIDQwOSBpcyB0aGUgc2FtZVxuICAvLyBhbHJlYWR5LWV4aXN0cyB0b2xlcmFuY2UgYXMgdGhlIHNpbmdsZSBwYXRoLCBhbnl0aGluZyBlbHNlIGZhaWxzIHRoZVxuICAvLyBkZWxpdmVyeSB0aGUgd2F5IGEgc2luZ2xlLXBhdGggcmVqZWN0aW9uIHdvdWxkLlxuICAvL1xuICAvLyBMYXRlbmN5IHNoYXBlOiBvbmx5IHRoZSBjaHVuayBjYXJyeWluZyB0aGUgcHJlLWNsYWltZWQgaW5saW5lIHBhaXJzXG4gIC8vIGdhdGVzIHRoZSBoYW5kbGVyJ3MgcmV0dXJuICh0aGUgY2FsbGVyIHN0YXJ0cyBib2RpZXMgb2ZmIGl0cyBjbGFpbXMpLlxuICAvLyBFdmVyeSBvdGhlciBjaHVuaydzIGNvbW1pdCDigJQgYW5kIGV2ZXJ5IGNodW5rJ3Mgc3RlcC1tZXNzYWdlIHB1Ymxpc2hlcyxcbiAgLy8gd2hpY2ggZmlyZSB0aGUgbW9tZW50IElUUyBjcmVhdGVzIGFyZSBkdXJhYmxlIOKAlCByaWRlc1xuICAvLyBgZGVmZXJyZWRCYXRjaFdvcmtgIHdoZW4gdGhlIGNhbGxlciBvcHRlZCBpbiwgam9pbmVkIGJlZm9yZSBhY2suIEEgc2xvd1xuICAvLyBzaWJsaW5nIGNodW5rIHRoZXJlZm9yZSBkZWxheXMgbmVpdGhlciB0aGUgaW5saW5lIGJvZGllcyBub3IgYW5vdGhlclxuICAvLyBjaHVuaydzIHF1ZXVlIG1lc3NhZ2VzLCB3aGlsZSBwdWJsaXNoLWFmdGVyLWNyZWF0ZSBzdGlsbCBob2xkcyBwZXJcbiAgLy8gc3RlcDogYSBzdGVwJ3MgbWVzc2FnZSBpcyBvbmx5IGV2ZXIgc2VudCBhZnRlciB0aGUgY2h1bmsgY2FycnlpbmcgaXRzXG4gIC8vIGNyZWF0ZSBoYXMgY29tbWl0dGVkLlxuICBsZXQgZGVmZXJyZWRCYXRjaFdvcms6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gIGlmIChiYXRjaEZhbm91dEVsaWdpYmxlKSB7XG4gICAgb3BzLnB1c2goXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAvLyBQcmVwcyB0aGF0IHJlamVjdGVkIGFscmVhZHkgc3VyZmFjZSB0aHJvdWdoIHRoZWlyIG93biBgb3BzYFxuICAgICAgICAvLyBlbnRyaWVzOyB0aGUgZm9sZCBjb21taXRzIHdoYXRldmVyIHdhcyBzdWNjZXNzZnVsbHkgZW5xdWV1ZWQsXG4gICAgICAgIC8vIHByZXNlcnZpbmcgdG9kYXkncyBwZXItb3AgaW5kZXBlbmRlbmNlLlxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChiYXRjaFByZXBzKTtcbiAgICAgICAgaWYgKGJhdGNoUXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVudHJpZXMgPSBbLi4uYmF0Y2hRdWV1ZV0uc29ydCgoYSwgYikgPT4gYS5vcmRlciAtIGIub3JkZXIpO1xuICAgICAgICBhd2FpdCBlbnN1cmVSdW5SZWFkeSgpO1xuICAgICAgICAvLyBBIGJhdGNoIG9mIE9ORSBnYWlucyBub3RoaW5nIG92ZXIgdGhlIHNpbmdsZSB3cml0ZSAoc2FtZSByb3VuZFxuICAgICAgICAvLyB0cmlwKSBhbmQgbG9zZXMgdGhlIHNsb3Qtc25hcHNob3QgcGFyYW1zICsgYnVtcC1hbmQtcmVwb3J0IHRoYXRcbiAgICAgICAgLy8gY3JlYXRlR3VhcmRlZCBwcm92aWRlcyDigJQgc28gYSBsb25lIGVhZ2VyIGV2ZW50IHRha2VzIHRoZSBvcmRpbmFyeVxuICAgICAgICAvLyBzaW5nbGUgcGF0aCwgd2l0aCB0aGUgc2FtZSBjb25mbGljdCB0b2xlcmFuY2UgYW5kIG93bmVyc2hpcFxuICAgICAgICAvLyBib29ra2VlcGluZyBpdCB3b3VsZCBoYXZlIGhhZCB3aXRob3V0IHRoZSBmb2xkLlxuICAgICAgICBpZiAoZW50cmllcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICBjb25zdCBbZW50cnldID0gZW50cmllcztcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgYXdhaXQgY3JlYXRlR3VhcmRlZChlbnRyeS5ldmVudCwgeyByZXF1ZXN0SWQgfSk7XG4gICAgICAgICAgICBpZiAoZW50cnkua2luZCA9PT0gJ3N0ZXAnKSB7XG4gICAgICAgICAgICAgIGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHMuYWRkKGVudHJ5LmNvcnJlbGF0aW9uSWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgICBydW50aW1lTG9nZ2VyLmluZm8oXG4gICAgICAgICAgICAgICAgZW50cnkua2luZCA9PT0gJ3N0ZXAnXG4gICAgICAgICAgICAgICAgICA/ICdTdGVwIGFscmVhZHkgZXhpc3RzLCBjb250aW51aW5nJ1xuICAgICAgICAgICAgICAgICAgOiAnV2FpdCBhbHJlYWR5IGV4aXN0cywgY29udGludWluZycsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbklkOiBlbnRyeS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gU2VlZCBmb3IgdGhlIGZvcmVpZ24taW50ZXJsZWF2aW5nIGRpYWdub3N0aWMgYmVsb3cuIFdpdGggY2h1bmtzXG4gICAgICAgIC8vIGNvbW1pdHRpbmcgaW4gcGFyYWxsZWwgdGhlcmUgaXMgbm8gcGVyLWNodW5rIFwiZXhwZWN0ZWQgbmV4dCBzbG90XCJcbiAgICAgICAgLy8g4oCUIHRoZSB3aG9sZSBmb2xkJ3MgY29tbWl0dGVkIHNwYW4gaXMgY29tcGFyZWQgYWdhaW5zdCB0aGUgc2VlZFxuICAgICAgICAvLyBvbmNlIGV2ZXJ5IGNodW5rIGhhcyBzZXR0bGVkOiBjb21taXR0ZWQgc2xvdHMgYXJlIGRlbnNlIHBlciB0aGVcbiAgICAgICAgLy8gV29ybGQncyBpbnZhcmlhbnQsIHNvIGFueSBleGNlc3Mgb2YgKG1heCBjb21taXR0ZWQgc2xvdCDiiJIgc2VlZCArXG4gICAgICAgIC8vIDEpIG92ZXIgdGhlIGZvbGQncyBvd24gY29tbWl0dGVkIGNvdW50IGlzIGV2ZW50cyBPVEhFUiB3cml0ZXJzXG4gICAgICAgIC8vIGxhbmRlZCBpbiBiZXR3ZWVuLlxuICAgICAgICBjb25zdCBleHBlY3RlZEZpcnN0U2xvdCA9IGV2ZW50TG9nXG4gICAgICAgICAgPyAobWF4RXZlbnRTbG90KGV2ZW50TG9nLmV2ZW50cykgPz8gMCkgKyAxXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIC8vIFBhaXItYXdhcmUgY2h1bmtpbmc6IGEgcHJlLWNsYWltZWQgcGFpcidzIHR3byByb3dzIG11c3QgbGFuZCBpblxuICAgICAgICAvLyB0aGUgc2FtZSBjcmVhdGVCYXRjaCBjYWxsIOKAlCBhZGphY2VudCwgc28gYSBXb3JsZCBjYW4gZm9sZCB0aGVtXG4gICAgICAgIC8vIGludG8gb25lIGJvcm4tcnVubmluZyBjcmVhdGUg4oCUIGFuZCBuZXZlciBzdHJhZGRsZSBhIGNodW5rXG4gICAgICAgIC8vIGJvdW5kYXJ5LCB3aGljaCB3b3VsZCB0dXJuIHRoZSBzdGFydGVkIHJvdyBpbnRvIGEgc3RhbmRhbG9uZVxuICAgICAgICAvLyBjbGFpbSByYWNpbmcgaXRzIG93biBjcmVhdGUncyBjb21taXQuXG4gICAgICAgIGNvbnN0IGNodW5rczogKHR5cGVvZiBlbnRyaWVzKVtdID0gW107XG4gICAgICAgIHtcbiAgICAgICAgICBsZXQgY3VycmVudDogdHlwZW9mIGVudHJpZXMgPSBbXTtcbiAgICAgICAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZW50cmllcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgICAgICAgICBjb25zdCBuZXh0ID0gZW50cmllc1tpbmRleCArIDFdO1xuICAgICAgICAgICAgY29uc3QgcGFpckxlYWQgPVxuICAgICAgICAgICAgICBlbnRyeS5raW5kID09PSAnaW5saW5lLWNyZWF0ZWQnICYmXG4gICAgICAgICAgICAgIG5leHQ/LmtpbmQgPT09ICdpbmxpbmUtc3RhcnRlZCcgJiZcbiAgICAgICAgICAgICAgbmV4dC5jb3JyZWxhdGlvbklkID09PSBlbnRyeS5jb3JyZWxhdGlvbklkO1xuICAgICAgICAgICAgY29uc3QgdGFrZSA9IHBhaXJMZWFkID8gMiA6IDE7XG4gICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgIGN1cnJlbnQubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgICBjdXJyZW50Lmxlbmd0aCArIHRha2UgPiBNQVhfQkFUQ0hfRkFOT1VUX0VWRU5UU1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgIGNodW5rcy5wdXNoKGN1cnJlbnQpO1xuICAgICAgICAgICAgICBjdXJyZW50ID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJyZW50LnB1c2goZW50cnkpO1xuICAgICAgICAgICAgaWYgKHBhaXJMZWFkKSB7XG4gICAgICAgICAgICAgIGN1cnJlbnQucHVzaChuZXh0KTtcbiAgICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGN1cnJlbnQubGVuZ3RoID4gMCkgY2h1bmtzLnB1c2goY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gU3RlcHMgd2hvc2UgcXVldWUgbWVzc2FnZXMgVEhJUyBGTFVTSCB3aWxsIHB1Ymxpc2ggKHRoZSBlYWdlclxuICAgICAgICAvLyBjcmVhdGVzKSwgcmVjb3JkZWQgYmVmb3JlIGFueSBjaHVuayBzZXR0bGVzIHNvIHRoZSBjYWxsZXInc1xuICAgICAgICAvLyBkaXNwYXRjaCBwYXNzIOKAlCB3aGljaCBydW5zIG9mZiB0aGUgaGFuZGxlcidzIHJldHVybiDigJQgc2tpcHMgdGhlbS5cbiAgICAgICAgLy8gVGhlIHNlbmRzIGFyZSBndWFyYW50ZWVkLW9yLWZhaWxlZCBieSB0aGUgdHJhaWxpbmcgd29yayB0aGVcbiAgICAgICAgLy8gY2FsbGVyIGpvaW5zIGJlZm9yZSBhY2tpbmcsIHNvIFwid2lsbCBiZSBwdWJsaXNoZWQgYnkgdGhpcyBmbHVzaFwiXG4gICAgICAgIC8vIGFuZCBcImFscmVhZHkgcHVibGlzaGVkXCIgYXJlIGVxdWl2YWxlbnQgZnJvbSB0aGUgY2FsbGVyJ3Mgc2lkZS5cbiAgICAgICAgY29uc3QgcHVibGlzaEVhZ2VyU3RlcHMgPSBzdGVwRGlzcGF0Y2ggIT09IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHB1Ymxpc2hFYWdlclN0ZXBzKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgICAgICBpZiAoZW50cnkua2luZCA9PT0gJ3N0ZXAnKSB7XG4gICAgICAgICAgICAgIHF1ZXVlZFN0ZXBDb3JyZWxhdGlvbklkcy5hZGQoZW50cnkuY29ycmVsYXRpb25JZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGFsbGllcyBmb3IgdGhlIGZvcmVpZ24taW50ZXJsZWF2aW5nIGRpYWdub3N0aWMsIGZvbGRlZCBhY3Jvc3NcbiAgICAgICAgLy8gdGhlIGNvbmN1cnJlbnQgY2h1bmtzIGFuZCByZWFkIG9uY2UgYWxsIG9mIHRoZW0gc2V0dGxlZC5cbiAgICAgICAgbGV0IGNvbW1pdHRlZENvdW50ID0gMDtcbiAgICAgICAgbGV0IG1heENvbW1pdHRlZFNsb3Q6IG51bWJlciB8IHVuZGVmaW5lZDtcblxuICAgICAgICBjb25zdCBjb21taXRDaHVuayA9IGFzeW5jIChjaHVuazogdHlwZW9mIGVudHJpZXMpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgICAgICAvLyBBbmNob3JzIGZvciB0aGUgcHJlLWNsYWltZWQgc3RlcHMnIHRlbGVtZXRyeTogdGhlIFBPU1QgaW5zdGFudFxuICAgICAgICAgIC8vIGlzIHRoZSBjbGFpbSdzIFwic3RhcnQgUE9TVCBzZW50XCIgKFJTRlMncyBlbmQpLCB0aGUgcmV0dXJuIGlzIHRoZVxuICAgICAgICAgIC8vIGNsYWltJ3MgY29tcGxldGlvbiAoVFRSJ3MgVDYpIOKAlCB0aGUgc2FtZSB0d28gaW5zdGFudHMgdGhlIGxhenlcbiAgICAgICAgICAvLyBjbGFpbSdzIG93biBQT1NUIHdvdWxkIGhhdmUgcHJvZHVjZWQuXG4gICAgICAgICAgY29uc3QgYmF0Y2hQb3N0U2VudEF0TXMgPSBEYXRlLm5vdygpO1xuICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N0eWxlL25vTm9uTnVsbEFzc2VydGlvbjogYmF0Y2hGYW5vdXRFbGlnaWJsZSBpbXBsaWVzIHByZXNlbmNlXG4gICAgICAgICAgY29uc3QgeyByZXN1bHRzIH0gPSBhd2FpdCB3b3JsZC5ldmVudHMuY3JlYXRlQmF0Y2ghKFxuICAgICAgICAgICAgcnVuSWQsXG4gICAgICAgICAgICBjaHVuay5tYXAoKGVudHJ5KSA9PiAoe1xuICAgICAgICAgICAgICBldmVudDogZW50cnkuZXZlbnQsXG4gICAgICAgICAgICAgIC8vIFRoZSBzdGFydGVkIHJvdyBpcyB0aGUgc3RlcCdzIGV4ZWN1dGluZyBjbGFpbSwgc28gaXQgY2Fycmllc1xuICAgICAgICAgICAgICAvLyB0aGUgY29tcHV0ZS1pbnN0YW5jZSBhdHRyaWJ1dGlvbiB0aGUgc2luZ2xlIGNsYWltIHNlbmRzIHZpYVxuICAgICAgICAgICAgICAvLyBDcmVhdGVFdmVudFBhcmFtcy5cbiAgICAgICAgICAgICAgLi4uKGVudHJ5LmtpbmQgPT09ICdpbmxpbmUtc3RhcnRlZCdcbiAgICAgICAgICAgICAgICA/IHsgY29tcHV0ZUluc3RhbmNlSWQ6IENPTVBVVEVfSU5TVEFOQ0VfSUQgfVxuICAgICAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgLy8gUGVyLXdyaXRlIHJlcXVlc3QgYXR0cmlidXRpb24sIHNhbWUgYXMgdGhlIHNpbmdsZSBwYXRoJ3NcbiAgICAgICAgICAgIC8vIGNyZWF0ZUd1YXJkZWQo4oCmLCB7IHJlcXVlc3RJZCB9KS5cbiAgICAgICAgICAgIHsgcmVxdWVzdElkIH1cbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IGNsYWltQ29tcGxldGVkQXRNcyA9IERhdGUubm93KCk7XG4gICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGl0ZW1dIG9mIHJlc3VsdHMuZW50cmllcygpKSB7XG4gICAgICAgICAgICBjb25zdCBlbnRyeSA9IGNodW5rW2luZGV4XTtcbiAgICAgICAgICAgIGlmIChpdGVtLmVycm9yID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgaWYgKGVudHJ5LmtpbmQgPT09ICdzdGVwJykge1xuICAgICAgICAgICAgICAgIGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHMuYWRkKGVudHJ5LmNvcnJlbGF0aW9uSWQpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGVudHJ5LmtpbmQgPT09ICdpbmxpbmUtc3RhcnRlZCcpIHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgcGFpciBjb21taXR0ZWQ6IHRoaXMgaW52b2NhdGlvbiBvd25zIHRoZSBzdGVwIGFuZCB0aGVcbiAgICAgICAgICAgICAgICAvLyBjYWxsZXIgcnVucyB0aGUgYm9keSB3aXRoIG5vIGNsYWltIG9mIGl0cyBvd24uIFRoZVxuICAgICAgICAgICAgICAgIC8vIHJlYWRiYWNrIGVudGl0eSBpcyBhdXRob3JpdGF0aXZlIHdoZXJlIHByZXNlbnQ7IGEgV29ybGRcbiAgICAgICAgICAgICAgICAvLyB0aGF0IG9taXR0ZWQgaXQgZ2V0cyB0aGUgc2FtZSBsb2NhbGx5IHN5bnRoZXNpemVkIHJ1bm5pbmdcbiAgICAgICAgICAgICAgICAvLyBhdHRlbXB0LTEgdGhlIG9wdGltaXN0aWMgcGF0aCBleGVjdXRlcyBhZ2FpbnN0LiBFaXRoZXJcbiAgICAgICAgICAgICAgICAvLyB3YXkgdGhlIGlucHV0IGlzIHJlLWF0dGFjaGVkIGxvY2FsbHkg4oCUIGJhdGNoIHJlc3BvbnNlc1xuICAgICAgICAgICAgICAgIC8vIHJldHVybiByZWZzIGxhemlseSwgYW5kIHRoZSBib2R5J3MgaHlkcmF0aW9uIHdhbnRzIHRoZVxuICAgICAgICAgICAgICAgIC8vIGV4YWN0IGJ5dGVzIHRoZSBwYWlyJ3MgY3JlYXRlZCByb3cgY2FycmllZC4gKFRoZSBjcmVhdGVkXG4gICAgICAgICAgICAgICAgLy8gcm93J3Mgc3VjY2VzcyBpcyBkZWxpYmVyYXRlbHkgTk9UIG1lbWJlcnNoaXAgaW5cbiAgICAgICAgICAgICAgICAvLyBjcmVhdGVkU3RlcENvcnJlbGF0aW9uSWRzOiBmb3IgaW5saW5lIHN0ZXBzIG93bmVyc2hpcCBpc1xuICAgICAgICAgICAgICAgIC8vIHRoZSBzdGFydGVkIHJvdydzIHZlcmRpY3QsIGFuZCB0aGUgY2FsbGVyJ3MgZGlzcGF0Y2ggcGFzc1xuICAgICAgICAgICAgICAgIC8vIHNraXBzIGlubGluZSBjb3JyZWxhdGlvbiBpZHMgcmVnYXJkbGVzcy4pXG4gICAgICAgICAgICAgICAgY29uc3QgZGVoeWRyYXRlZCA9IGxhenlJbmxpbmVCeUNvcnJlbGF0aW9uSWQuZ2V0KFxuICAgICAgICAgICAgICAgICAgZW50cnkuY29ycmVsYXRpb25JZFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKGRlaHlkcmF0ZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgLy8gVW5yZWFjaGFibGU6IHRoZSBzYW1lIHByZXAgb3AgdGhhdCBlbnF1ZXVlZCB0aGUgcGFpciBzZXRcbiAgICAgICAgICAgICAgICAgIC8vIHRoaXMgZW50cnksIGFuZCB0aGUgZmx1c2ggYXdhaXRlZCBldmVyeSBwcmVwIGFib3ZlLlxuICAgICAgICAgICAgICAgICAgLy9cbiAgICAgICAgICAgICAgICAgIC8vIE5vdCBmcmVlIGlmIGl0IGV2ZXIgZmlyZXMsIHRob3VnaDogdGhlIHBhaXIgaXMgYWxyZWFkeVxuICAgICAgICAgICAgICAgICAgLy8gZHVyYWJsZSBoZXJlLCBzbyB0aGlzIHRocm93cyB3aXRoIHRoZSBzdGVwIGNsYWltZWQgYW5kXG4gICAgICAgICAgICAgICAgICAvLyBpdHMgYm9keSBuZXZlciBydW4uIFRoZSBkZWxpdmVyeSBmYWlscywgYW5kIHJlZGVsaXZlcnlcbiAgICAgICAgICAgICAgICAgIC8vIHJlY292ZXJzIGl0IHRocm91Z2ggb3duZWQtcmVjb3ZlcnkgKHRoZSBzdGVwIGNhcnJpZXMgdGhpc1xuICAgICAgICAgICAgICAgICAgLy8gbWVzc2FnZSdzIG93bmVyc2hpcCBzdGFtcCkgcmF0aGVyIHRoYW4gdGhlIHJlcXVlc3QganVzdFxuICAgICAgICAgICAgICAgICAgLy8gZmFpbGluZyBjbGVhbmx5LlxuICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFdvcmtmbG93V29ybGRFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYG5vIGRlaHlkcmF0ZWQgaW5wdXQgZm9yIHByZS1jbGFpbWVkIHN0ZXAgJHtlbnRyeS5jb3JyZWxhdGlvbklkfWAsXG4gICAgICAgICAgICAgICAgICAgIHsgc3RhdHVzOiA1MDAgfVxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBzdGFydGVkU3RlcDogU3RhcnRlZFN0ZXAgPSBpdGVtLnN0ZXA/LnN0YXJ0ZWRBdFxuICAgICAgICAgICAgICAgICAgPyB7IC4uLml0ZW0uc3RlcCwgc3RhcnRlZEF0OiBpdGVtLnN0ZXAuc3RhcnRlZEF0IH1cbiAgICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICAgICAgICAgIHN0ZXBJZDogZW50cnkuY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICAgICAgICBzdGVwTmFtZTogZGVoeWRyYXRlZC5zdGVwTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICdydW5uaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICBhdHRlbXB0OiAxLFxuICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZWRBdDogbm93LFxuICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZWRBdDogbm93LFxuICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0ZWRBdDogbm93LFxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGlubGluZUNsYWltcy5zZXQoZW50cnkuY29ycmVsYXRpb25JZCwge1xuICAgICAgICAgICAgICAgICAgb3duZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICBzdGVwOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnN0YXJ0ZWRTdGVwLFxuICAgICAgICAgICAgICAgICAgICBpbnB1dDogZGVoeWRyYXRlZC5kZWh5ZHJhdGVkSW5wdXQsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgYmF0Y2hQb3N0U2VudEF0TXMsXG4gICAgICAgICAgICAgICAgICBjbGFpbUNvbXBsZXRlZEF0TXMsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXRlbS5zdGF0dXMgPT09IDQwOSkge1xuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgZW50cnkua2luZCA9PT0gJ2lubGluZS1jcmVhdGVkJyB8fFxuICAgICAgICAgICAgICAgIGVudHJ5LmtpbmQgPT09ICdpbmxpbmUtc3RhcnRlZCdcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIHBhaXIgbG9zdCBpdHMgYXRvbWljIGNyZWF0ZS1jbGFpbTogYSBjb25jdXJyZW50IHdyaXRlclxuICAgICAgICAgICAgICAgIC8vIGFscmVhZHkgb3ducyB0aGlzIHN0ZXAgKGFuIGVhcmxpZXIgZGVsaXZlcnkncyBjcmVhdGUsIG9yIGFcbiAgICAgICAgICAgICAgICAvLyByYWNpbmcgaGFuZGxlcidzIGNsYWltKS4gUmVjb3JkZWQgYXMgYSBsb3N0IGNsYWltIOKAlCB0aGVcbiAgICAgICAgICAgICAgICAvLyBjYWxsZXIncyBleGVjdXRlU3RlcCByZXR1cm5zIGBza2lwcGVkYCB3aXRob3V0IHJ1bm5pbmcgdGhlXG4gICAgICAgICAgICAgICAgLy8gYm9keSwgdGhlIHNhbWUgb3V0Y29tZSBhcyBsb3NpbmcgdGhlIGxhenkgY2xhaW0uIEEgV29ybGRcbiAgICAgICAgICAgICAgICAvLyB0aGF0IGZvbGRzIHRoZSBwYWlyIHJlcG9ydHMgdGhlIDQwOSBvbiBib3RoIHJvd3MgKHNldFxuICAgICAgICAgICAgICAgIC8vIHR3aWNlLCBoYXJtbGVzcyk7IG9uZSB0aGF0IGV2YWx1YXRlcyByb3dzIGluZGVwZW5kZW50bHlcbiAgICAgICAgICAgICAgICAvLyBoYXMgdGhlIHN0YXJ0ZWQgcm93IOKAlCBwcm9jZXNzZWQgc2Vjb25kIOKAlCBkZWNpZGUsIHdoaWNoIGlzXG4gICAgICAgICAgICAgICAgLy8gZXhhY3RseSB0aGUgc2luZ2xlIHBhdGgncyBzZW1hbnRpY3MgKGNyZWF0ZSBsb3N0ICsgY2xhaW1cbiAgICAgICAgICAgICAgICAvLyB3b24gc3RpbGwgcnVucyB0aGUgYm9keTsgY3JlYXRlIHdvbiArIGNsYWltIGxvc3Qgc2tpcHMpLlxuICAgICAgICAgICAgICAgIGlubGluZUNsYWltcy5zZXQoZW50cnkuY29ycmVsYXRpb25JZCwgeyBvd25lZDogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKCdJbmxpbmUgc3RlcCBwcmUtY2xhaW0gbG9zdCwgY29udGludWluZycsIHtcbiAgICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb25JZDogZW50cnkuY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGl0ZW0ubWVzc2FnZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAvLyBTYW1lIHRvbGVyYW5jZSBhcyB0aGUgc2luZ2xlIHBhdGgncyBFbnRpdHlDb25mbGljdEVycm9yOiBhXG4gICAgICAgICAgICAgIC8vIGNvbmN1cnJlbnQgb3IgZWFybGllciBkZWxpdmVyeSBhbHJlYWR5IGNyZWF0ZWQgaXQuXG4gICAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuaW5mbyhcbiAgICAgICAgICAgICAgICBlbnRyeS5raW5kID09PSAnc3RlcCdcbiAgICAgICAgICAgICAgICAgID8gJ1N0ZXAgYWxyZWFkeSBleGlzdHMsIGNvbnRpbnVpbmcnXG4gICAgICAgICAgICAgICAgICA6ICdXYWl0IGFscmVhZHkgZXhpc3RzLCBjb250aW51aW5nJyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICB3b3JrZmxvd1J1bklkOiBydW5JZCxcbiAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IGVudHJ5LmNvcnJlbGF0aW9uSWQsXG4gICAgICAgICAgICAgICAgICBtZXNzYWdlOiBpdGVtLm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRocm93IG5ldyBXb3JrZmxvd1dvcmxkRXJyb3IoXG4gICAgICAgICAgICAgIGBiYXRjaGVkICR7ZW50cnkuZXZlbnQuZXZlbnRUeXBlfSBmb3IgJHtlbnRyeS5jb3JyZWxhdGlvbklkfSBgICtcbiAgICAgICAgICAgICAgICBgZmFpbGVkOiAke2l0ZW0uZXJyb3J9OiAke2l0ZW0ubWVzc2FnZX1gLFxuICAgICAgICAgICAgICB7IHN0YXR1czogaXRlbS5zdGF0dXMgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gSGlnaGVzdCBzbG90IHRoaXMgY2h1bmsgY29tbWl0dGVkOiB0aGUgY2VpbGluZyB0aGUgY2FsbGVyIGZvbGRzXG4gICAgICAgICAgLy8gaW50byB0aGUgaW5saW5lIGV4ZWN1dGlvbnMnIHNsb3Qgc25hcHNob3QgKHNlZVxuICAgICAgICAgIC8vIFN1c3BlbnNpb25IYW5kbGVyUmVzdWx0LmJhdGNoQ29tbWl0dGVkU2xvdENlaWxpbmcpIGFuZCBvbmUgaW5wdXRcbiAgICAgICAgICAvLyBvZiB0aGUgaW50ZXJsZWF2aW5nIGRpYWdub3N0aWMuXG4gICAgICAgICAgY29uc3QgY2h1bmtNYXhTbG90ID0gbWF4RXZlbnRTbG90KFxuICAgICAgICAgICAgcmVzdWx0cy5mbGF0TWFwKChpdGVtKSA9PlxuICAgICAgICAgICAgICBpdGVtLmVycm9yID09PSB1bmRlZmluZWQgJiYgaXRlbS5ldmVudCA/IFtpdGVtLmV2ZW50XSA6IFtdXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBjaHVua01heFNsb3QgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKGJhdGNoQ29tbWl0dGVkU2xvdENlaWxpbmcgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgICAgICAgICBjaHVua01heFNsb3QgPiBiYXRjaENvbW1pdHRlZFNsb3RDZWlsaW5nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgYmF0Y2hDb21taXR0ZWRTbG90Q2VpbGluZyA9IGNodW5rTWF4U2xvdDtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29tbWl0dGVkQ291bnQgKz0gcmVzdWx0cy5maWx0ZXIoXG4gICAgICAgICAgICAoaXRlbSkgPT4gaXRlbS5lcnJvciA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgKS5sZW5ndGg7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgY2h1bmtNYXhTbG90ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgIChtYXhDb21taXR0ZWRTbG90ID09PSB1bmRlZmluZWQgfHwgY2h1bmtNYXhTbG90ID4gbWF4Q29tbWl0dGVkU2xvdClcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIG1heENvbW1pdHRlZFNsb3QgPSBjaHVua01heFNsb3Q7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFB1Ymxpc2ggdGhlIGNodW5rJ3MgZWFnZXIgc3RlcHMnIHF1ZXVlIG1lc3NhZ2VzIHRoZSBtb21lbnQgSVRTXG4gICAgICAgIC8vIGNyZWF0ZXMgYXJlIGR1cmFibGUg4oCUIHRoZSBwZXItY2h1bmsgaGFsZiBvZiBwdWJsaXNoLWFmdGVyLWNyZWF0ZS5cbiAgICAgICAgLy8gU2FtZSBtZXNzYWdlIHNoYXBlIGFuZCBzdGVwLWlkZW50aXR5LXNjb3BlZCBpZGVtcG90ZW5jeSBrZXkgYXMgdGhlXG4gICAgICAgIC8vIGNhbGxlcidzIGRpc3BhdGNoIHBhc3MsIHNvIGFueXRoaW5nIGRvdWJsZS1wdWJsaXNoZWQgZGVkdXBlcy5cbiAgICAgICAgY29uc3QgcHVibGlzaENodW5rU3RlcHMgPSBhc3luYyAoXG4gICAgICAgICAgY2h1bms6IHR5cGVvZiBlbnRyaWVzXG4gICAgICAgICk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgICAgIGlmICghcHVibGlzaEVhZ2VyU3RlcHMpIHJldHVybjtcbiAgICAgICAgICBjb25zdCBzdGVwRW50cmllcyA9IGNodW5rLmZpbHRlcigoZW50cnkpID0+IGVudHJ5LmtpbmQgPT09ICdzdGVwJyk7XG4gICAgICAgICAgaWYgKHN0ZXBFbnRyaWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgICAgIGNvbnN0IHRyYWNlQ2FycmllciA9IGF3YWl0IGdldFN0ZXBEaXNwYXRjaFRyYWNlQ2FycmllcigpO1xuICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICAgICAgc3RlcEVudHJpZXMubWFwKChlbnRyeSkgPT5cbiAgICAgICAgICAgICAgcXVldWVNZXNzYWdlKFxuICAgICAgICAgICAgICAgIHdvcmxkLFxuICAgICAgICAgICAgICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N0eWxlL25vTm9uTnVsbEFzc2VydGlvbjogcHVibGlzaEVhZ2VyU3RlcHMgaW1wbGllcyBwcmVzZW5jZVxuICAgICAgICAgICAgICAgIHN0ZXBEaXNwYXRjaCEucXVldWVOYW1lLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIHJ1bklkLFxuICAgICAgICAgICAgICAgICAgc3RlcElkOiBlbnRyeS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvbm9Ob25OdWxsQXNzZXJ0aW9uOiBzZXQgb24gZXZlcnkgJ3N0ZXAnIGVudHJ5IGF0IGVucXVldWVcbiAgICAgICAgICAgICAgICAgIHN0ZXBOYW1lOiBlbnRyeS5zdGVwTmFtZSEsXG4gICAgICAgICAgICAgICAgICB0cmFjZUNhcnJpZXIsXG4gICAgICAgICAgICAgICAgICByZXF1ZXN0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGlkZW1wb3RlbmN5S2V5OiBzdGVwRGlzcGF0Y2hJZGVtcG90ZW5jeUtleShcbiAgICAgICAgICAgICAgICAgICAgZW50cnkuY29ycmVsYXRpb25JZCxcbiAgICAgICAgICAgICAgICAgICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvc3R5bGUvbm9Ob25OdWxsQXNzZXJ0aW9uOiBzZXQgb24gZXZlcnkgJ3N0ZXAnIGVudHJ5IGF0IGVucXVldWVcbiAgICAgICAgICAgICAgICAgICAgZW50cnkuc3RlcE5hbWUhXG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gTGF1bmNoIGV2ZXJ5IGNodW5rJ3MgUE9TVCBub3c7IGNoYWluIGVhY2ggY2h1bmsncyBwdWJsaXNoZXMgb24gaXRzXG4gICAgICAgIC8vIE9XTiBjb21taXQuIEEgY2h1bmsgd2hvc2UgY29tbWl0IHJlamVjdGVkIGtlZXBzIGl0cyBtZXNzYWdlc1xuICAgICAgICAvLyB1bnNlbnQgKHRoZSByZWplY3Rpb24gZmFpbHMgdGhlIGRlbGl2ZXJ5OyByZWRlbGl2ZXJ5IHJlLWNyZWF0ZXNcbiAgICAgICAgLy8gYW5kIHJlLWRpc3BhdGNoZXMsIGRlZHVwZWQgYnkgdGhlIGlkZW1wb3RlbmN5IGtleXMpLlxuICAgICAgICBjb25zdCBjb21taXRzID0gY2h1bmtzLm1hcCgoY2h1bmspID0+IGNvbW1pdENodW5rKGNodW5rKSk7XG4gICAgICAgIGNvbnN0IHB1Ymxpc2hlcyA9IGNodW5rcy5tYXAoYXN5bmMgKGNodW5rLCBpbmRleCkgPT4ge1xuICAgICAgICAgIGF3YWl0IGNvbW1pdHNbaW5kZXhdO1xuICAgICAgICAgIGF3YWl0IHB1Ymxpc2hDaHVua1N0ZXBzKGNodW5rKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgdHJhaWxpbmcgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIC8vIExldCBldmVyeSBzaWJsaW5nIHNldHRsZSBiZWZvcmUgc3VyZmFjaW5nIHRoZSBmaXJzdCBmYWlsdXJlOiBhXG4gICAgICAgICAgLy8gY2h1bmsgdGhhdCBjb21taXR0ZWQgbXVzdCBzdGlsbCBnZXQgaXRzIHB1Ymxpc2hlcyBvdXQgZXZlbiB3aGVuXG4gICAgICAgICAgLy8gYW5vdGhlciBjaHVuayBmYWlsZWQsIGFuZCB0aGUgY2FsbGVyIGFja3Mgb25seSBhZnRlciB0aGlzXG4gICAgICAgICAgLy8gcmVzb2x2ZXMuXG4gICAgICAgICAgY29uc3Qgc2V0dGxlZCA9IGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4uY29tbWl0cywgLi4ucHVibGlzaGVzXSk7XG4gICAgICAgICAgLy8gRm9yZWlnbi1pbnRlcmxlYXZpbmcgdmlzaWJpbGl0eTogdGhlIGJhdGNoIGVuZHBvaW50IGhhcyBub1xuICAgICAgICAgIC8vIGJ1bXAtYW5kLXJlcG9ydCwgc28gZXZlbnRzIG90aGVyIHdyaXRlcnMgbGFuZGVkIGJldHdlZW4gdGhlXG4gICAgICAgICAgLy8gc25hcHNob3QgYW5kIHRoZXNlIGNvbW1pdHMgcHVzaGVkIHRoZSBmb2xkIHRvIGhpZ2hlciBzbG90c1xuICAgICAgICAgIC8vIFdJVEhPVVQgaGFuZGluZyB1cyB0aGUgc2tpcHBlZCBldmVudHMuIFNhbWUgYWNjZXB0ZWQgZXhwb3N1cmVcbiAgICAgICAgICAvLyBhcyBhIGRyb3BwZWQgdHJ1bmNhdGVkIHJlcG9ydCBvbiB0aGUgc2luZ2xlIHBhdGg6IHRoZSBsb2NhbFxuICAgICAgICAgIC8vIGxvZyBzdGF5cyBhIHN0cmljdCBwcmVmaXggYW5kIHRoZSBuZXh0IHJlbG9hZCBvYnNlcnZlcyB0aGVtLlxuICAgICAgICAgIC8vIExvZ2dlZCBzbyBhIGJ1bXAgaXMgZGlhZ25vc2FibGUgcmF0aGVyIHRoYW4gc2lsZW50LlxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGV4cGVjdGVkRmlyc3RTbG90ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICAgIG1heENvbW1pdHRlZFNsb3QgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29uc3QgaW50ZXJsZWF2ZWQgPVxuICAgICAgICAgICAgICBtYXhDb21taXR0ZWRTbG90IC0gZXhwZWN0ZWRGaXJzdFNsb3QgKyAxIC0gY29tbWl0dGVkQ291bnQ7XG4gICAgICAgICAgICBpZiAoaW50ZXJsZWF2ZWQgPiAwKSB7XG4gICAgICAgICAgICAgIHJ1bnRpbWVMb2dnZXIuZGVidWcoJ0JhdGNoZWQgZmFuLW91dCBjb21taXR0ZWQgYWJvdmUgc25hcHNob3QnLCB7XG4gICAgICAgICAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgICAgICAgICAgZXhwZWN0ZWRGaXJzdFNsb3QsXG4gICAgICAgICAgICAgICAgbWF4Q29tbWl0dGVkU2xvdCxcbiAgICAgICAgICAgICAgICBjb21taXR0ZWRDb3VudCxcbiAgICAgICAgICAgICAgICBpbnRlcmxlYXZlZCxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGZhaWx1cmUgPSBzZXR0bGVkLmZpbmQoXG4gICAgICAgICAgICAob3V0Y29tZSk6IG91dGNvbWUgaXMgUHJvbWlzZVJlamVjdGVkUmVzdWx0ID0+XG4gICAgICAgICAgICAgIG91dGNvbWUuc3RhdHVzID09PSAncmVqZWN0ZWQnXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAoZmFpbHVyZSkgdGhyb3cgZmFpbHVyZS5yZWFzb247XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgLy8gRVZFUlkgY2h1bmsgY2FycnlpbmcgcGFpcnMgZ2F0ZXMgdGhlIHJldHVybiwgbm90IGp1c3QgdGhlIGZpcnN0OlxuICAgICAgICAvLyBhIHBhaXIgd2hvc2UgY29tbWl0IHRoZSBjYWxsZXIgaGFzIG5vdCBzZWVuIHlpZWxkcyBub1xuICAgICAgICAvLyBgaW5saW5lQ2xhaW1zYCBlbnRyeSwgc28gdGhlIGNhbGxlciBmYWxscyBiYWNrIHRvIGEgbGF6eVxuICAgICAgICAvLyBgc3RlcF9zdGFydGVkYCB0aGF0IHdvdWxkIHJhY2UgdGhpcyBzYW1lIGZvbGQncyBzdGlsbC1pbi1mbGlnaHRcbiAgICAgICAgLy8gcGFpciBmb3IgdGhlIHNhbWUgc3RlcC4gVG9kYXkgcGFpcnMgYWx3YXlzIGxhbmQgaW4gb25lIGNodW5rXG4gICAgICAgIC8vICh0aGV5IHNvcnQgZmlyc3QsIGFuZCB0d28gcm93cyBwZXIgaW5saW5lIHN0ZXAgZml0IGluc2lkZSBvbmVcbiAgICAgICAgLy8gY2h1bmsg4oCUIHBpbm5lZCBieSBjb25zdGFudHMudGVzdC50cyksIHNvIHRoaXMgaXMgYXQgbW9zdCBvbmVcbiAgICAgICAgLy8gY29tbWl0OyB0aGUgZmlsdGVyIGlzIHdoYXQga2VlcHMgdGhlIHByb3BlcnR5IHRydWUgaWYgZWl0aGVyIGNhcFxuICAgICAgICAvLyBtb3Zlcy5cbiAgICAgICAgY29uc3QgcGFpckNvbW1pdHMgPSBjaHVua3MuZmxhdE1hcCgoY2h1bmssIGluZGV4KSA9PlxuICAgICAgICAgIGNodW5rLnNvbWUoKGVudHJ5KSA9PiBlbnRyeS5raW5kID09PSAnaW5saW5lLXN0YXJ0ZWQnKVxuICAgICAgICAgICAgPyBbY29tbWl0c1tpbmRleF1dXG4gICAgICAgICAgICA6IFtdXG4gICAgICAgICk7XG4gICAgICAgIGlmIChhbGxvd0RlZmVycmVkQmF0Y2hXb3JrKSB7XG4gICAgICAgICAgLy8gVGhlIHRyYWlsaW5nIHdvcmsgaXMgdGhlIGNhbGxlcidzIHRvIGpvaW4gYmVmb3JlIGFjay4gQXR0YWNoIGFcbiAgICAgICAgICAvLyBoYW5kbGVyIG5vdyBzbyBhIHJlamVjdGlvbiB0aGF0IHJhY2VzIHRoYXQgam9pbiAob3IgYSBmb3JlZ3JvdW5kXG4gICAgICAgICAgLy8gZmFpbHVyZSB0aGF0IHByZXZlbnRzIHRoZSBjYWxsZXIgZnJvbSBldmVyIHJlYWNoaW5nIGl0KSBpcyBuZXZlclxuICAgICAgICAgIC8vIGFuIHVuaGFuZGxlZFJlamVjdGlvbiDigJQgYXdhaXRpbmcgdGhlIHByb21pc2Ugc3RpbGwgb2JzZXJ2ZXMgaXQuXG4gICAgICAgICAgdHJhaWxpbmcuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgICAgIGRlZmVycmVkQmF0Y2hXb3JrID0gdHJhaWxpbmc7XG4gICAgICAgICAgLy8gT25seSB0aGUgcGFpciBjaHVua3MgZ2F0ZSB0aGUgcmV0dXJuOiB0aGVpciBjbGFpbXMgYXJlIHdoYXQgdGhlXG4gICAgICAgICAgLy8gY2FsbGVyIHN0YXJ0cyB0aGUgaW5saW5lIGJvZGllcyBmcm9tLiBXaXRoIG5vIHBhaXJzIHRoZXJlIGlzXG4gICAgICAgICAgLy8gbm90aGluZyB0aGUgY2FsbGVyJ3MgcG9zdC1yZXR1cm4gd29yayByZWFkcyBmcm9tIHRoZSBjb21taXRzLFxuICAgICAgICAgIC8vIHNvIG5vdGhpbmcgZ2F0ZXMuXG4gICAgICAgICAgaWYgKHBhaXJDb21taXRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHBhaXJDb21taXRzKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAvLyBBIHBhaXIgY2h1bmsgZmFpbGVkLCBzbyB0aGlzIHBoYXNlJ3Mgd3JpdGUgc2V0IGlzIE5PVCB0aGVcbiAgICAgICAgICAgICAgLy8gY2FsbGVyJ3MgdG8gam9pbiBhbnkgbW9yZSDigJQgYGRlZmVycmVkQmF0Y2hXb3JrYCBuZXZlclxuICAgICAgICAgICAgICAvLyByZWFjaGVzIGl0IG9uY2UgaGFuZGxlU3VzcGVuc2lvbiB0aHJvd3MuIFNldHRsZSB0aGUgcmVzdFxuICAgICAgICAgICAgICAvLyBiZWZvcmUgdGhlIHJlamVjdGlvbiBlc2NhcGVzLCBmb3IgdGhlIHJlYXNvbiBgc2V0dGxlUGhhc2VgXG4gICAgICAgICAgICAgIC8vIGdpdmVzOiBhIHNpYmxpbmcgY3JlYXRlIGxhbmRpbmcgYWZ0ZXIgdGhlIHRocm93IGNvbW1pdHMgYW5cbiAgICAgICAgICAgICAgLy8gZXZlbnQgZnJvbSB0aGUgYWJhbmRvbmVkIHJlcGxheSdzIHNlZWRlZCBzZXF1ZW5jZSBhbmQgcmFjZXNcbiAgICAgICAgICAgICAgLy8gdGhlIGNhbGxlcidzIHJlc3RhcnQgcmVsb2FkIHdoaWxlIGRvaW5nIHNvLlxuICAgICAgICAgICAgICBhd2FpdCB0cmFpbGluZy5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICAgICAgICAgIHRocm93IGVycjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXdhaXQgdHJhaWxpbmc7XG4gICAgICAgIH1cbiAgICAgIH0pKClcbiAgICApO1xuICB9XG5cbiAgZm9yIChjb25zdCBxdWV1ZUl0ZW0gb2YgYXR0cmlidXRlSXRlbXMpIHtcbiAgICBvcHMucHVzaChcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgZW5zdXJlUnVuUmVhZHkoKTtcbiAgICAgICAgICAvLyBHdWFyZGVkIGxpa2UgZXZlcnkgb3RoZXIgc3VzcGVuc2lvbiB3cml0ZTogYW4gYXR0cl9zZXQgaXMgYVxuICAgICAgICAgIC8vIHJlcGxheS1kZXJpdmVkIGV2ZW50IHdpdGggYSBjb3JyZWxhdGlvbiBpZCBmcm9tIHRoaXMgcmVwbGF5J3NcbiAgICAgICAgICAvLyBzZWVkZWQgc2VxdWVuY2UsIHNvIGl0IG11c3Qgbm90IGxhbmQgb24gYSBsb2cgdGhlIHJlcGxheSBuZXZlclxuICAgICAgICAgIC8vIHNhdy4gUmVqZWN0aW5nIGl0IGlzIGNoZWFwIOKAlCBhIHJ1biB3aXRoIGF0dHJpYnV0ZSBldmVudHMgYWxyZWFkeVxuICAgICAgICAgIC8vIGZvcmNlcyBhbiBpbi1wcm9jZXNzIHJlcGxheSwgc28gdGhlIHJlc3RhcnQgY29zdHMgdGhlIHJlcGxheSBpdFxuICAgICAgICAgIC8vIHdhcyBnb2luZyB0byBkbyBhbnl3YXkuXG4gICAgICAgICAgYXdhaXQgY3JlYXRlR3VhcmRlZChcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZXZlbnRUeXBlOiAnYXR0cl9zZXQnLFxuICAgICAgICAgICAgICBzcGVjVmVyc2lvbjogU1BFQ19WRVJTSU9OX0NVUlJFTlQsXG4gICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICBldmVudERhdGE6IHtcbiAgICAgICAgICAgICAgICBjaGFuZ2VzOiBxdWV1ZUl0ZW0uY2hhbmdlcyxcbiAgICAgICAgICAgICAgICB3cml0ZXI6IHsgdHlwZTogJ3dvcmtmbG93JyB9LFxuICAgICAgICAgICAgICAgIC4uLihxdWV1ZUl0ZW0uYWxsb3dSZXNlcnZlZEF0dHJpYnV0ZXNcbiAgICAgICAgICAgICAgICAgID8geyBhbGxvd1Jlc2VydmVkQXR0cmlidXRlczogdHJ1ZSB9XG4gICAgICAgICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IHJlcXVlc3RJZCB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgaWYgKEVudGl0eUNvbmZsaWN0RXJyb3IuaXMoZXJyKSkge1xuICAgICAgICAgICAgcnVudGltZUxvZ2dlci5pbmZvKFxuICAgICAgICAgICAgICAnV29ya2Zsb3cgYXR0cmlidXRlIGV2ZW50IGFscmVhZHkgZXhpc3RzLCBjb250aW51aW5nJyxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJ1bklkLFxuICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uSWQ6IHF1ZXVlSXRlbS5jb3JyZWxhdGlvbklkLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGVyci5tZXNzYWdlLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaXNXb3JsZFZhbGlkYXRpb25GYWlsdXJlKGVycikpIHtcbiAgICAgICAgICAgIC8vIERldGVybWluaXN0aWMgdmFsaWRhdGlvbiByZWplY3Rpb24gZnJvbSB0aGUgV29ybGQg4oCUIGUuZy4gdGhlXG4gICAgICAgICAgICAvLyBjdW11bGF0aXZlIHBlci1ydW4gYXR0cmlidXRlIGNhcCwgd2hpY2ggb25seSB0aGUgV29ybGQgY2FuXG4gICAgICAgICAgICAvLyBjaGVjayBhZ2FpbnN0IHRoZSBydW4ncyBleGlzdGluZyBhdHRyaWJ1dGVzLiBSZWRlbGl2ZXJpbmcgdGhlXG4gICAgICAgICAgICAvLyBvcmNoZXN0cmF0b3IgbWVzc2FnZSByZXBsYXlzIHRoZSB3b3JrZmxvdyBpbnRvIHRoZSBleGFjdCBzYW1lXG4gICAgICAgICAgICAvLyB3cml0ZSBhbmQgdGhlIGV4YWN0IHNhbWUgcmVqZWN0aW9uLCBzbyByZXRyeWluZyBjYW4gbmV2ZXJcbiAgICAgICAgICAgIC8vIHN1Y2NlZWQuIFN1cmZhY2UgaXQgYXMgYSBGYXRhbEVycm9yIHNvIHRoZSBjYWxsZXIgZmFpbHMgdGhlXG4gICAgICAgICAgICAvLyBydW4gd2l0aCBhIGNsZWFyIGVycm9yIGluc3RlYWQgb2Ygd2VkZ2luZyBpdCBpbiByZWRlbGl2ZXJ5LlxuICAgICAgICAgICAgY29uc3QgZmF0YWwgPSBuZXcgRmF0YWxFcnJvcihcbiAgICAgICAgICAgICAgYHNldEF0dHJpYnV0ZXMgZmFpbGVkIFdvcmxkIHZhbGlkYXRpb246ICR7XG4gICAgICAgICAgICAgICAgZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpXG4gICAgICAgICAgICAgIH1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgZmF0YWwuY2F1c2UgPSBlcnI7XG4gICAgICAgICAgICB0aHJvdyBmYXRhbDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSkoKVxuICAgICk7XG4gIH1cblxuICAvLyBBd2FpdCB0aGUgc3RlcF9jcmVhdGVkIC8gd2FpdF9jcmVhdGVkIGV2ZW50IGNyZWF0ZXMgYmVmb3JlIHJldHVybmluZy5cbiAgLy8gVGhlIGNhbGxlciAod29ya2Zsb3dFbnRyeXBvaW50KSBvbmx5IGVucXVldWVzIHRoZSBzdGVwLWRpc3BhdGNoIHF1ZXVlXG4gIC8vIG1lc3NhZ2VzIEFGVEVSIGhhbmRsZVN1c3BlbnNpb24gcmVzb2x2ZXMsIGFuZCB0aGUgcXVldWUgaGFuZGxlciBhY2tzXG4gIC8vIHRoZSBvcmNoZXN0cmF0b3IgbWVzc2FnZSBvbmx5IGFmdGVyIHRoZSBjYWxsZXIgcmVzb2x2ZXMuIFNvIHRoZSBzdGVwX2NyZWF0ZWRcbiAgLy8gZXZlbnRzIG11c3QgYmUgZHVyYWJsZSBoZXJlLCBhbmQgdGhlIGRpc3BhdGNoIHNlbmRzIG11c3QgY29tcGxldGUgaW4gdGhlIGNhbGxlcixcbiAgLy8gYWxsIGJlZm9yZSBhY2suIElmIHRoZSBwcm9jZXNzIGNyYXNoZXMgYmVmb3JlIHRoaXMgcmVzb2x2ZXMsIHRoZSBvcmNoZXN0cmF0b3JcbiAgLy8gbWVzc2FnZSBpcyBub3QgYWNrZWQgYW5kIFZRUyByZWRlbGl2ZXJzLCByZS1jcmVhdGVzIHRoZSAoaWRlbXBvdGVudClcbiAgLy8gc3RlcF9jcmVhdGVkIGFuZCByZS1kaXNwYXRjaGVzLCBhbmQgcmVjb3ZlcnMgdGhlIHJ1biBpbnN0ZWFkIG9mIG9ycGhhbmluZyBpdC5cbiAgYXdhaXQgc2V0dGxlUGhhc2Uob3BzKTtcblxuICAvLyBUaGUgc3RlcC1pbnB1dCBkZWh5ZHJhdGlvbnMgYWJvdmUgaGF2ZSBzZXR0bGVkLCBzbyB0aGUgc2luayBpcyBmaW5hbC5cbiAgY29uc3QgcmV0YWluZWRTdGVwSW5wdXRzU2FmZSA9IGd1ZXN0Q29kZVN0YXRzLmV4ZWN1dGlvbnMubGVuZ3RoID09PSAwO1xuICBpZiAoIXJldGFpbmVkU3RlcElucHV0c1NhZmUpIHtcbiAgICBydW50aW1lTG9nZ2VyLmRlYnVnKFxuICAgICAgJ1NlcmlhbGl6aW5nIHN0ZXAgaW5wdXRzIGV4ZWN1dGVkIHdvcmtmbG93IGNvZGU7IGZhbGxpbmcgYmFjayB0byByZXBsYXkgaW5zdGVhZCBvZiByZXRhaW5pbmcgdGhlIFZNJyxcbiAgICAgIHtcbiAgICAgICAgd29ya2Zsb3dSdW5JZDogcnVuSWQsXG4gICAgICAgIGV4ZWN1dGlvbnM6IGd1ZXN0Q29kZVN0YXRzLmV4ZWN1dGlvbnNcbiAgICAgICAgICAuc2xpY2UoMCwgNSlcbiAgICAgICAgICAubWFwKChlKSA9PiAoZS5kZXRhaWwgPyBgJHtlLmtpbmR9KCR7ZS5kZXRhaWx9KWAgOiBlLmtpbmQpKSxcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLy8gUmVidWlsZCB0aGUgaW5saW5lIGJhdGNoIGluIGRldGVybWluaXN0aWMgb3JkZXIuIGBsYXp5SW5saW5lQ29ycmVsYXRpb25JZHNgXG4gIC8vIGlzIGEgU2V0IHNlZWRlZCBmcm9tIHRoZSBvcmRlcmVkIGZpcnN0LU4gc2xpY2UsIHNvIGl0ZXJhdGluZyBpdCBwcmVzZXJ2ZXNcbiAgLy8gc3RlcEl0ZW1zIG9yZGVyOyBldmVyeSBpZCBpbiBpdCB3YXMgc2V0IGJ5IHRoZSBsYXp5IGJyYW5jaCBhYm92ZS5cbiAgY29uc3QgbGF6eUlubGluZVN0ZXBzOiBTdXNwZW5zaW9uSGFuZGxlclJlc3VsdFsnbGF6eUlubGluZVN0ZXBzJ10gPSBbXTtcbiAgZm9yIChjb25zdCBjb3JyZWxhdGlvbklkIG9mIGxhenlJbmxpbmVDb3JyZWxhdGlvbklkcykge1xuICAgIGNvbnN0IGxhenlTdGVwID0gbGF6eUlubGluZUJ5Q29ycmVsYXRpb25JZC5nZXQoY29ycmVsYXRpb25JZCk7XG4gICAgaWYgKGxhenlTdGVwKSBsYXp5SW5saW5lU3RlcHMucHVzaChsYXp5U3RlcCk7XG4gIH1cblxuICAvLyBGaW5kIHRoZSBzb29uZXN0IHBlbmRpbmcgd2FpdCAobWluaW11bSB0aW1lb3V0KVxuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBsZXQgc29vbmVzdFdhaXQ6IHsgc2Vjb25kczogbnVtYmVyOyBjb3JyZWxhdGlvbklkOiBzdHJpbmcgfSB8IHVuZGVmaW5lZDtcbiAgZm9yIChjb25zdCBxdWV1ZUl0ZW0gb2Ygd2FpdEl0ZW1zKSB7XG4gICAgY29uc3QgcmVzdW1lQXRNcyA9IHF1ZXVlSXRlbS5yZXN1bWVBdC5nZXRUaW1lKCk7XG4gICAgY29uc3QgZGVsYXlNcyA9IE1hdGgubWF4KDEwMDAsIHJlc3VtZUF0TXMgLSBub3cpO1xuICAgIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gTWF0aC5jZWlsKGRlbGF5TXMgLyAxMDAwKTtcbiAgICBpZiAoIXNvb25lc3RXYWl0IHx8IHRpbWVvdXRTZWNvbmRzIDwgc29vbmVzdFdhaXQuc2Vjb25kcykge1xuICAgICAgc29vbmVzdFdhaXQgPSB7XG4gICAgICAgIHNlY29uZHM6IHRpbWVvdXRTZWNvbmRzLFxuICAgICAgICBjb3JyZWxhdGlvbklkOiBxdWV1ZUl0ZW0uY29ycmVsYXRpb25JZCxcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgc3Bhbj8uc2V0QXR0cmlidXRlcyh7XG4gICAgLi4uQXR0cmlidXRlLldvcmtmbG93UnVuU3RhdHVzKCd3b3JrZmxvd19zdXNwZW5kZWQnKSxcbiAgICAuLi5BdHRyaWJ1dGUuV29ya2Zsb3dTdGVwc0NyZWF0ZWQoc3RlcEl0ZW1zLmxlbmd0aCksXG4gICAgLi4uQXR0cmlidXRlLldvcmtmbG93SG9va3NDcmVhdGVkKGhvb2tzTmVlZGluZ0NyZWF0aW9uLmxlbmd0aCksXG4gICAgLi4uQXR0cmlidXRlLldvcmtmbG93V2FpdHNDcmVhdGVkKHdhaXRJdGVtcy5sZW5ndGgpLFxuICAgIC4uLihyZXNpbGllbnREaXNwYXRjaFJlY292ZXJlZCA+IDBcbiAgICAgID8gQXR0cmlidXRlLlN0ZXBSZXNpbGllbnREaXNwYXRjaFJlY292ZXJlZChyZXNpbGllbnREaXNwYXRjaFJlY292ZXJlZClcbiAgICAgIDoge30pLFxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIHBlbmRpbmdTdGVwczogc3RlcEl0ZW1zLFxuICAgIGNyZWF0ZWRTdGVwQ29ycmVsYXRpb25JZHMsXG4gICAgcXVldWVkU3RlcENvcnJlbGF0aW9uSWRzLFxuICAgIGxhenlJbmxpbmVTdGVwcyxcbiAgICBpbmxpbmVDbGFpbXMsXG4gICAgYmF0Y2hDb21taXR0ZWRTbG90Q2VpbGluZyxcbiAgICBkZWZlcnJlZEJhdGNoV29yayxcbiAgICAvLyBPbiBob29rIGNvbmZsaWN0IHRoZSBjYWxsZXIgcmUtaW52b2tlcyBpbW1lZGlhdGVseSBhbmQgbmV2ZXIgcmVhZHNcbiAgICAvLyB0aGUgd2FpdCB0aW1lb3V0LCBzbyBkb24ndCByZXBvcnQgb25lLlxuICAgIHdhaXRUaW1lb3V0OiBoYXNIb29rQ29uZmxpY3QgPyB1bmRlZmluZWQgOiBzb29uZXN0V2FpdCxcbiAgICBoYXNIb29rQ29uZmxpY3QsXG4gICAgaGFzQXdhaXRlZEhvb2tDcmVhdGlvbixcbiAgICBoYXNBdHRyaWJ1dGVFdmVudHM6IGF0dHJpYnV0ZUl0ZW1zLmxlbmd0aCA+IDAsXG4gICAgaGFzSG9va0V2ZW50czogaG9va3NOZWVkaW5nQ3JlYXRpb24ubGVuZ3RoID4gMCxcbiAgICBob29rQ3JlYXRpb25NcyxcbiAgICByZXRhaW5lZFN0ZXBJbnB1dHNTYWZlLFxuICAgIHJlcG9ydGVkRXZlbnRDb3VudDogcmVwb3J0ZWRFdmVudHMsXG4gIH07XG59XG5cbi8qKlxuICogV2hldGhlciBhbiBgZXZlbnRzLmNyZWF0ZWAgcmVqZWN0aW9uIGlzIGRldGVybWluaXN0aWMgV29ybGQgdmFsaWRhdGlvblxuICogcmF0aGVyIHRoYW4gYSB0cmFuc2llbnQvc3RvcmFnZSBlcnJvci4gTG9jYWwgV29ybGRzXG4gKiAod29ybGQtbG9jYWwsIHdvcmxkLXBvc3RncmVzKSB0aHJvdyBgQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yYCBkaXJlY3RseTtcbiAqIHJlbW90ZSBXb3JsZHMgc3VyZmFjZSB0aGUgZXF1aXZhbGVudCBzZXJ2ZXItc2lkZSByZWplY3Rpb24gYXMgYVxuICogYFdvcmtmbG93V29ybGRFcnJvcmAgd2l0aCBIVFRQIHN0YXR1cyA0MDAuIFRoZSBuYW1lIGNoZWNrIGNvdmVyc1xuICogYEF0dHJpYnV0ZVZhbGlkYXRpb25FcnJvcmAgaW5zdGFuY2VzIGZyb20gYSBkaWZmZXJlbnQgY29weSBvZlxuICogYEB3b3JrZmxvdy93b3JsZGAgdGhhbiB0aGUgb25lIHRoaXMgcGFja2FnZSByZXNvbHZlZC5cbiAqL1xuZnVuY3Rpb24gaXNXb3JsZFZhbGlkYXRpb25GYWlsdXJlKGVycjogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAoZXJyIGluc3RhbmNlb2YgQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yICYmIGVyci5uYW1lID09PSAnQXR0cmlidXRlVmFsaWRhdGlvbkVycm9yJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBXb3JrZmxvd1dvcmxkRXJyb3IuaXMoZXJyKSAmJiBlcnIuc3RhdHVzID09PSA0MDA7XG59XG4iXX0=
|