cdk-nextjs 0.7.6 → 0.7.7
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/.jsii +3 -3
- package/.jsii.tabl.json +1 -1
- package/README.md +12 -3
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +31 -13
- package/docs/caching-guide.md +11 -1
- package/docs/harness-coverage.md +2 -1
- package/lib/adapter/aws-cache-store.d.ts +214 -3
- package/lib/adapter/aws-cache-store.js +470 -35
- package/lib/adapter/aws-cache-store.test.js +675 -3
- package/lib/adapter/cache-handler.mjs +421 -30
- package/lib/adapter/use-cache-common.d.ts +53 -1
- package/lib/adapter/use-cache-common.js +121 -14
- package/lib/adapter/use-cache-common.test.js +138 -1
- package/lib/adapter/use-cache-default-handler.js +36 -6
- package/lib/adapter/use-cache-default-handler.mjs +525 -42
- package/lib/adapter/use-cache-handlers.test.js +247 -7
- package/lib/adapter/use-cache-remote-handler.js +9 -7
- package/lib/adapter/use-cache-remote-handler.mjs +516 -40
- package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +2 -1
- package/lib/lambdas/post-deploy/prune-revalidation-table.js +35 -13
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +19 -1
- package/lib/nextjs-api.js +1 -1
- package/lib/nextjs-build/nextjs-build.js +1 -1
- package/lib/nextjs-cache.js +1 -1
- package/lib/nextjs-compute/nextjs-containers.js +1 -1
- package/lib/nextjs-compute/nextjs-functions.js +1 -1
- package/lib/nextjs-distribution.js +1 -1
- package/lib/nextjs-post-deploy.js +1 -1
- package/lib/nextjs-static-assets.js +1 -1
- package/lib/root-constructs/nextjs-base-construct.js +1 -1
- package/lib/root-constructs/nextjs-global-containers.js +1 -1
- package/lib/root-constructs/nextjs-global-functions.js +1 -1
- package/lib/root-constructs/nextjs-regional-containers.js +1 -1
- package/lib/root-constructs/nextjs-regional-functions.js +1 -1
- package/lib/runtime/core.js +18 -4
- package/lib/runtime/core.test.js +17 -1
- package/lib/runtime/lambda.mjs +16 -3
- package/lib/runtime/server.mjs +16 -3
- package/lib/runtime/tag-manifest.d.ts +15 -0
- package/lib/runtime/tag-manifest.js +24 -0
- package/lib/runtime/tag-manifest.test.d.ts +1 -0
- package/lib/runtime/tag-manifest.test.js +21 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CacheBucket = exports.TrackedTagMarkers = exports.DEFAULT_MAX_TRACKED_TAGS = exports.MAX_REVALIDATION_LOG_GAP_MS = exports.DEFAULT_TAG_RESYNC_MS = exports.REVALIDATION_LOG_LOOKBACK_MS = exports.RevalidationLog = exports.REVALIDATION_LOG_MAX_PAGES = exports.REVALIDATION_LOG_TTL_MS = exports.TagMarkerTable = exports.MAX_TAG_BYTES = exports.MAX_SORT_KEY_BYTES = exports.DEFAULT_TAG_REFRESH_MS = exports.BATCH_GET_MAX_KEYS = exports.USE_CACHE_KEY_PREFIX = void 0;
|
|
3
|
+
exports.CacheBucket = exports.TrackedTagMarkers = exports.DEFAULT_MAX_TRACKED_TAGS = exports.MAX_REVALIDATION_LOG_GAP_MS = exports.DEFAULT_TAG_RESYNC_MS = exports.REVALIDATION_LOG_LOOKBACK_MS = exports.RevalidationLog = exports.REVALIDATION_LOG_MAX_PAGES = exports.REVALIDATION_LOG_TTL_MS = exports.TagMarkerTable = exports.MAX_TAG_BYTES = exports.MAX_SORT_KEY_BYTES = exports.TAG_REFRESH_GRACE_MS = exports.DEFAULT_TAG_REFRESH_MS = exports.BATCH_GET_MAX_KEYS = exports.USE_CACHE_KEY_PREFIX = void 0;
|
|
4
4
|
exports.resolveAwsCacheConfig = resolveAwsCacheConfig;
|
|
5
5
|
exports.buildS3Key = buildS3Key;
|
|
6
6
|
exports.s3ObjectKey = s3ObjectKey;
|
|
@@ -24,6 +24,7 @@ exports.mergeMarkers = mergeMarkers;
|
|
|
24
24
|
kinds of handler, and they must read each other's markers the same way.
|
|
25
25
|
*/
|
|
26
26
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
27
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
27
28
|
const node_path_1 = require("node:path");
|
|
28
29
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
29
30
|
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
@@ -164,6 +165,13 @@ exports.BATCH_GET_MAX_KEYS = 100;
|
|
|
164
165
|
* revalidation log, the reads scale with instances instead of requests or tags.
|
|
165
166
|
*/
|
|
166
167
|
exports.DEFAULT_TAG_REFRESH_MS = 1000;
|
|
168
|
+
/**
|
|
169
|
+
* How far past `refreshIntervalMs` the last refresh may have settled before a
|
|
170
|
+
* `'use cache'` request waits for the next one (see
|
|
171
|
+
* {@link TrackedTagMarkers.behind}). An instance serving steady traffic stays
|
|
172
|
+
* inside it; one that sat idle, or frozen between Lambda invocations, does not.
|
|
173
|
+
*/
|
|
174
|
+
exports.TAG_REFRESH_GRACE_MS = 1000;
|
|
167
175
|
/** DynamoDB's limit on a sort key, in UTF-8 bytes. */
|
|
168
176
|
exports.MAX_SORT_KEY_BYTES = 1024;
|
|
169
177
|
/**
|
|
@@ -464,15 +472,19 @@ exports.DEFAULT_MAX_TRACKED_TAGS = 10_000;
|
|
|
464
472
|
* The cost is bounded per instance, not per request:
|
|
465
473
|
* - {@link ensure} reads a tag's marker the first time it is needed and not
|
|
466
474
|
* again until it is evicted, so a tag costs one read per instance, not one
|
|
467
|
-
* per request.
|
|
475
|
+
* per request. An entry created since {@link completeSince} needs no read
|
|
476
|
+
* at all.
|
|
468
477
|
* - {@link refresh}, at most once per `refreshIntervalMs`, sends one `Query`
|
|
469
478
|
* for the log rows written since the last one, and applies those of tags
|
|
470
479
|
* this instance tracks. Concurrent callers share it. Alongside, it re-reads
|
|
471
480
|
* the markers of up to {@link BATCH_GET_MAX_KEYS} tags not read for
|
|
472
481
|
* {@link DEFAULT_TAG_RESYNC_MS}, in one `BatchGetItem`.
|
|
473
482
|
* A revalidation on another instance is therefore seen within
|
|
474
|
-
* `refreshIntervalMs` (plus the query itself)
|
|
475
|
-
*
|
|
483
|
+
* `refreshIntervalMs` (plus the query itself) - by `'use cache'`, from the
|
|
484
|
+
* first request after the query returns, since its `refreshTags` does not wait
|
|
485
|
+
* for it (see `tagMethods`) unless the instance is {@link behind}, which the
|
|
486
|
+
* runtime settles before a page render starts ({@link catchUp}). The instance
|
|
487
|
+
* that ran it applies it itself, at once, with {@link set}.
|
|
476
488
|
*/
|
|
477
489
|
class TrackedTagMarkers {
|
|
478
490
|
markers;
|
|
@@ -498,10 +510,64 @@ class TrackedTagMarkers {
|
|
|
498
510
|
* result rather than dropped.
|
|
499
511
|
*/
|
|
500
512
|
pendingRows = new Map();
|
|
513
|
+
/**
|
|
514
|
+
* Log rows for tags not tracked and not being read, merged by tag, oldest
|
|
515
|
+
* first: what the log has said about them since {@link completeSince}. Taken
|
|
516
|
+
* into a tag's marker when it is read or written.
|
|
517
|
+
*/
|
|
518
|
+
logOnly = new Map();
|
|
519
|
+
/** See {@link completeSince}. */
|
|
520
|
+
floor;
|
|
521
|
+
/**
|
|
522
|
+
* The future `expiredAt`s of markers dropped since, as `[from, to]`, in
|
|
523
|
+
* order: once `from` is past, {@link completeSince} moves to `to`, and not
|
|
524
|
+
* before, since only then does it expire anything. `from` and `to` are the
|
|
525
|
+
* same until spans are merged for space ({@link laterFloor}).
|
|
526
|
+
*/
|
|
527
|
+
laterFloors = [];
|
|
528
|
+
/** The in-memory entry stores judged by {@link completeSince}. */
|
|
529
|
+
entryStores = [];
|
|
530
|
+
/** How many times {@link forget} ran: a read started before one is made again. */
|
|
531
|
+
forgotten = 0;
|
|
501
532
|
/** Tracked tags whose read failed, for the next refresh to read again. */
|
|
502
533
|
unread = new Set();
|
|
534
|
+
/**
|
|
535
|
+
* Set inside a page render {@link catchUp} let go, for that render alone.
|
|
536
|
+
* See {@link behindInRender}.
|
|
537
|
+
*/
|
|
538
|
+
caughtUpRender = new node_async_hooks_1.AsyncLocalStorage();
|
|
539
|
+
/** When `sync` last scanned the entry stores ({@link oldestEntry}). */
|
|
540
|
+
lastEntryScan = -Infinity;
|
|
541
|
+
/**
|
|
542
|
+
* No `logOnly` row is known by it or earlier, so a {@link pruneLogged}
|
|
543
|
+
* against it or earlier drops nothing: a marker is only ever known by later,
|
|
544
|
+
* as its `expiredAt` passes.
|
|
545
|
+
*/
|
|
546
|
+
prunedAgainst = -Infinity;
|
|
547
|
+
/** When the last refresh started, or was skipped. */
|
|
503
548
|
lastRefresh = -Infinity;
|
|
549
|
+
/**
|
|
550
|
+
* The refresh in flight. One left open across a freeze comes back after the
|
|
551
|
+
* thaw with what it read before, so {@link refresh} waits for it and then
|
|
552
|
+
* for a fresh one, rather than the runtime waiting for it before the freeze:
|
|
553
|
+
* that would bill every Lambda invocation for the query's tail.
|
|
554
|
+
*/
|
|
504
555
|
refreshing;
|
|
556
|
+
/**
|
|
557
|
+
* When {@link refreshing} last showed the process running: a timer ticks
|
|
558
|
+
* while it is in flight, and a tick that comes late, or none at all, means
|
|
559
|
+
* the process was paused - frozen - since it started.
|
|
560
|
+
*/
|
|
561
|
+
lastTick = -Infinity;
|
|
562
|
+
/** Whether a tick came late since {@link refreshing} started. */
|
|
563
|
+
pausedWhileRefreshing = false;
|
|
564
|
+
ticker;
|
|
565
|
+
canFreeze;
|
|
566
|
+
/**
|
|
567
|
+
* When the last refresh settled, either way, unless it spanned a pause: what
|
|
568
|
+
* it knows is from then. See {@link behind}.
|
|
569
|
+
*/
|
|
570
|
+
settledAt;
|
|
505
571
|
/**
|
|
506
572
|
* Where the next log query starts (`clock()`): the last successful one's
|
|
507
573
|
* start, less {@link REVALIDATION_LOG_LOOKBACK_MS}.
|
|
@@ -525,22 +591,70 @@ class TrackedTagMarkers {
|
|
|
525
591
|
this.clock = options.clock ?? (() => Date.now());
|
|
526
592
|
this.random = options.random ?? Math.random;
|
|
527
593
|
this.debug = options.debug ?? (() => { });
|
|
594
|
+
this.canFreeze = options.canFreeze ?? false;
|
|
528
595
|
// Nothing is tracked yet, so nothing before this can be missed: every tag
|
|
529
596
|
// is read from its marker the first time it is needed.
|
|
530
597
|
const at = this.clock();
|
|
531
598
|
this.cursor = at - exports.REVALIDATION_LOG_LOOKBACK_MS;
|
|
532
599
|
this.lastLogRead = at;
|
|
600
|
+
this.settledAt = at;
|
|
601
|
+
this.floor = markerClock();
|
|
533
602
|
}
|
|
534
603
|
/** `tag`'s marker as this instance knows it, if it tracks `tag`. */
|
|
535
604
|
get(tag) {
|
|
536
605
|
return this.tags.get(tag);
|
|
537
606
|
}
|
|
607
|
+
/**
|
|
608
|
+
* Since when (`markerClock()`) this instance knows of every revalidation of
|
|
609
|
+
* every tag, tracked or not: tracked ones from their markers and the log,
|
|
610
|
+
* the others from the log alone (`logOnly`). So an entry created at or after
|
|
611
|
+
* it can be judged by {@link state} and {@link expiration} without
|
|
612
|
+
* {@link ensure} reading anything - which matters inside a `'use cache'`
|
|
613
|
+
* lookup, where Next.js waits for the answer and a read pushes the entry out
|
|
614
|
+
* of the static stage of a staged render.
|
|
615
|
+
*
|
|
616
|
+
* Starts at construction: the log is followed from before it. Moves to now
|
|
617
|
+
* when the tracked markers are forgotten, and past the revalidations of
|
|
618
|
+
* whatever else it lets go of - a marker evicted for space, a log row
|
|
619
|
+
* pruned - which are no longer known: to its `expiredAt` only once that is
|
|
620
|
+
* past, since a profile's `expire` can be a year out, and moving there at
|
|
621
|
+
* once would turn the read-free path off for the instance's life.
|
|
622
|
+
*
|
|
623
|
+
* A row is pruned only once it is no later than every entry held, so that
|
|
624
|
+
* costs those entries nothing. An entry stored afterwards with an older
|
|
625
|
+
* `timestamp` - Next.js stamps the start of its generation, which can
|
|
626
|
+
* outlast a lookback - is older than this too, and is read first.
|
|
627
|
+
*
|
|
628
|
+
* It does not cover a revalidation older than the log's first lookback
|
|
629
|
+
* whose `expiredAt` is still to come, which would expire an entry created
|
|
630
|
+
* after it. So the `'use cache'` handler reads an entry's tags in the
|
|
631
|
+
* background as it stores it.
|
|
632
|
+
*/
|
|
633
|
+
get completeSince() {
|
|
634
|
+
const at = markerClock();
|
|
635
|
+
while (this.laterFloors.length > 0 && this.laterFloors[0][0] <= at) {
|
|
636
|
+
this.floor = Math.max(this.floor, this.laterFloors.shift()[1]);
|
|
637
|
+
}
|
|
638
|
+
return this.floor;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Register an in-memory store whose entries are judged by
|
|
642
|
+
* {@link completeSince}, by the `timestamp` of the oldest entry it holds:
|
|
643
|
+
* `logOnly` keeps the rows that could still apply to one of them, and no
|
|
644
|
+
* others. With none registered it keeps nothing. Asked with `scan` false,
|
|
645
|
+
* `oldestTimestamp` may answer early, but never late, without a scan.
|
|
646
|
+
*/
|
|
647
|
+
judgeEntriesOf(oldestTimestamp, holdsAny = () => oldestTimestamp(false) < Infinity) {
|
|
648
|
+
this.entryStores.push({ oldestTimestamp, holdsAny });
|
|
649
|
+
}
|
|
538
650
|
/**
|
|
539
651
|
* Track `tag` with `marker`: what this instance just wrote, which it knows
|
|
540
652
|
* without reading it back.
|
|
541
653
|
*/
|
|
542
654
|
set(tag, marker) {
|
|
543
|
-
this.
|
|
655
|
+
const logged = this.logOnly.get(tag);
|
|
656
|
+
this.logOnly.delete(tag);
|
|
657
|
+
this.remember(tag, mergeMarkers(marker, logged));
|
|
544
658
|
this.known(tag, this.clock());
|
|
545
659
|
}
|
|
546
660
|
/**
|
|
@@ -592,31 +706,117 @@ class TrackedTagMarkers {
|
|
|
592
706
|
const waits = [];
|
|
593
707
|
const unread = [];
|
|
594
708
|
for (const tag of new Set(tags)) {
|
|
709
|
+
// Tracked first: a tracked tag in `reading` is only being re-read in
|
|
710
|
+
// the background (`sync`), which nothing needs to wait for.
|
|
595
711
|
const inFlight = this.reading.get(tag);
|
|
596
|
-
if (
|
|
597
|
-
waits.push(inFlight);
|
|
598
|
-
}
|
|
599
|
-
else if (this.tags.has(tag)) {
|
|
712
|
+
if (this.tags.has(tag)) {
|
|
600
713
|
this.touch(tag);
|
|
601
714
|
}
|
|
715
|
+
else if (inFlight) {
|
|
716
|
+
waits.push(inFlight);
|
|
717
|
+
}
|
|
602
718
|
else {
|
|
603
719
|
unread.push(tag);
|
|
604
720
|
}
|
|
605
721
|
}
|
|
606
722
|
if (unread.length > 0) {
|
|
607
|
-
|
|
608
|
-
const read = this.readInto(unread).then(() => {
|
|
609
|
-
for (const tag of unread) {
|
|
610
|
-
this.reading.delete(tag);
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
for (const tag of unread) {
|
|
614
|
-
this.reading.set(tag, read);
|
|
615
|
-
}
|
|
616
|
-
waits.push(read);
|
|
723
|
+
waits.push(this.startRead(unread));
|
|
617
724
|
}
|
|
618
725
|
await Promise.all(waits);
|
|
619
726
|
}
|
|
727
|
+
/**
|
|
728
|
+
* {@link readInto} `tags`, as the read of each that whoever needs one of
|
|
729
|
+
* them next waits on ({@link reading}). Never rejects: a failed read leaves
|
|
730
|
+
* the tags tracked.
|
|
731
|
+
*/
|
|
732
|
+
startRead(tags) {
|
|
733
|
+
const read = this.readInto(tags).then(() => {
|
|
734
|
+
for (const tag of tags) {
|
|
735
|
+
this.reading.delete(tag);
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
for (const tag of tags) {
|
|
739
|
+
this.reading.set(tag, read);
|
|
740
|
+
}
|
|
741
|
+
return read;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Whether the last refresh settled more than `refreshIntervalMs` plus
|
|
745
|
+
* {@link TAG_REFRESH_GRACE_MS} ago - one that spanned a freeze counts from
|
|
746
|
+
* when it started: after the instance sat idle or frozen - or always, with
|
|
747
|
+
* a `refreshIntervalMs` of `0`. Answering from what it knows then could
|
|
748
|
+
* serve an entry revalidated elsewhere since, however long ago that was, so
|
|
749
|
+
* `refreshTags` waits for the refresh, and the runtime waits for it before
|
|
750
|
+
* a page render starts ({@link catchUp}).
|
|
751
|
+
*
|
|
752
|
+
* From when it settled, not when it started, so a slow query the runtime
|
|
753
|
+
* waited for before the render does not leave the instance behind inside
|
|
754
|
+
* it. A failed one counts too, so one request does not wait for two: the
|
|
755
|
+
* same "assume the entry is valid" a failed read answers with, until the
|
|
756
|
+
* next refresh, at most the interval and the grace later.
|
|
757
|
+
*/
|
|
758
|
+
get behind() {
|
|
759
|
+
return (this.log !== undefined &&
|
|
760
|
+
// `0` asks before every check, so every check waits for the answer.
|
|
761
|
+
(this.refreshIntervalMs === 0 || this.overdue(this.settledAt)));
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* {@link behind}, as `refreshTags` asks it: never inside a page's render
|
|
765
|
+
* {@link catchUp} caught up, since the runtime settled it for that request
|
|
766
|
+
* before the render started, and a wait inside a `'use cache'` lookup is
|
|
767
|
+
* what it settled it to avoid - a render crossing the line partway through
|
|
768
|
+
* would otherwise wait after all. So a revalidation elsewhere can go unseen
|
|
769
|
+
* for a render's duration on top of the usual window.
|
|
770
|
+
*
|
|
771
|
+
* A route handler, which no catch-up precedes, waits at the plain line.
|
|
772
|
+
*/
|
|
773
|
+
get behindInRender() {
|
|
774
|
+
return this.refreshIntervalMs !== 0 && this.caughtUpRender.getStore()
|
|
775
|
+
? false
|
|
776
|
+
: this.behind;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Whether a registered store ({@link judgeEntriesOf}) holds any entry: one
|
|
780
|
+
* a refresh could expire. With none there is nothing to wait for even when
|
|
781
|
+
* the instance is {@link behind}, since whatever is stored from here on is
|
|
782
|
+
* newer than what the log would say - which covers the first `'use cache'`
|
|
783
|
+
* call of a process, which creates the handler inside the render.
|
|
784
|
+
*/
|
|
785
|
+
get holdsEntries() {
|
|
786
|
+
return this.entryStores.some((store) => store.holdsAny());
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* {@link refresh}, waited for when the instance is {@link behind}. The
|
|
790
|
+
* runtime calls it before handing a page request to Next.js, outside the
|
|
791
|
+
* staged render whose static stage a wait inside a `'use cache'` lookup
|
|
792
|
+
* would cut short. Only for the `'use cache'` handler's entries
|
|
793
|
+
* ({@link judgeEntriesOf}): the other caches wait for the refresh where they
|
|
794
|
+
* read anyway. Not with a `refreshIntervalMs` of `0` either, where
|
|
795
|
+
* `refreshTags` asks again regardless. Then `render`, marked as caught up
|
|
796
|
+
* for ({@link behindInRender}). Rejects only as `render` does.
|
|
797
|
+
*/
|
|
798
|
+
async catchUp(render) {
|
|
799
|
+
const log = (error) => console.error("Error refreshing cache tags:", error);
|
|
800
|
+
if (this.refreshIntervalMs > 0 && this.behind) {
|
|
801
|
+
if (!this.holdsEntries) {
|
|
802
|
+
// Not caught up, so no grace: an entry stored meanwhile, by another
|
|
803
|
+
// request, makes the render's lookups wait at the plain line.
|
|
804
|
+
return render();
|
|
805
|
+
}
|
|
806
|
+
await this.refresh().catch(log);
|
|
807
|
+
}
|
|
808
|
+
else if (this.refreshIntervalMs > 0) {
|
|
809
|
+
// Started, not waited for, as `refreshTags` would: a page that reads
|
|
810
|
+
// no cache keeps the instance current too, rather than falling behind
|
|
811
|
+
// and making a later request wait.
|
|
812
|
+
void this.refresh().catch(log);
|
|
813
|
+
}
|
|
814
|
+
return this.caughtUpRender.run(true, render);
|
|
815
|
+
}
|
|
816
|
+
/** Whether `at` is more than the interval and the grace ago. */
|
|
817
|
+
overdue(at) {
|
|
818
|
+
return this.clock() - at > this.refreshIntervalMs + exports.TAG_REFRESH_GRACE_MS;
|
|
819
|
+
}
|
|
620
820
|
/**
|
|
621
821
|
* Catch up on revalidations other instances ran, at most once per
|
|
622
822
|
* `refreshIntervalMs`. See {@link TrackedTagMarkers} for the cost.
|
|
@@ -627,6 +827,12 @@ class TrackedTagMarkers {
|
|
|
627
827
|
return;
|
|
628
828
|
}
|
|
629
829
|
if (this.refreshing) {
|
|
830
|
+
// One started before a freeze read the log as it was then, and says
|
|
831
|
+
// nothing of what ran meanwhile: an instance behind waits for a fresh
|
|
832
|
+
// one, after it. One that is merely slow is as fresh as any.
|
|
833
|
+
if (this.behind && this.pausedSinceRefreshStarted()) {
|
|
834
|
+
return this.refreshing.then(() => this.refresh());
|
|
835
|
+
}
|
|
630
836
|
return this.refreshing;
|
|
631
837
|
}
|
|
632
838
|
const at = this.clock();
|
|
@@ -635,15 +841,55 @@ class TrackedTagMarkers {
|
|
|
635
841
|
}
|
|
636
842
|
this.lastRefresh = at;
|
|
637
843
|
// Whatever gets tracked before the next refresh is read from its marker,
|
|
638
|
-
// so there is nothing to catch up on yet
|
|
639
|
-
|
|
844
|
+
// so there is nothing to catch up on yet - unless an entry is judged by
|
|
845
|
+
// `completeSince`, which relies on the log for every tag. Even with none
|
|
846
|
+
// held: a row let go of then moves `completeSince` past it, for an entry
|
|
847
|
+
// whose generation started before that revalidation and that is stored
|
|
848
|
+
// after it.
|
|
849
|
+
if (this.tags.size === 0 && this.entryStores.length === 0) {
|
|
640
850
|
return;
|
|
641
851
|
}
|
|
852
|
+
this.startTicking();
|
|
642
853
|
this.refreshing = this.sync(at, log).finally(() => {
|
|
854
|
+
// One that spanned a pause knows the log as of its start at best. So
|
|
855
|
+
// does one that only looked paused, its event loop held up: it counts
|
|
856
|
+
// as no older than its start, as if it had not settled since.
|
|
857
|
+
this.settledAt = Math.max(this.settledAt, this.pausedSinceRefreshStarted() ? this.lastRefresh : this.clock());
|
|
858
|
+
this.stopTicking();
|
|
643
859
|
this.refreshing = undefined;
|
|
644
860
|
});
|
|
645
861
|
return this.refreshing;
|
|
646
862
|
}
|
|
863
|
+
startTicking() {
|
|
864
|
+
if (!this.canFreeze) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
this.lastTick = this.clock();
|
|
868
|
+
this.pausedWhileRefreshing = false;
|
|
869
|
+
this.ticker = setInterval(() => {
|
|
870
|
+
const at = this.clock();
|
|
871
|
+
if (at - this.lastTick > REFRESH_PAUSE_MS) {
|
|
872
|
+
this.pausedWhileRefreshing = true;
|
|
873
|
+
}
|
|
874
|
+
this.lastTick = at;
|
|
875
|
+
}, REFRESH_TICK_MS);
|
|
876
|
+
// Never what keeps a process alive.
|
|
877
|
+
this.ticker.unref?.();
|
|
878
|
+
}
|
|
879
|
+
stopTicking() {
|
|
880
|
+
clearInterval(this.ticker);
|
|
881
|
+
this.ticker = undefined;
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Whether the process was paused since {@link refreshing} started: a tick
|
|
885
|
+
* came late, or the next one is overdue (after a thaw, a request can run
|
|
886
|
+
* before the timer does).
|
|
887
|
+
*/
|
|
888
|
+
pausedSinceRefreshStarted() {
|
|
889
|
+
return (this.canFreeze &&
|
|
890
|
+
(this.pausedWhileRefreshing ||
|
|
891
|
+
this.clock() - this.lastTick > REFRESH_PAUSE_MS));
|
|
892
|
+
}
|
|
647
893
|
/**
|
|
648
894
|
* Record a revalidation of `tags`: here at once, and in the revalidation
|
|
649
895
|
* table for every other instance - the marker row plus a log row per tag.
|
|
@@ -681,7 +927,7 @@ class TrackedTagMarkers {
|
|
|
681
927
|
const at = markerClock();
|
|
682
928
|
let state = "fresh";
|
|
683
929
|
for (const tag of tags) {
|
|
684
|
-
const marker = this.
|
|
930
|
+
const marker = this.knownMarker(tag);
|
|
685
931
|
if (!marker) {
|
|
686
932
|
continue;
|
|
687
933
|
}
|
|
@@ -705,7 +951,7 @@ class TrackedTagMarkers {
|
|
|
705
951
|
const at = markerClock();
|
|
706
952
|
let latest = 0;
|
|
707
953
|
for (const tag of tags) {
|
|
708
|
-
const marker = this.
|
|
954
|
+
const marker = this.knownMarker(tag);
|
|
709
955
|
if (!marker) {
|
|
710
956
|
continue;
|
|
711
957
|
}
|
|
@@ -787,13 +1033,17 @@ class TrackedTagMarkers {
|
|
|
787
1033
|
this.forget(at, "the revalidation log may not cover the gap since it was last read");
|
|
788
1034
|
return;
|
|
789
1035
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
this.
|
|
796
|
-
|
|
1036
|
+
// The rolling re-read runs alongside, not waited for: catching up needs
|
|
1037
|
+
// only the log, and a throttled `BatchGetItem` should not hold the
|
|
1038
|
+
// request `catchUp` makes wait. A forget meanwhile reads it again.
|
|
1039
|
+
const due = this.due(at);
|
|
1040
|
+
if (due.length > 0) {
|
|
1041
|
+
void this.startRead(due);
|
|
1042
|
+
}
|
|
1043
|
+
const result = await log.query(this.cursor).catch((error) => {
|
|
1044
|
+
console.error("Error reading tag revalidation log:", error);
|
|
1045
|
+
return undefined;
|
|
1046
|
+
});
|
|
797
1047
|
if (!result) {
|
|
798
1048
|
return;
|
|
799
1049
|
}
|
|
@@ -801,6 +1051,15 @@ class TrackedTagMarkers {
|
|
|
801
1051
|
this.forget(at, "the revalidation log has more rows than one query reads");
|
|
802
1052
|
return;
|
|
803
1053
|
}
|
|
1054
|
+
// A scan of every entry held, which also drops the expired ones, once in
|
|
1055
|
+
// a while: so expired entries never read again don't pile up ahead of
|
|
1056
|
+
// live ones. In between, the stores answer early without one, which only
|
|
1057
|
+
// keeps rows in `logOnly` a little longer.
|
|
1058
|
+
const scan = at - this.lastEntryScan > ENTRY_SCAN_INTERVAL_MS;
|
|
1059
|
+
if (scan) {
|
|
1060
|
+
this.lastEntryScan = at;
|
|
1061
|
+
}
|
|
1062
|
+
const oldest = this.oldestEntry(scan);
|
|
804
1063
|
let applied = 0;
|
|
805
1064
|
for (const row of result.rows) {
|
|
806
1065
|
if (this.applied.has(row.sk)) {
|
|
@@ -826,11 +1085,19 @@ class TrackedTagMarkers {
|
|
|
826
1085
|
// rolling re-read. Left unmarked, the next refresh applies it to
|
|
827
1086
|
// whatever that read found; it costs no read, only the row being
|
|
828
1087
|
// looked at again while it is inside the lookback.
|
|
1088
|
+
//
|
|
1089
|
+
// Kept meanwhile in `logOnly`, which is all `completeSince` needs.
|
|
1090
|
+
this.rememberLogged(row.tag, mergeMarkers(this.logOnly.get(row.tag), row.marker), oldest);
|
|
829
1091
|
continue;
|
|
830
1092
|
}
|
|
831
1093
|
this.applied.set(row.sk, row.at);
|
|
832
1094
|
applied++;
|
|
833
1095
|
}
|
|
1096
|
+
if (oldest > this.prunedAgainst) {
|
|
1097
|
+
this.pruneLogged(oldest);
|
|
1098
|
+
}
|
|
1099
|
+
// The rows just kept are known by later than `oldest` too.
|
|
1100
|
+
this.prunedAgainst = oldest;
|
|
834
1101
|
this.lastLogRead = at;
|
|
835
1102
|
this.advance(at - exports.REVALIDATION_LOG_LOOKBACK_MS);
|
|
836
1103
|
this.debug(`read ${result.rows.length} revalidation log rows (${applied} applied)`);
|
|
@@ -845,7 +1112,9 @@ class TrackedTagMarkers {
|
|
|
845
1112
|
for (const tag of this.unread) {
|
|
846
1113
|
if (due.length >= exports.BATCH_GET_MAX_KEYS)
|
|
847
1114
|
return due;
|
|
848
|
-
|
|
1115
|
+
if (!this.reading.has(tag)) {
|
|
1116
|
+
due.push(tag);
|
|
1117
|
+
}
|
|
849
1118
|
}
|
|
850
1119
|
// Known in time order, and each due at most `jitter` earlier than the
|
|
851
1120
|
// tags after it: past a tag due more than that from now, none is due.
|
|
@@ -854,7 +1123,7 @@ class TrackedTagMarkers {
|
|
|
854
1123
|
if (due.length >= exports.BATCH_GET_MAX_KEYS || dueAt - jitter > at) {
|
|
855
1124
|
break;
|
|
856
1125
|
}
|
|
857
|
-
if (dueAt <= at && !this.unread.has(tag)) {
|
|
1126
|
+
if (dueAt <= at && !this.unread.has(tag) && !this.reading.has(tag)) {
|
|
858
1127
|
due.push(tag);
|
|
859
1128
|
}
|
|
860
1129
|
}
|
|
@@ -867,10 +1136,21 @@ class TrackedTagMarkers {
|
|
|
867
1136
|
*/
|
|
868
1137
|
forget(at, why) {
|
|
869
1138
|
this.debug(`forgetting ${this.tags.size} tracked tags: ${why}`);
|
|
1139
|
+
this.forgotten++;
|
|
1140
|
+
// What the markers expire later is still to apply once it is past.
|
|
1141
|
+
for (const marker of this.tags.values()) {
|
|
1142
|
+
this.raiseFloor(marker);
|
|
1143
|
+
}
|
|
1144
|
+
for (const marker of this.logOnly.values()) {
|
|
1145
|
+
this.raiseFloor(marker);
|
|
1146
|
+
}
|
|
870
1147
|
this.tags.clear();
|
|
871
1148
|
this.dueAt.clear();
|
|
872
1149
|
this.unread.clear();
|
|
873
1150
|
this.applied.clear();
|
|
1151
|
+
this.logOnly.clear();
|
|
1152
|
+
// Never back: a marker dropped earlier may have expired entries later.
|
|
1153
|
+
this.floor = Math.max(this.floor, markerClock());
|
|
874
1154
|
this.cursor = at - exports.REVALIDATION_LOG_LOOKBACK_MS;
|
|
875
1155
|
this.lastLogRead = at;
|
|
876
1156
|
}
|
|
@@ -896,13 +1176,23 @@ class TrackedTagMarkers {
|
|
|
896
1176
|
* always answered with, rather than a read on every request while DynamoDB
|
|
897
1177
|
* is unavailable.
|
|
898
1178
|
*/
|
|
899
|
-
async readInto(tags) {
|
|
1179
|
+
async readInto(tags, again = false) {
|
|
900
1180
|
if (tags.length === 0) {
|
|
901
1181
|
return true;
|
|
902
1182
|
}
|
|
903
1183
|
const at = this.clock();
|
|
1184
|
+
const forgotten = this.forgotten;
|
|
904
1185
|
try {
|
|
905
1186
|
const read = await this.markers.read(tags);
|
|
1187
|
+
if (this.forgotten !== forgotten && !again) {
|
|
1188
|
+
// Read before a forget - across a freeze, as like as not - so as
|
|
1189
|
+
// stale as what it forgot. Read again rather than leave the tags
|
|
1190
|
+
// untracked: whoever waits on this read (`reading`) judges entries
|
|
1191
|
+
// by it next, and an untracked tag counts for nothing. Once: a run
|
|
1192
|
+
// of forgets (a truncated log, query after query) would otherwise
|
|
1193
|
+
// keep them waiting, and the second read began after the first.
|
|
1194
|
+
return await this.readInto(tags, true);
|
|
1195
|
+
}
|
|
906
1196
|
for (const tag of tags) {
|
|
907
1197
|
this.unread.delete(tag);
|
|
908
1198
|
this.remember(tag, mergeMarkers(mergeMarkers(this.tags.get(tag), read.get(tag)), this.takePendingRows(tag)));
|
|
@@ -913,6 +1203,9 @@ class TrackedTagMarkers {
|
|
|
913
1203
|
}
|
|
914
1204
|
catch (error) {
|
|
915
1205
|
console.error("Error reading tag markers:", error);
|
|
1206
|
+
if (this.forgotten !== forgotten && !again) {
|
|
1207
|
+
return this.readInto(tags, true);
|
|
1208
|
+
}
|
|
916
1209
|
this.trackUnread(tags);
|
|
917
1210
|
for (const tag of tags) {
|
|
918
1211
|
this.unread.add(tag);
|
|
@@ -926,8 +1219,127 @@ class TrackedTagMarkers {
|
|
|
926
1219
|
}
|
|
927
1220
|
takePendingRows(tag) {
|
|
928
1221
|
const pending = this.pendingRows.get(tag);
|
|
1222
|
+
const logged = this.logOnly.get(tag);
|
|
929
1223
|
this.pendingRows.delete(tag);
|
|
930
|
-
|
|
1224
|
+
this.logOnly.delete(tag);
|
|
1225
|
+
return logged ? mergeMarkers(logged, pending) : pending;
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* What this instance knows of `tag`: tracked, or from the log alone -
|
|
1229
|
+
* including rows that arrived while its first read is in flight.
|
|
1230
|
+
*/
|
|
1231
|
+
knownMarker(tag) {
|
|
1232
|
+
const tracked = this.tags.get(tag);
|
|
1233
|
+
if (tracked) {
|
|
1234
|
+
return tracked;
|
|
1235
|
+
}
|
|
1236
|
+
const logged = this.logOnly.get(tag);
|
|
1237
|
+
const pending = this.pendingRows.get(tag);
|
|
1238
|
+
return logged || pending ? mergeMarkers(logged, pending) : undefined;
|
|
1239
|
+
}
|
|
1240
|
+
/**
|
|
1241
|
+
* Keep `tag`'s log rows in `logOnly`, unless they cannot apply to an entry
|
|
1242
|
+
* held, `oldest` or newer (see {@link pruneLogged}), as bounded as the
|
|
1243
|
+
* tracked tags. Either way a row let go of takes what it knew with it, so
|
|
1244
|
+
* `completeSince` moves past it.
|
|
1245
|
+
*/
|
|
1246
|
+
rememberLogged(tag, marker, oldest) {
|
|
1247
|
+
this.logOnly.delete(tag);
|
|
1248
|
+
if (knownBy(marker, markerClock()) <= oldest) {
|
|
1249
|
+
this.raiseFloor(marker);
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
this.logOnly.set(tag, marker);
|
|
1253
|
+
for (const [first, dropped] of this.logOnly) {
|
|
1254
|
+
if (this.logOnly.size <= this.maxTrackedTags) {
|
|
1255
|
+
break;
|
|
1256
|
+
}
|
|
1257
|
+
this.logOnly.delete(first);
|
|
1258
|
+
this.raiseFloor(dropped);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Drop the `logOnly` rows that cannot apply to an entry held, `oldest` or
|
|
1263
|
+
* newer: every revalidation they name so far is no later than it. That
|
|
1264
|
+
* moves `completeSince` no further than `oldest`, which costs the entries
|
|
1265
|
+
* held nothing, and a profile's `expiredAt` still to come waits in
|
|
1266
|
+
* `laterFloors`. Without this, a deployment revalidating many distinct tags
|
|
1267
|
+
* filled `logOnly` with tags no entry here carries, and the evictions past
|
|
1268
|
+
* its bound kept moving `completeSince` up to the present.
|
|
1269
|
+
*/
|
|
1270
|
+
pruneLogged(oldest) {
|
|
1271
|
+
const at = markerClock();
|
|
1272
|
+
for (const [tag, marker] of this.logOnly) {
|
|
1273
|
+
if (knownBy(marker, at) <= oldest) {
|
|
1274
|
+
this.logOnly.delete(tag);
|
|
1275
|
+
this.raiseFloor(marker);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
1280
|
+
* The oldest entry timestamp of any registered store, `Infinity` with none:
|
|
1281
|
+
* early, never late, unless `scan`.
|
|
1282
|
+
*/
|
|
1283
|
+
oldestEntry(scan) {
|
|
1284
|
+
let oldest = Infinity;
|
|
1285
|
+
for (const { oldestTimestamp } of this.entryStores) {
|
|
1286
|
+
oldest = Math.min(oldest, oldestTimestamp(scan));
|
|
1287
|
+
}
|
|
1288
|
+
return oldest;
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Move `completeSince` past `marker`'s revalidations: what is no longer
|
|
1292
|
+
* known about a tag once its marker is dropped. A future `expiredAt` waits
|
|
1293
|
+
* in `laterFloors` until it is past.
|
|
1294
|
+
*/
|
|
1295
|
+
raiseFloor(marker) {
|
|
1296
|
+
const at = markerClock();
|
|
1297
|
+
this.floor = Math.max(this.floor, knownBy(marker, at));
|
|
1298
|
+
const { expiredAt } = marker;
|
|
1299
|
+
if (expiredAt !== undefined && expiredAt > Math.max(at, this.floor)) {
|
|
1300
|
+
this.laterFloor(expiredAt);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Add `time` to `laterFloors`, in order. Past the tracked-tag bound the two
|
|
1305
|
+
* spans closest together are merged: from the first's start,
|
|
1306
|
+
* `completeSince` is the second's end, early - which only costs reads, and
|
|
1307
|
+
* for as short a time as any merge allows. Never later than its time, which
|
|
1308
|
+
* would let an entry expire unseen.
|
|
1309
|
+
*/
|
|
1310
|
+
laterFloor(time) {
|
|
1311
|
+
const floors = this.laterFloors;
|
|
1312
|
+
let low = 0;
|
|
1313
|
+
let high = floors.length;
|
|
1314
|
+
while (low < high) {
|
|
1315
|
+
const mid = Math.floor((low + high) / 2);
|
|
1316
|
+
if (floors[mid][0] < time) {
|
|
1317
|
+
low = mid + 1;
|
|
1318
|
+
}
|
|
1319
|
+
else {
|
|
1320
|
+
high = mid;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
// Inside a merged span already: by its start, `completeSince` is past it.
|
|
1324
|
+
// Or already there: a log row for an untracked tag is applied again by
|
|
1325
|
+
// every query its lookback returns it to.
|
|
1326
|
+
if ((low > 0 && floors[low - 1][1] >= time) || floors[low]?.[0] === time) {
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
floors.splice(low, 0, [time, time]);
|
|
1330
|
+
// A scan, but only once past the bound. Merging the new time into a
|
|
1331
|
+
// neighbour instead could join an hour-out span with a year-out one, and
|
|
1332
|
+
// hold `completeSince` a year early.
|
|
1333
|
+
if (floors.length > this.maxTrackedTags) {
|
|
1334
|
+
let merge = 0;
|
|
1335
|
+
for (let i = 1; i < floors.length - 1; i++) {
|
|
1336
|
+
if (floors[i + 1][1] - floors[i][0] <
|
|
1337
|
+
floors[merge + 1][1] - floors[merge][0]) {
|
|
1338
|
+
merge = i;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
floors.splice(merge, 2, [floors[merge][0], floors[merge + 1][1]]);
|
|
1342
|
+
}
|
|
931
1343
|
}
|
|
932
1344
|
/** Record that `tag`'s marker was known from the table at `at`. */
|
|
933
1345
|
known(tag, at) {
|
|
@@ -941,6 +1353,7 @@ class TrackedTagMarkers {
|
|
|
941
1353
|
if (this.tags.size <= this.maxTrackedTags) {
|
|
942
1354
|
break;
|
|
943
1355
|
}
|
|
1356
|
+
this.raiseFloor(this.tags.get(oldest));
|
|
944
1357
|
this.tags.delete(oldest);
|
|
945
1358
|
this.dueAt.delete(oldest);
|
|
946
1359
|
this.unread.delete(oldest);
|
|
@@ -954,12 +1367,34 @@ class TrackedTagMarkers {
|
|
|
954
1367
|
}
|
|
955
1368
|
}
|
|
956
1369
|
exports.TrackedTagMarkers = TrackedTagMarkers;
|
|
1370
|
+
/**
|
|
1371
|
+
* The latest revalidation `marker` has made known by `at`, `-Infinity` with
|
|
1372
|
+
* none: a future `expiredAt` is still to come.
|
|
1373
|
+
*/
|
|
1374
|
+
function knownBy(marker, at) {
|
|
1375
|
+
const { revalidatedAt, staleAt, expiredAt } = marker;
|
|
1376
|
+
return Math.max(revalidatedAt ?? -Infinity, staleAt ?? -Infinity, expiredAt !== undefined && expiredAt <= at ? expiredAt : -Infinity);
|
|
1377
|
+
}
|
|
957
1378
|
/**
|
|
958
1379
|
* The longest a log row's put may take and still be seen by every reader: half
|
|
959
1380
|
* the lookback, leaving the rest for writers' clocks and eventually consistent
|
|
960
1381
|
* queries.
|
|
961
1382
|
*/
|
|
962
1383
|
const MAX_LOG_PUT_MS = exports.REVALIDATION_LOG_LOOKBACK_MS / 2;
|
|
1384
|
+
/**
|
|
1385
|
+
* How often a refresh scans the entry stores for their oldest entry, dropping
|
|
1386
|
+
* the expired ones no request reads again.
|
|
1387
|
+
*/
|
|
1388
|
+
const ENTRY_SCAN_INTERVAL_MS = 60_000;
|
|
1389
|
+
/** How often a refresh in flight checks the process is running. */
|
|
1390
|
+
const REFRESH_TICK_MS = 250;
|
|
1391
|
+
/**
|
|
1392
|
+
* How late a tick may come before the process counts as paused (frozen)
|
|
1393
|
+
* since the refresh in flight started. A busy event loop can delay one too:
|
|
1394
|
+
* the refresh then counts as no fresher than its start, as before the pause
|
|
1395
|
+
* check, so a request waits for the next one once that is past the grace.
|
|
1396
|
+
*/
|
|
1397
|
+
const REFRESH_PAUSE_MS = 1000;
|
|
963
1398
|
/**
|
|
964
1399
|
* A marker as read from the table or the log, keeping whatever this instance
|
|
965
1400
|
* already knows that the read does not show yet: reads are eventually
|
|
@@ -1032,4 +1467,4 @@ class CacheBucket {
|
|
|
1032
1467
|
}
|
|
1033
1468
|
}
|
|
1034
1469
|
exports.CacheBucket = CacheBucket;
|
|
1035
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNhY2hlLXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvYXdzLWNhY2hlLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQStDQSxzREFPQztBQVNELGdDQUVDO0FBR0Qsa0NBRUM7QUFtQkQsc0NBRUM7QUFxQ0Qsa0NBZ0JDO0FBV0Qsa0NBRUM7QUFXRCw4QkFXQztBQVFELGtDQVdDO0FBR0Qsb0NBZUM7QUF5Q0QsOEJBRUM7QUFZRCxnQ0FFQztBQXM0QkQsb0NBb0JDO0FBM3FDRDs7Ozs7Ozs7O0VBU0U7QUFDRixzREFBc0Q7QUFDdEQseUNBQWlDO0FBQ2pDLDhEQVNrQztBQUNsQyxrREFLNEI7QUFDNUIsK0NBQTZFO0FBa0I3RSw4Q0FBOEM7QUFDOUMsU0FBZ0IscUJBQXFCO0lBQ25DLE9BQU87UUFDTCxVQUFVLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsSUFBSSxFQUFFO1FBQzFELFNBQVMsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxJQUFJLEVBQUU7UUFDL0QsTUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLFdBQVc7UUFDN0MsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLElBQUksRUFBRTtLQUMvQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQWdCLFVBQVUsQ0FBQyxPQUFlLEVBQUUsUUFBZ0I7SUFDMUQsT0FBTyxJQUFBLGdCQUFJLEVBQUMsT0FBTyxFQUFFLElBQUEsOEJBQWdCLEVBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsbUZBQW1GO0FBQ25GLFNBQWdCLFdBQVcsQ0FBQyxPQUFlLEVBQUUsUUFBZ0I7SUFDM0QsT0FBTyxJQUFBLGdCQUFJLEVBQUMsT0FBTyxFQUFFLElBQUEsNkJBQWUsRUFBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ2xELENB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Q0FBQztRQUN4RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLHFCQUFTLEVBQUUsQ0FBQztnQkFDL0IsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRCw4Q0FBOEM7SUFDOUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFXLEVBQUUsSUFBWTtRQUNyQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUNwQixJQUFJLDRCQUFnQixDQUFDO1lBQ25CLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVTtZQUN2QixHQUFHLEVBQUUsR0FBRztZQUNSLElBQUksRUFBRSxJQUFJO1lBQ1YsV0FBVyxFQUFFLGlDQUFpQztTQUMvQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXZDRCxrQ0F1Q0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBUaGUgUzMgLyBEeW5hbW9EQiBwbHVtYmluZyBzaGFyZWQgYnkgZXZlcnkgY2RrLW5leHRqcyBjYWNoZSBoYW5kbGVyOiB0aGVcbiAgaW5jcmVtZW50YWwgYGNhY2hlSGFuZGxlcmAgKGBTM0NhY2hlSGFuZGxlcmApIGFuZCB0aGUgYGNhY2hlSGFuZGxlcnNgIGZvclxuICBgJ3VzZSBjYWNoZSdgIC8gYCd1c2UgY2FjaGU6IHJlbW90ZSdgLlxuXG4gIFdoYXQgbGl2ZXMgaGVyZSBpcyB3aGF0IGhhcyB0byBhZ3JlZSBiZXR3ZWVuIHRoZW0gLSB3aGVyZSB0aGUgY29uZmlndXJhdGlvblxuICBjb21lcyBmcm9tLCBob3cgYSBjYWNoZSBrZXkgYmVjb21lcyBhbiBTMyBrZXksIGFuZCB3aGF0IGEgdGFnJ3MgbWFya2VyIHJvdyBpblxuICB0aGUgcmV2YWxpZGF0aW9uIHRhYmxlIGxvb2tzIGxpa2UgYW5kIG1lYW5zLiBBIGByZXZhbGlkYXRlVGFnYCByZWFjaGVzIGJvdGhcbiAga2luZHMgb2YgaGFuZGxlciwgYW5kIHRoZXkgbXVzdCByZWFkIGVhY2ggb3RoZXIncyBtYXJrZXJzIHRoZSBzYW1lIHdheS5cbiovXG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVWYWx1ZSxcbiAgQmF0Y2hHZXRJdGVtQ29tbWFuZCxcbiAgQmF0Y2hHZXRJdGVtQ29tbWFuZE91dHB1dCxcbiAgRHluYW1vREJDbGllbnQsXG4gIFB1dEl0ZW1Db21tYW5kLFxuICBRdWVyeUNvbW1hbmQsXG4gIFF1ZXJ5Q29tbWFuZE91dHB1dCxcbiAgVXBkYXRlSXRlbUNvbW1hbmQsXG59IGZyb20gXCJAYXdzLXNkay9jbGllbnQtZHluYW1vZGJcIjtcbmltcG9ydCB7XG4gIEdldE9iamVjdENvbW1hbmQsXG4gIE5vU3VjaEtleSxcbiAgUHV0T2JqZWN0Q29tbWFuZCxcbiAgUzNDbGllbnQsXG59IGZyb20gXCJAYXdzLXNkay9jbGllbnQtczNcIjtcbmltcG9ydCB7IGNhY2hlS2V5RmlsZU5hbWUsIGNhY2hlT2JqZWN0TmFtZSwgc2hhMjU2SGV4IH0gZnJvbSBcIi4vY2FjaGUtdXRpbHNcIjtcblxuLyoqXG4gKiBXaGVyZSB0aGUgY2FjaGUgbGl2ZXMsIGFzIHRoZSBjb25zdHJ1Y3RzIHBhc3MgaXQgdG8gdGhlIGNvbXB1dGUgdGhyb3VnaCB0aGVcbiAqIGVudmlyb25tZW50IChgTmV4dGpzRnVuY3Rpb25zYCwgYE5leHRqc0NvbnRhaW5lcnNgKS4gRW1wdHkgc3RyaW5ncyBmb3Igd2hhdCBpc1xuICogbm90IGNvbmZpZ3VyZWQsIHdoaWNoIGVhY2ggaGFuZGxlciByZWFkcyBhcyBcInRoYXQgbGF5ZXIgaXMgZGlzYWJsZWRcIi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBd3NDYWNoZUNvbmZpZyB7XG4gIC8qKiBgQ0RLX05FWFRKU19DQUNIRV9CVUNLRVRfTkFNRWAuICovXG4gIGJ1Y2tldE5hbWU6IHN0cmluZztcbiAgLyoqIGBDREtfTkVYVEpTX1JFVkFMSURBVElPTl9UQUJMRV9OQU1FYC4gKi9cbiAgdGFibGVOYW1lOiBzdHJpbmc7XG4gIC8qKiBgQVdTX1JFR0lPTmAsIGB1cy1lYXN0LTFgIHdoZW4gdW5zZXQuICovXG4gIHJlZ2lvbjogc3RyaW5nO1xuICAvKiogYENES19ORVhUSlNfQlVJTERfSURgOiBldmVyeSBTMyBrZXkgYW5kIGV2ZXJ5IG1hcmtlciByb3cgaXMgc2NvcGVkIHRvIGl0LiAqL1xuICBidWlsZElkOiBzdHJpbmc7XG59XG5cbi8qKiBUaGUgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBlbnZpcm9ubWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQXdzQ2FjaGVDb25maWcoKTogQXdzQ2FjaGVDb25maWcge1xuICByZXR1cm4ge1xuICAgIGJ1Y2tldE5hbWU6IHByb2Nlc3MuZW52LkNES19ORVhUSlNfQ0FDSEVfQlVDS0VUX05BTUUgfHwgXCJcIixcbiAgICB0YWJsZU5hbWU6IHByb2Nlc3MuZW52LkNES19ORVhUSlNfUkVWQUxJREFUSU9OX1RBQkxFX05BTUUgfHwgXCJcIixcbiAgICByZWdpb246IHByb2Nlc3MuZW52LkFXU19SRUdJT04gfHwgXCJ1cy1lYXN0LTFcIixcbiAgICBidWlsZElkOiBwcm9jZXNzLmVudi5DREtfTkVYVEpTX0JVSUxEX0lEIHx8IFwiXCIsXG4gIH07XG59XG5cbi8qKlxuICogYHtidWlsZElkfS97Y2FjaGVLZXl9Lmpzb25gLCB0aGUgaW5jcmVtZW50YWwgY2FjaGUncyBrZXkgY29udmVudGlvbi5cbiAqXG4gKiBUaGUgcm9vdCBwYXRoIGJlY29tZXMgYGluZGV4YCwgYW5kIGEgbGVhZGluZyBzbGFzaCBpcyBkcm9wcGVkIHNvIHRoZXJlIGlzIG5vXG4gKiBlbXB0eSBmb2xkZXIgdW5kZXIgdGhlIGJ1aWxkIHByZWZpeC4gRXZlcnl0aGluZyB0aGlzIHJldHVybnMgZW5kcyBpbiBgLmpzb25gLFxuICogd2hpY2ggaXMgd2hhdCBrZWVwcyBpdCBkaXNqb2ludCBmcm9tIHtAbGluayB1c2VDYWNoZVMzS2V5fS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUzNLZXkoYnVpbGRJZDogc3RyaW5nLCBjYWNoZUtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oYnVpbGRJZCwgY2FjaGVLZXlGaWxlTmFtZShjYWNoZUtleSkpO1xufVxuXG4vKiogYHtidWlsZElkfS9gICsge0BsaW5rIGNhY2hlT2JqZWN0TmFtZX06IHRoZSBTMyBvYmplY3QgYW4gZW50cnkgaXMgc3RvcmVkIGluLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHMzT2JqZWN0S2V5KGJ1aWxkSWQ6IHN0cmluZywgY2FjaGVLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGJ1aWxkSWQsIGNhY2hlT2JqZWN0TmFtZShjYWNoZUtleSkpO1xufVxuXG4vKipcbiAqIFRoZSBmb2xkZXIgdW5kZXIgdGhlIGJ1aWxkIHByZWZpeCB0aGF0IGAndXNlIGNhY2hlJ2AgZW50cmllcyBhcmUgc3RvcmVkIGluLlxuICogQHNlZSB1c2VDYWNoZVMzS2V5XG4gKi9cbmV4cG9ydCBjb25zdCBVU0VfQ0FDSEVfS0VZX1BSRUZJWCA9IFwiX3VzZS1jYWNoZVwiO1xuXG4vKipcbiAqIGB7YnVpbGRJZH0vX3VzZS1jYWNoZS97aGFzaH0uZW50cnlgLCB3aGVyZSBhIGBjYWNoZUhhbmRsZXJzYCBlbnRyeSBpcyBzdG9yZWQuXG4gKlxuICogSGFzaGVkIGJlY2F1c2UgYSBgJ3VzZSBjYWNoZSdgIGtleSBpcyB0aGUgc2VyaWFsaXplZCBhcmd1bWVudHMgb2YgdGhlIGNhbGwgYW5kXG4gKiBoYXMgbm8gbGVuZ3RoIGxpbWl0LCB3aGVyZSBhbiBTMyBrZXkgc3RvcHMgYXQgMTAyNCBieXRlcy4gVGhlIGAuZW50cnlgIHN1ZmZpeFxuICogcmF0aGVyIHRoYW4gYC5qc29uYCBpcyB3aGF0IG1ha2VzIGEgY29sbGlzaW9uIHdpdGggdGhlIGluY3JlbWVudGFsIGNhY2hlXG4gKiBpbXBvc3NpYmxlIHJhdGhlciB0aGFuIHVubGlrZWx5OiBldmVyeSBvYmplY3Qge0BsaW5rIHMzT2JqZWN0S2V5fSBuYW1lcyBlbmRzXG4gKiBpbiBgLmpzb25gIG9yIGAubG9uZ2AsIGluY2x1ZGluZyBvbmUgZm9yIGEgcm91dGUgdGhhdCBoYXBwZW5zIHRvIGJlIG5hbWVkXG4gKiBgL191c2UtY2FjaGUv4oCmYC5cbiAqIFN0aWxsIHVuZGVyIHRoZSBidWlsZCBwcmVmaXgsIHNvIHBvc3QtZGVwbG95IHBydW5pbmcgZHJvcHMgdGhlbSB3aXRoIHRoZSBidWlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZUNhY2hlUzNLZXkoYnVpbGRJZDogc3RyaW5nLCBrZXlIYXNoOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihidWlsZElkLCBVU0VfQ0FDSEVfS0VZX1BSRUZJWCwgYCR7a2V5SGFzaH0uZW50cnlgKTtcbn1cblxuLyoqXG4gKiBUaGUgYGR1cmF0aW9uc2AgTmV4dC5qcyAxNiBwYXNzZXMgYSB0YWcgcmV2YWxpZGF0aW9uIGZvciBhIHByb2ZpbGU6XG4gKiBgcmV2YWxpZGF0ZVRhZyhcInBvc3RzXCIsIFwibWF4XCIpYCBhcnJpdmVzIGFzIGB7IGV4cGlyZTogPHRoZSBwcm9maWxlJ3MgZXhwaXJlPiB9YC5cbiAqIEFic2VudCBmb3IgYHVwZGF0ZVRhZ2AgYW5kIGEgYmFyZSBgcmV2YWxpZGF0ZVRhZ2AsIHdoaWNoIGV4cGlyZSBpbW1lZGlhdGVseS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXZhbGlkYXRlRHVyYXRpb25zIHtcbiAgZXhwaXJlPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEEgdGFnJ3MgbWFya2VyIHJvdywgYXMgdGltZXN0YW1wcyBpbiBtaWxsaXNlY29uZHMuIFdyaXR0ZW4gYnlcbiAqIHtAbGluayBtYXJrZXJVcGRhdGV9OyBlYWNoIGZpZWxkIGlzIGFic2VudCB1bnRpbCBhIHJldmFsaWRhdGlvbiBvZiB0aGF0IHNoYXBlXG4gKiBoYXMgaGFwcGVuZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFnTWFya2VyIHtcbiAgLyoqIEV4cGlyZWQgb3V0cmlnaHQ6IGB1cGRhdGVUYWdgLCBvciBgcmV2YWxpZGF0ZVRhZ2Agd2l0aCBubyBwcm9maWxlLiAqL1xuICByZXZhbGlkYXRlZEF0PzogbnVtYmVyO1xuICAvKiogU3RhbGUgZnJvbSBoZXJlOiBgcmV2YWxpZGF0ZVRhZyh0YWcsIHByb2ZpbGUpYC4gKi9cbiAgc3RhbGVBdD86IG51bWJlcjtcbiAgLyoqIFdoZW4gdGhlIHByb2ZpbGUncyBgZXhwaXJlYCBydW5zIG91dCwgd2hpY2ggbWF5IGJlIGluIHRoZSBmdXR1cmUuICovXG4gIGV4cGlyZWRBdD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBXaGF0IHRoZSB0YWcgbWFya2VycyBzYXkgYWJvdXQgYW4gZW50cnk6IHVudG91Y2hlZCwgc2VydmVkIHN0YWxlIHdoaWxlIGFcbiAqIGJhY2tncm91bmQgcmVuZGVyIHJlcGxhY2VzIGl0LCBvciBleHBpcmVkIGFuZCByZS1yZW5kZXJlZCBiZWZvcmUgYW5zd2VyaW5nLlxuICovXG5leHBvcnQgdHlwZSBSZXZhbGlkYXRpb25TdGF0ZSA9IFwiZnJlc2hcIiB8IFwic3RhbGVcIiB8IFwiZXhwaXJlZFwiO1xuXG4vKipcbiAqIFdoYXQgYG1hcmtlcmAgbWVhbnMgZm9yIGFuIGVudHJ5IGNyZWF0ZWQgYXQgYGNyZWF0ZWRBdGAsIGF0IGBub3dgLlxuICpcbiAqIGBleHBpcmVkQXRgIGluIHRoZSBmdXR1cmUgaXMgYSBwcm9maWxlJ3MgYGV4cGlyZWAgdGhhdCBoYXMgbm90IGNvbWUgeWV0LFxuICogY29tcGFyZWQgdGhlIHdheSBOZXh0LmpzJ3MgYGFyZVRhZ3NFeHBpcmVkYCBkb2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyU3RhdGUoXG4gIG1hcmtlcjogVGFnTWFya2VyLFxuICBjcmVhdGVkQXQ6IG51bWJlcixcbiAgbm93OiBudW1iZXIsXG4pOiBSZXZhbGlkYXRpb25TdGF0ZSB7XG4gIGNvbnN0IHsgcmV2YWxpZGF0ZWRBdCwgZXhwaXJlZEF0LCBzdGFsZUF0IH0gPSBtYXJrZXI7XG4gIGlmIChcbiAgICAocmV2YWxpZGF0ZWRBdCAhPT0gdW5kZWZpbmVkICYmIHJldmFsaWRhdGVkQXQgPiBjcmVhdGVkQXQpIHx8XG4gICAgKGV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIGV4cGlyZWRBdCA8PSBub3cgJiYgZXhwaXJlZEF0ID4gY3JlYXRlZEF0KVxuICApIHtcbiAgICByZXR1cm4gXCJleHBpcmVkXCI7XG4gIH1cbiAgaWYgKHN0YWxlQXQgIT09IHVuZGVmaW5lZCAmJiBzdGFsZUF0ID4gY3JlYXRlZEF0KSB7XG4gICAgcmV0dXJuIFwic3RhbGVcIjtcbiAgfVxuICByZXR1cm4gXCJmcmVzaFwiO1xufVxuXG4vKipcbiAqIFRoZSBjbG9jayBldmVyeSB0YWcgbWFya2VyIGlzIHN0YW1wZWQgd2l0aCwgYW5kIGV2ZXJ5IGVudHJ5IHRpbWVzdGFtcCBpdCBpc1xuICogY29tcGFyZWQgYWdhaW5zdDogdGhlIG9uZSBOZXh0LmpzIHN0YW1wcyBgQ2FjaGVFbnRyeS50aW1lc3RhbXBgIHdpdGhcbiAqIChgcGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpYCwgaW4gYHVzZS1jYWNoZS13cmFwcGVyLmpzYCBhbmRcbiAqIHRoZSBkZWZhdWx0IGhhbmRsZXIpLCByYXRoZXIgdGhhbiBgRGF0ZS5ub3coKWAuIEJvdGggaGFuZGxlcnMgd3JpdGUgdGhlIHNhbWVcbiAqIG1hcmtlciByb3dzLCBzbyBib3RoIGhhdmUgdG8gdXNlIGl0OiB0d28gY2xvY2tzIG9uIG9uZSByb3cgbGV0IHRoZSBsYXN0IHdyaXRlclxuICogZGVjaWRlIHdoaWNoIGNsb2NrIHRoZSBvdGhlcnMgY29tcGFyZSBhZ2FpbnN0LCBhbmQgdGhleSBkcmlmdCBhcGFydCBmb3IgYXNcbiAqIGxvbmcgYXMgYSBMYW1iZGEgc2FuZGJveCBvciBGYXJnYXRlIHRhc2sgbGl2ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJDbG9jaygpOiBudW1iZXIge1xuICByZXR1cm4gcGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpO1xufVxuXG4vKipcbiAqIFRoZSBtYXJrZXIgZmllbGRzIGEgdGFnIHJldmFsaWRhdGVkIGF0IGBub3dgIHNldHMuXG4gKlxuICogV2l0aG91dCBgZHVyYXRpb25zYCAtIGB1cGRhdGVUYWdgLCBvciBgcmV2YWxpZGF0ZVRhZ2Agd2l0aCBubyBwcm9maWxlIC0gdGhlXG4gKiB0YWcncyBlbnRyaWVzIGV4cGlyZSBpbW1lZGlhdGVseSAoYHJldmFsaWRhdGVkQXRgKS4gV2l0aCB0aGVtIHRoZSBlbnRyaWVzIGdvXG4gKiBzdGFsZSBub3cgYW5kIGV4cGlyZSBhZnRlciB0aGUgcHJvZmlsZSdzIGBleHBpcmVgLCB0aGUgc2FtZSBwYWlyIG9mXG4gKiB0aW1lc3RhbXBzIE5leHQuanMncyBgRmlsZVN5c3RlbUNhY2hlLnJldmFsaWRhdGVUYWdgIHJlY29yZHMuIEEgcHJvZmlsZSB3aXRoXG4gKiBubyBgZXhwaXJlYCBzZXRzIG9ubHkgYHN0YWxlQXRgLCBhbmQgd2hhdGV2ZXIgYGV4cGlyZWRBdGAgdGhlIHRhZyBoYWQgc3RheXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJGb3IoXG4gIG5vdzogbnVtYmVyLFxuICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4pOiBUYWdNYXJrZXIge1xuICBpZiAoIWR1cmF0aW9ucykge1xuICAgIHJldHVybiB7IHJldmFsaWRhdGVkQXQ6IG5vdyB9O1xuICB9XG4gIGlmIChkdXJhdGlvbnMuZXhwaXJlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4geyBzdGFsZUF0OiBub3cgfTtcbiAgfVxuICByZXR1cm4geyBzdGFsZUF0OiBub3csIGV4cGlyZWRBdDogbm93ICsgZHVyYXRpb25zLmV4cGlyZSAqIDEwMDAgfTtcbn1cblxuY29uc3QgTUFSS0VSX0ZJRUxEUyA9IFtcInJldmFsaWRhdGVkQXRcIiwgXCJzdGFsZUF0XCIsIFwiZXhwaXJlZEF0XCJdIGFzIGNvbnN0O1xuXG4vKipcbiAqIGBleGlzdGluZ2Agd2l0aCB0aGUgZmllbGRzIGB1cGRhdGVgIHNldHMsIGFzIGEge0BsaW5rIG1hcmtlclVwZGF0ZX0gbGVhdmVzXG4gKiB0aGUgcm93OiBhIGZpZWxkIGB1cGRhdGVgIGRvZXMgbm90IHNldCBrZWVwcyBpdHMgdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseU1hcmtlcihcbiAgZXhpc3Rpbmc6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCxcbiAgdXBkYXRlOiBUYWdNYXJrZXIsXG4pOiBUYWdNYXJrZXIge1xuICBjb25zdCBtYXJrZXIgPSB7IC4uLmV4aXN0aW5nIH07XG4gIGZvciAoY29uc3QgZmllbGQgb2YgTUFSS0VSX0ZJRUxEUykge1xuICAgIGlmICh1cGRhdGVbZmllbGRdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1hcmtlcltmaWVsZF0gPSB1cGRhdGVbZmllbGRdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWFya2VyO1xufVxuXG4vKiogVGhlIG1hcmtlci1yb3cgdXBkYXRlIHRoYXQgc2V0cyB7QGxpbmsgbWFya2VyRm9yfSdzIGZpZWxkcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJVcGRhdGUoXG4gIG5vdzogbnVtYmVyLFxuICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4pOiBQaWNrPFxuICBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIFVwZGF0ZUl0ZW1Db21tYW5kPlswXSxcbiAgXCJVcGRhdGVFeHByZXNzaW9uXCIgfCBcIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXNcIlxuPiB7XG4gIGNvbnN0IG1hcmtlciA9IG1hcmtlckZvcihub3csIGR1cmF0aW9ucyk7XG4gIGNvbnN0IGZpZWxkcyA9IE1BUktFUl9GSUVMRFMuZmlsdGVyKChmaWVsZCkgPT4gbWFya2VyW2ZpZWxkXSAhPT0gdW5kZWZpbmVkKTtcbiAgcmV0dXJuIHtcbiAgICBVcGRhdGVFeHByZXNzaW9uOiBgU0VUICR7ZmllbGRzLm1hcCgoZmllbGQpID0+IGAke2ZpZWxkfSA9IDoke2ZpZWxkfWApLmpvaW4oXCIsIFwiKX1gLFxuICAgIEV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXM6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIGZpZWxkcy5tYXAoKGZpZWxkKSA9PiBbYDoke2ZpZWxkfWAsIHsgTjogU3RyaW5nKG1hcmtlcltmaWVsZF0pIH1dKSxcbiAgICApLFxuICB9O1xufVxuXG4vKiogQSBEeW5hbW9EQiBudW1iZXIgYXR0cmlidXRlIGFzIGEgbnVtYmVyLCBvciBgdW5kZWZpbmVkYCB3aGVuIGFic2VudC4gKi9cbmZ1bmN0aW9uIG51bWJlckF0dHJpYnV0ZShcbiAgdmFsdWU6IEF0dHJpYnV0ZVZhbHVlIHwgdW5kZWZpbmVkLFxuKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlPy5OID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBOdW1iZXIodmFsdWUuTik7XG59XG5cbi8qKiBUaGUgbWFya2VyIGZpZWxkcyBvZiBhIG1hcmtlciBvciBsb2cgcm93LiAqL1xuZnVuY3Rpb24gbWFya2VyT2YoaXRlbTogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+KTogVGFnTWFya2VyIHtcbiAgcmV0dXJuIHtcbiAgICByZXZhbGlkYXRlZEF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5yZXZhbGlkYXRlZEF0KSxcbiAgICBzdGFsZUF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5zdGFsZUF0KSxcbiAgICBleHBpcmVkQXQ6IG51bWJlckF0dHJpYnV0ZShpdGVtLmV4cGlyZWRBdCksXG4gIH07XG59XG5cbi8qKiBEeW5hbW9EQidzIGNhcCBvbiBrZXlzIGluIG9uZSBgQmF0Y2hHZXRJdGVtYC4gKi9cbmV4cG9ydCBjb25zdCBCQVRDSF9HRVRfTUFYX0tFWVMgPSAxMDA7XG5cbi8qKlxuICogSG93IG9mdGVuLCBhdCBtb3N0LCBhbiBpbnN0YW5jZSBjYXRjaGVzIHVwIG9uIHJldmFsaWRhdGlvbnMgb3RoZXIgaW5zdGFuY2VzXG4gKiByYW4sIHVubGVzcyBgQ0RLX05FWFRKU19UQUdfUkVGUkVTSF9NU2Agc2F5cyBvdGhlcndpc2U6IHRoZSBzdGFsZW5lc3Mgd2luZG93XG4gKiBmb3IgYSBgcmV2YWxpZGF0ZVRhZ2AgcnVuIGVsc2V3aGVyZS4gRXZlcnkgY2FjaGUgaGl0IGNoZWNrcyBpdHMgdGFncydcbiAqIG1hcmtlcnMsIGFuZCBldmVyeSBtYXJrZXIgb2YgYSBkZXBsb3ltZW50IHNoYXJlcyBvbmUgcGFydGl0aW9uIGtleSwgc29cbiAqIHJlYWRpbmcgdGhlbSBwZXIgcmVxdWVzdCBjYXBwZWQgYSByb3V0ZSdzIGNhY2hlIGhpdHMgYXQgdGhlIHBhcnRpdGlvbidzIHJlYWRcbiAqIHRocm91Z2hwdXQgKH4xLDkwMCByZXEvcyBvbiBOZXh0anNSZWdpb25hbEZ1bmN0aW9ucykuIE9uY2UgYSBzZWNvbmQsIGZyb20gdGhlXG4gKiByZXZhbGlkYXRpb24gbG9nLCB0aGUgcmVhZHMgc2NhbGUgd2l0aCBpbnN0YW5jZXMgaW5zdGVhZCBvZiByZXF1ZXN0cyBvciB0YWdzLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9UQUdfUkVGUkVTSF9NUyA9IDEwMDA7XG5cbi8qKiBEeW5hbW9EQidzIGxpbWl0IG9uIGEgc29ydCBrZXksIGluIFVURi04IGJ5dGVzLiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9TT1JUX0tFWV9CWVRFUyA9IDEwMjQ7XG5cbi8qKlxuICogYCM8c2hhMjU2KHRhZyk+YCwgc3RhbmRpbmcgaW4gZm9yIGEgdGFnIGluIGEgc29ydCBrZXkgaXQgd291bGQgcHVzaCBwYXN0XG4gKiB7QGxpbmsgTUFYX1NPUlRfS0VZX0JZVEVTfS4gTmV4dC5qcyBjYXBzIHRoZSB0YWdzIGFuIGFwcCBuYW1lcywgYnV0IG5vdCBhblxuICogaW1wbGljaXQgYF9OX1RfL+KApmAgdGFnLCB3aGljaCBpcyBhcyBsb25nIGFzIGl0cyBwYXRoLCBhbmQgYSByZWplY3RlZCB3cml0ZVxuICogbGVmdCBgcmV2YWxpZGF0ZVBhdGhgIG9uIGEgbG9uZyBwYXRoIHJlY29yZGVkIG5vd2hlcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoZWRUYWcodGFnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCMke3NoYTI1NkhleCh0YWcpfWA7XG59XG5cbi8qKlxuICogVGhlIGxvbmdlc3QgdGFnIGEgc29ydCBrZXkgc3BlbGxzIG91dDsgcGFzdCBpdCwge0BsaW5rIHNvcnRLZXlUYWd9IGhhc2hlc1xuICogaXQuIE9uZSBjYXAgZm9yIGV2ZXJ5IHJvdyB0aGUgdGFnIGlzIGluLCBzbyBhIHJvdydzIHdyaXRlciBhbmQgcmVhZGVyIGFncmVlXG4gKiB3aXRob3V0IGVhY2ggd29ya2luZyBvdXQgd2hhdCBlbHNlIHNoYXJlcyBpdHMga2V5LiBJdCBsZWF2ZXMgcm9vbSBmb3IgdGhlXG4gKiBtb3N0IGFueSByb3cgcHV0cyBiZXNpZGUgdGhlIHRhZzogYSBtYXBwaW5nIHJvdydzIGAjPGJ1aWxkSWQ+LyM8c2hhMjU2PmAsXG4gKiB3aXRoIHRoZSBidWlsZCBJRCBjYXBwZWQgYXQgYE1BWF9CVUlMRF9JRF9CWVRFU2AuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfVEFHX0JZVEVTID0gNzY4O1xuXG4vKiogYHRhZ2AgYXMgYSBzb3J0IGtleSBzcGVsbHMgaXQ6IGl0c2VsZiwgb3Ige0BsaW5rIGhhc2hlZFRhZ30gcGFzdCB7QGxpbmsgTUFYX1RBR19CWVRFU30uICovXG5leHBvcnQgZnVuY3Rpb24gc29ydEtleVRhZyh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBCdWZmZXIuYnl0ZUxlbmd0aCh0YWcpIDw9IE1BWF9UQUdfQllURVMgPyB0YWcgOiBoYXNoZWRUYWcodGFnKTtcbn1cblxuLyoqXG4gKiBUaGUgYmFyZS10YWcgbWFya2VyIHJvd3Mgb2YgdGhlIHJldmFsaWRhdGlvbiB0YWJsZSAoYHBrID0gYnVpbGRJZGAsXG4gKiBgc2sgPSB0YWdgLCBvciB7QGxpbmsgaGFzaGVkVGFnfSBwYXN0IHtAbGluayBNQVhfVEFHX0JZVEVTfSksIHdoaWNoIHJlY29yZCB3aGVuIGEgdGFnXG4gKiB3YXMgbGFzdCByZXZhbGlkYXRlZCBhbmQgaG93LlxuICpcbiAqIFRoZSB0YWJsZSBhbHNvIGhvbGRzIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSdzIGB0YWcjczNLZXlgIG1hcHBpbmcgcm93cywgd2hpY2hcbiAqIGFyZSBpdHMgb3duIGJ1c2luZXNzIGFuZCBzdGF5IGluIGBTM0NhY2hlSGFuZGxlcmA6IG9ubHkgdGhlIG1hcmtlcnMgbWVhbiB0aGVcbiAqIHNhbWUgdGhpbmcgdG8gZXZlcnkgaGFuZGxlci4gV2hhdCBhbiBpbnN0YW5jZSBrZWVwcyBvZiB0aGVtIGJldHdlZW4gcmVhZHMgaXNcbiAqIHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30uXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWdNYXJrZXJUYWJsZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBEeW5hbW9EQkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFJlY29yZCBgdGFnYCdzIHJldmFsaWRhdGlvbiBhdCBgbm93YC4gU2VlIHtAbGluayBtYXJrZXJVcGRhdGV9LlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSByb3cgYXMgdGhpcyB3cml0ZSBsZWZ0IGl0LCBzbyB0aGUgaW5zdGFuY2UgdGhhdCB3cm90ZSBpdCBjYW5cbiAgICogdHJhY2sgaXQgcmF0aGVyIHRoYW4gcmVhZCBpdCBiYWNrOiByZWFkcyBhcmUgZXZlbnR1YWxseSBjb25zaXN0ZW50LCBhbmQgYVxuICAgKiByZWFkLWJhY2sgcmFjaW5nIHJlcGxpY2F0aW9uIGNvdWxkIHJldHVybiB0aGUgbWFya2VyIGZyb20gYmVmb3JlIHRoZSB3cml0ZS5cbiAgICovXG4gIGFzeW5jIHdyaXRlKFxuICAgIHRhZzogc3RyaW5nLFxuICAgIG5vdzogbnVtYmVyLFxuICAgIGR1cmF0aW9uczogUmV2YWxpZGF0ZUR1cmF0aW9ucyB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTxUYWdNYXJrZXIgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICBuZXcgVXBkYXRlSXRlbUNvbW1hbmQoe1xuICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICBLZXk6IHtcbiAgICAgICAgICBwazogeyBTOiB0aGlzLmJ1aWxkSWQgfSxcbiAgICAgICAgICBzazogeyBTOiBzb3J0S2V5VGFnKHRhZykgfSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4ubWFya2VyVXBkYXRlKG5vdywgZHVyYXRpb25zKSxcbiAgICAgICAgUmV0dXJuVmFsdWVzOiBcIkFMTF9ORVdcIixcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIHJlc3BvbnNlPy5BdHRyaWJ1dGVzID8gbWFya2VyT2YocmVzcG9uc2UuQXR0cmlidXRlcykgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG1hcmtlciByb3dzIGZvciBgdGFnc2AgdGhhdCBleGlzdCwgYnkgdGFnLCBpbiBvbmUgYEJhdGNoR2V0SXRlbWAgcGVyXG4gICAqIHtAbGluayBCQVRDSF9HRVRfTUFYX0tFWVN9IHRhZ3MgcmF0aGVyIHRoYW4gYSBgR2V0SXRlbWAgZWFjaDogYSBwYWdlXG4gICAqIGNhcnJpZXMgaXRzIHdob2xlIGltcGxpY2l0IGBfTl9UXy/igKZgIGNoYWluIHBsdXMgdGhlIGFwcCdzIG93biB0YWdzLCBhXG4gICAqIHBhZ2Ugd2l0aCBhIGZldyBmZXRjaGVzIGNoZWNrcyBlYWNoIG9mIHRoZW0gdG9vLCBhbmQgZXZlcnkgb25lIGlzIG9uIHRoZVxuICAgKiByZXF1ZXN0IHBhdGguIEEgdGFnIHdpdGggbm8gcm93IGlzIGFic2VudCBmcm9tIHRoZSByZXN1bHQuXG4gICAqL1xuICBhc3luYyByZWFkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBUYWdNYXJrZXI+PiB7XG4gICAgY29uc3QgeyB0YWJsZU5hbWUsIGJ1aWxkSWQgfSA9IHRoaXM7XG4gICAgY29uc3QgdW5pcXVlID0gQXJyYXkuZnJvbShuZXcgU2V0KHRhZ3MpKTtcbiAgICBjb25zdCBtYXJrZXJzID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdW5pcXVlLmxlbmd0aDsgaSArPSBCQVRDSF9HRVRfTUFYX0tFWVMpIHtcbiAgICAgIC8vIEEgaGFzaGVkIHNvcnQga2V5IG5hbWVzIG5vIHRhZywgc28gZWFjaCByb3cgaXMgbWF0Y2hlZCBiYWNrIGJ5IGtleS5cbiAgICAgIGNvbnN0IHRhZ0J5U2sgPSBuZXcgTWFwKFxuICAgICAgICB1bmlxdWVcbiAgICAgICAgICAuc2xpY2UoaSwgaSArIEJBVENIX0dFVF9NQVhfS0VZUylcbiAgICAgICAgICAubWFwKCh0YWcpID0+IFtzb3J0S2V5VGFnKHRhZyksIHRhZ10pLFxuICAgICAgKTtcbiAgICAgIGxldCBrZXlzOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT5bXSB8IHVuZGVmaW5lZCA9IEFycmF5LmZyb20oXG4gICAgICAgIHRhZ0J5U2sua2V5cygpLFxuICAgICAgICAoc2spID0+ICh7IHBrOiB7IFM6IGJ1aWxkSWQgfSwgc2s6IHsgUzogc2sgfSB9KSxcbiAgICAgICk7XG4gICAgICAvLyBgVW5wcm9jZXNzZWRLZXlzYCBpcyBEeW5hbW9EQiBkZWNsaW5pbmcgcGFydCBvZiB0aGUgYmF0Y2ggdW5kZXIgbG9hZDtcbiAgICAgIC8vIGEgbWFya2VyIGxlZnQgdW5yZWFkIGlzIGEgcmV2YWxpZGF0aW9uIG1pc3NlZCwgc28gaXQgaXMgYXNrZWQgYWdhaW4uXG4gICAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsga2V5cz8ubGVuZ3RoICYmIGF0dGVtcHQgPCAzOyBhdHRlbXB0KyspIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2U6IEJhdGNoR2V0SXRlbUNvbW1hbmRPdXRwdXQgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgICAgIG5ldyBCYXRjaEdldEl0ZW1Db21tYW5kKHtcbiAgICAgICAgICAgIFJlcXVlc3RJdGVtczoge1xuICAgICAgICAgICAgICBbdGFibGVOYW1lXToge1xuICAgICAgICAgICAgICAgIEtleXM6IGtleXMsXG4gICAgICAgICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246IFwic2ssIHJldmFsaWRhdGVkQXQsIHN0YWxlQXQsIGV4cGlyZWRBdFwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHJlc3BvbnNlLlJlc3BvbnNlcz8uW3RhYmxlTmFtZV0gPz8gW10pIHtcbiAgICAgICAgICBjb25zdCB0YWcgPSB0YWdCeVNrLmdldChpdGVtLnNrPy5TID8/IFwiXCIpO1xuICAgICAgICAgIGlmICh0YWcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbWFya2Vycy5zZXQodGFnLCBtYXJrZXJPZihpdGVtKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGtleXMgPSByZXNwb25zZS5VbnByb2Nlc3NlZEtleXM/Llt0YWJsZU5hbWVdPy5LZXlzO1xuICAgICAgfVxuICAgICAgaWYgKGtleXM/Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYER5bmFtb0RCIGxlZnQgJHtrZXlzLmxlbmd0aH0gdGFnIG1hcmtlcnMgdW5yZWFkIGFmdGVyIHJldHJ5aW5nYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcmtlcnM7XG4gIH1cbn1cblxuLyoqXG4gKiBIb3cgbG9uZyBhIHJldmFsaWRhdGlvbiBsb2cgcm93IGlzIGtlcHQgKGB0dGxgLCBlcG9jaCBzZWNvbmRzKS4gRHluYW1vREIgbmV2ZXJcbiAqIGRlbGV0ZXMgYW4gaXRlbSBiZWZvcmUgaXRzIFRUTCwgb25seSBzb21lIHRpbWUgYWZ0ZXIsIHNvIGEgcmVhZGVyIHRoYXQgbGFzdFxuICogcXVlcmllZCBsZXNzIHRoYW4gdGhpcyBsb25nIGFnbyAobGVzcyBhIG1hcmdpbiBmb3Igd3JpdGVycycgY2xvY2tzKSBpcyBzdXJlXG4gKiB0byBmaW5kIGV2ZXJ5IHJvdyBpdCBoYXMgbm90IHNlZW4geWV0LlxuICovXG5leHBvcnQgY29uc3QgUkVWQUxJREFUSU9OX0xPR19UVExfTVMgPSAxNSAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBtb3N0IGBRdWVyeWAgcGFnZXMgb25lIHtAbGluayBSZXZhbGlkYXRpb25Mb2cucXVlcnl9IHJlYWRzLiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfTUFYX1BBR0VTID0gNTtcblxuLyoqIEhvdyBtYW55IHNvcnQga2V5cyB7QGxpbmsgUmV2YWxpZGF0aW9uTG9nLnB1dH0gdHJpZXMgYmVmb3JlIGdpdmluZyB1cC4gKi9cbmNvbnN0IExPR19QVVRfQVRURU1QVFMgPSA1O1xuXG4vKiogRGlnaXRzIGEgbG9nIHJvdydzIHRpbWVzdGFtcCBpcyB6ZXJvLXBhZGRlZCB0bywgc28gc29ydCBrZXlzIHNvcnQgYnkgdGltZS4gKi9cbmNvbnN0IExPR19TS19ESUdJVFMgPSAxNTtcblxuLyoqIEEgcmV2YWxpZGF0aW9uIHJlYWQgYmFjayBmcm9tIHRoZSBsb2cuICovXG5leHBvcnQgaW50ZXJmYWNlIFJldmFsaWRhdGlvbkxvZ1JvdyB7XG4gIC8qKiBUaGUgcm93J3Mgc29ydCBrZXk6IHVuaXF1ZSBwZXIgcmV2YWxpZGF0aW9uIG9mIGEgdGFnLiAqL1xuICBzazogc3RyaW5nO1xuICAvKiogV2hlbiBpdCB3YXMgd3JpdHRlbiwgb24gdGhlIHdyaXRlcidzIGBEYXRlLm5vdygpYC4gKi9cbiAgYXQ6IG51bWJlcjtcbiAgdGFnOiBzdHJpbmc7XG4gIC8qKiBUaGUgbWFya2VyIGZpZWxkcyB0aGUgcmV2YWxpZGF0aW9uIHNldCwgYXMge0BsaW5rIG1hcmtlckZvcn0gcmV0dXJucyB0aGVtLiAqL1xuICBtYXJrZXI6IFRhZ01hcmtlcjtcbn1cblxuLyoqXG4gKiBUaGUgcmV2YWxpZGF0aW9uIGxvZzogb25lIHJvdyBwZXIgdGFnIHJldmFsaWRhdGlvbiAoYHBrID0gPGJ1aWxkSWQ+I2xvZ2AsXG4gKiBgc2sgPSA8RGF0ZS5ub3coKSwgemVyby1wYWRkZWQ+Izx0YWc+YCksIHdoaWNoIGV4cGlyZXMgYWZ0ZXJcbiAqIHtAbGluayBSRVZBTElEQVRJT05fTE9HX1RUTF9NU30uIEEgdGFnIHBhc3Qge0BsaW5rIE1BWF9UQUdfQllURVN9IGlzXG4gKiB7QGxpbmsgaGFzaGVkVGFnfSB0aGVyZSwgYW5kIHNwZWxsZWQgb3V0IGluIHRoZSByb3cncyBgbG9uZ1RhZ2AgaW5zdGVhZC5cbiAqXG4gKiBUaGUgbWFya2VyIHJvd3Mgc3RheSB0aGUgc291cmNlIG9mIHRydXRoLiBUaGUgbG9nIGV4aXN0cyBzbyBhbiBpbnN0YW5jZVxuICogY2FuIGFzayBcIndoYXQgd2FzIHJldmFsaWRhdGVkIHNpbmNlIEkgbGFzdCBsb29rZWQ/XCIgaW4gb25lIGBRdWVyeWAsIGluc3RlYWRcbiAqIG9mIHJlLXJlYWRpbmcgZXZlcnkgdGFnIGl0IHRyYWNrcyB0byBmaW5kIG91dCB0aGF0IGFsbW9zdCBub25lIGNoYW5nZWQuIEV2ZXJ5XG4gKiBtYXJrZXIgcm93IG9mIGEgZGVwbG95bWVudCBzaGFyZXMgb25lIHBhcnRpdGlvbiwgYW5kIHRob3NlIHJlLXJlYWRzIGZyb20gYVxuICogaGFuZGZ1bCBvZiBidXN5IGluc3RhbmNlcyB3ZXJlIGVub3VnaCB0byB0aHJvdHRsZSBpdC5cbiAqXG4gKiBUaGUgc29ydCBrZXkncyB0aW1lc3RhbXAgaXMgdGhlIHdyaXRlcidzIHdhbGwgY2xvY2sgKGBEYXRlLm5vdygpYCksIG5vdCB0aGVcbiAqIHBlcmZvcm1hbmNlIGNsb2NrICh7QGxpbmsgbWFya2VyQ2xvY2t9KSB0aGUgbWFya2VyIHZhbHVlcyBhcmUgc3RhbXBlZCB3aXRoIGJ5IGJvdGhcbiAqIGhhbmRsZXJzOiBpdCBvbmx5IG9yZGVycyByb3dzIGZvciByZWFkZXJzJyBjdXJzb3JzLCB3aGljaCBhcmUgb24gdGhlaXIgb3duXG4gKiB3YWxsIGNsb2NrcywgYW5kIGlzIG5ldmVyIGNvbXBhcmVkIHdpdGggYW4gZW50cnkncyB0aW1lc3RhbXAuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXZhbGlkYXRpb25Mb2cge1xuICBwcml2YXRlIHJlYWRvbmx5IHBrOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IER5bmFtb0RCQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgYnVpbGRJZDogc3RyaW5nLFxuICApIHtcbiAgICB0aGlzLnBrID0gYCR7YnVpbGRJZH0jbG9nYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgdGhhdCBgdGFnYCB3YXMgcmV2YWxpZGF0ZWQgYXQgYGF0YCAoYERhdGUubm93KClgKSwgc2V0dGluZyBgbWFya2VyYC5cbiAgICpcbiAgICogVHdvIHJldmFsaWRhdGlvbnMgb2YgYHRhZ2AgaW4gdGhlIHNhbWUgbWlsbGlzZWNvbmQgd291bGQgc2hhcmUgYSBzb3J0IGtleSxcbiAgICogYW5kIHRoZSBzZWNvbmQgd291bGQgb3ZlcndyaXRlIHRoZSBmaXJzdC4gU28gdGhlIHJvdyBpcyBvbmx5IHdyaXR0ZW4gd2hlcmVcbiAgICogaXRzIGtleSBpcyBmcmVlLCBhbmQgb24gYSBjb2xsaXNpb24gaXQgbW92ZXMgdG8gdGhlIG5leHQgbWlsbGlzZWNvbmQsIHVwXG4gICAqIHRvIHtAbGluayBMT0dfUFVUX0FUVEVNUFRTfSB0aW1lcy5cbiAgICovXG4gIGFzeW5jIHB1dCh0YWc6IHN0cmluZywgYXQ6IG51bWJlciwgbWFya2VyOiBUYWdNYXJrZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBza1RhZyA9IHNvcnRLZXlUYWcodGFnKTtcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgOyBhdHRlbXB0KyspIHtcbiAgICAgIGNvbnN0IGl0ZW06IFJlY29yZDxzdHJpbmcsIEF0dHJpYnV0ZVZhbHVlPiA9IHtcbiAgICAgICAgcGs6IHsgUzogdGhpcy5wayB9LFxuICAgICAgICBzazogeyBTOiBgJHtsb2dTa1ByZWZpeChhdCl9IyR7c2tUYWd9YCB9LFxuICAgICAgICB0dGw6IHsgTjogU3RyaW5nKE1hdGguY2VpbCgoYXQgKyBSRVZBTElEQVRJT05fTE9HX1RUTF9NUykgLyAxMDAwKSkgfSxcbiAgICAgICAgLi4uKHNrVGFnICE9PSB0YWcgJiYgeyBsb25nVGFnOiB7IFM6IHRhZyB9IH0pLFxuICAgICAgfTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgTUFSS0VSX0ZJRUxEUykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG1hcmtlcltmaWVsZF07XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaXRlbVtmaWVsZF0gPSB7IE46IFN0cmluZyh2YWx1ZSkgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgUHV0SXRlbUNvbW1hbmQoe1xuICAgICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICAgIEl0ZW06IGl0ZW0sXG4gICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiBcImF0dHJpYnV0ZV9ub3RfZXhpc3RzKHNrKVwiLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKGVycm9yIGFzIEVycm9yIHwgdW5kZWZpbmVkKT8ubmFtZSAhPT1cbiAgICAgICAgICAgIFwiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZEV4Y2VwdGlvblwiIHx8XG4gICAgICAgICAgYXR0ZW1wdCA+PSBMT0dfUFVUX0FUVEVNUFRTXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGF0ID0gTWF0aC5mbG9vcihhdCkgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcm93cyB3cml0dGVuIGF0IG9yIGFmdGVyIGBzaW5jZWAgKGBEYXRlLm5vdygpYCksIG9sZGVzdCBmaXJzdC5cbiAgICogYHRydW5jYXRlZGAgd2hlbiB0aGVyZSB3ZXJlIG1vcmUgdGhhbiB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19NQVhfUEFHRVN9XG4gICAqIHBhZ2VzIG9mIHRoZW0sIGFuZCBgcm93c2AgaXMgb25seSB0aGUgc3RhcnQuXG4gICAqXG4gICAqIEV2ZW50dWFsbHkgY29uc2lzdGVudDogYSByb3cgd3JpdHRlbiBhIG1vbWVudCBhZ28gbWF5IG5vdCBzaG93IHlldCwgd2hpY2hcbiAgICogaXMgd2hhdCB0aGUgcmVhZGVyJ3MgbG9va2JhY2sgaXMgZm9yLlxuICAgKi9cbiAgYXN5bmMgcXVlcnkoXG4gICAgc2luY2U6IG51bWJlcixcbiAgKTogUHJvbWlzZTx7IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdOyB0cnVuY2F0ZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdID0gW107XG4gICAgbGV0IHN0YXJ0S2V5OiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgcGFnZSA9IDA7IHBhZ2UgPCBSRVZBTElEQVRJT05fTE9HX01BWF9QQUdFUzsgcGFnZSsrKSB7XG4gICAgICBjb25zdCByZXNwb25zZTogUXVlcnlDb21tYW5kT3V0cHV0ID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgbmV3IFF1ZXJ5Q29tbWFuZCh7XG4gICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICBLZXlDb25kaXRpb25FeHByZXNzaW9uOiBcInBrID0gOnBrIEFORCBzayA+PSA6c2luY2VcIixcbiAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICBcIjpwa1wiOiB7IFM6IHRoaXMucGsgfSxcbiAgICAgICAgICAgIFwiOnNpbmNlXCI6IHsgUzogbG9nU2tQcmVmaXgoTWF0aC5tYXgoMCwgc2luY2UpKSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246XG4gICAgICAgICAgICBcInNrLCBsb25nVGFnLCByZXZhbGlkYXRlZEF0LCBzdGFsZUF0LCBleHBpcmVkQXRcIixcbiAgICAgICAgICBFeGNsdXNpdmVTdGFydEtleTogc3RhcnRLZXksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiByZXNwb25zZS5JdGVtcyA/PyBbXSkge1xuICAgICAgICBjb25zdCBzayA9IGl0ZW0uc2s/LlM7XG4gICAgICAgIC8vIGA8ZGlnaXRzPiM8dGFnPmA6IHRoZSB0YWcgaXMgZXZlcnl0aGluZyBhZnRlciB0aGUgZml4ZWQtd2lkdGhcbiAgICAgICAgLy8gdGltZXN0YW1wLCBgI2BzIGluY2x1ZGVkLlxuICAgICAgICBpZiAoc2sgPT09IHVuZGVmaW5lZCB8fCBza1tMT0dfU0tfRElHSVRTXSAhPT0gXCIjXCIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICByb3dzLnB1c2goe1xuICAgICAgICAgIHNrLFxuICAgICAgICAgIGF0OiBOdW1iZXIoc2suc2xpY2UoMCwgTE9HX1NLX0RJR0lUUykpLFxuICAgICAgICAgIHRhZzogaXRlbS5sb25nVGFnPy5TID8/IHNrLnNsaWNlKExPR19TS19ESUdJVFMgKyAxKSxcbiAgICAgICAgICBtYXJrZXI6IG1hcmtlck9mKGl0ZW0pLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0S2V5ID0gcmVzcG9uc2UuTGFzdEV2YWx1YXRlZEtleTtcbiAgICAgIGlmICghc3RhcnRLZXkpIHtcbiAgICAgICAgcmV0dXJuIHsgcm93cywgdHJ1bmNhdGVkOiBmYWxzZSB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyByb3dzLCB0cnVuY2F0ZWQ6IHRydWUgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBsb2dTa1ByZWZpeChhdDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIFN0cmluZyhNYXRoLmZsb29yKGF0KSkucGFkU3RhcnQoTE9HX1NLX0RJR0lUUywgXCIwXCIpO1xufVxuXG4vKipcbiAqIEhvdyBmYXIgYmVoaW5kIHRoZSBsYXN0IHF1ZXJ5J3Mgc3RhcnQgdGhlIG5leHQgb25lIHN0YXJ0cyByZWFkaW5nIHRoZSBsb2c6XG4gKiB0aGUgcm9vbSBmb3IgdGhlIGBRdWVyeWAgYmVpbmcgZXZlbnR1YWxseSBjb25zaXN0ZW50IGFuZCBmb3Igd3JpdGVycycgY2xvY2tzXG4gKiBydW5uaW5nIGJlaGluZCB0aGUgcmVhZGVyJ3MuIFJvd3MgaW5zaWRlIGl0IGFyZSByZWFkIGFnYWluLCBhbmQgZHJvcHBlZCBhc1xuICogYWxyZWFkeSBhcHBsaWVkLlxuICovXG5leHBvcnQgY29uc3QgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyA9IDUwMDA7XG5cbi8qKlxuICogVGhlIGxvbmdlc3Qge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzfSB0cnVzdHMgdGhlIGxvZyBhbG9uZSBmb3IgYSB0YWcgYmVmb3JlXG4gKiByZWFkaW5nIGl0cyBtYXJrZXIgcm93IGFnYWluLiBUaGUgbG9nIGlzIHRoZSBmYXN0IHBhdGgsIGJ1dCB0aGUgbWFya2VyIHJvd3NcbiAqIGFyZSB0aGUgc291cmNlIG9mIHRydXRoOiBhIGxvZyByb3cgd2hvc2Ugd3JpdGUgZmFpbGVkIHdvdWxkIG90aGVyd2lzZSBiZVxuICogbWlzc2VkIGZvciBhcyBsb25nIGFzIHRoZSB0YWcgc3RheXMgdHJhY2tlZC5cbiAqXG4gKiBSb2xsaW5nLCBub3QgYWxsIGF0IG9uY2U6IGVhY2ggcmVmcmVzaCByZS1yZWFkcyBhdCBtb3N0XG4gKiB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSBvZiB0aGUgdGFncyBkdWUsIG9sZGVzdCBmaXJzdC4gUmUtcmVhZGluZyB0aGVtIGFsbFxuICogdG9nZXRoZXIgY29zdCB+NTAwIFJDVSBhdCAxMDAwIHRhZ3MgLSBhIGZsZWV0IHN0YXJ0ZWQgYnkgb25lIGxvYWQgdGVzdCBkaWQgaXRcbiAqIGluIHRoZSBzYW1lIG1pbnV0ZSwgMTIsODAwIFJDVSwgYW5kIHRocm90dGxlZCAtIGFuZCB3b3VsZCBiZSB+NSwwMDAgUkNVIGF0XG4gKiB7QGxpbmsgREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTfSwgcGFzdCB3aGF0IHRoZSBvbmUgcGFydGl0aW9uIHNlcnZlcyBpbiBhXG4gKiBzZWNvbmQuIFNwcmVhZCBvdXQsIDEwLDAwMCB0cmFja2VkIHRhZ3MgY29zdCB+OCBSQ1UgYSBzZWNvbmQgcGVyIGluc3RhbmNlLlxuICpcbiAqIEVhY2ggdGFnIGlzIGR1ZSBhdCBhIHJhbmRvbSA3NS0xMDAlIG9mIHRoaXMgYWZ0ZXIgaXQgd2FzIGxhc3QgcmVhZCwgc28gdGFnc1xuICogZmlyc3QgcmVhZCB0b2dldGhlciAtIGFuIGluc3RhbmNlIHdhcm1pbmcgdXAgLSBkbyBub3QgYWxsIGNvbWUgZHVlIHRvZ2V0aGVyXG4gKiBhZ2FpbiBldmVyeSBpbnRlcnZhbDogdGhlIGxvYWQgdGVzdCB0aGF0IG1lYXN1cmVkIHRoZSByb2xsaW5nIHJlLXJlYWQgc2F3XG4gKiBpdHMgd2FybS11cCdzIHJlYWRzIHJldHVybiBhcyBhIDMwLTM2IFJDVS9zIGJ1bXAgdGVuIG1pbnV0ZXMgbGF0ZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1RBR19SRVNZTkNfTVMgPSAxMCAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBmcmFjdGlvbiBvZiB7QGxpbmsgREVGQVVMVF9UQUdfUkVTWU5DX01TfSBhIHRhZyBtYXkgY29tZSBkdWUgZWFybHkgYnkuICovXG5jb25zdCBUQUdfUkVTWU5DX0pJVFRFUiA9IDAuMjU7XG5cbi8qKlxuICogSG93IGxvbmcgc2luY2UgdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBsb2cgcXVlcnkgdGhlIGxvZyBjYW4gc3RpbGwgYmUgdHJ1c3RlZCB0b1xuICogaG9sZCBldmVyeSByb3cgbm90IHJlYWQgeWV0OiBpdHMgVFRMIGxlc3MgYSBtYXJnaW4gZm9yIHdyaXRlcnMnIGNsb2Nrcy4gUGFzdFxuICogaXQgLSBhIExhbWJkYSBmcm96ZW4gYmV0d2VlbiBpbnZvY2F0aW9ucywgYSBydW4gb2YgZmFpbGVkIHF1ZXJpZXMgLSB0aGVcbiAqIHRyYWNrZWQgbWFya2VycyBhcmUgZm9yZ290dGVuLCB0byBiZSByZWFkIGFnYWluIGFzIHRoZXkgYXJlIG5lZWRlZCwgYW5kIHRoZVxuICogbG9nIGlzIGZvbGxvd2VkIGZyb20gdGhlcmUuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfUkVWQUxJREFUSU9OX0xPR19HQVBfTVMgPVxuICBSRVZBTElEQVRJT05fTE9HX1RUTF9NUyAtIDUgKiA2MCAqIDEwMDA7XG5cbi8qKlxuICogVGhlIG1vc3QgdGFncyBvbmUgaW5zdGFuY2UgdHJhY2tzLiBQYXN0IGl0IHRoZSBsZWFzdCByZWNlbnRseSB1c2VkIGlzXG4gKiBmb3Jnb3R0ZW4sIHdoaWNoIGNvc3RzIGEgcmVhZCB0aGUgbmV4dCB0aW1lIGl0IGlzIG5lZWRlZDogYW4gdW50cmFja2VkIHRhZ1xuICogaXMgcmVhZCBiZWZvcmUgaXQgaXMgdHJ1c3RlZC5cbiAqXG4gKiBBIHRyYWNrZWQgdGFnIGNvc3RzIG1lbW9yeSAofjIgTUIgYXQgdGhpcyBib3VuZCkgYW5kIGl0cyBzaGFyZSBvZiB0aGUgcm9sbGluZ1xuICogcmUtcmVhZCwgbm90IGEgcmVhZCBldmVyeSByZWZyZXNoLCBzbyB0aGUgYm91bmQgaXMgc2V0IGJ5IGhvdyBtYW55IHRhZ3MgYW5cbiAqIGluc3RhbmNlIHJlYWxseSB1c2VzLiBFdmVyeSBwYXRoIGlzIGEgdGFnIG9mIGl0cyBvd24gKGBfTl9UXy88cGF0aD5gKSwgYW5kIGF0XG4gKiAxMDAwIGFuIGFwcCBvZiAxMDAwIHRhZ2dlZCBwYWdlcyBrZXB0IGV2aWN0aW5nIHdoYXQgaXQgd2FzIGFib3V0IHRvIG5lZWQ6XG4gKiBoYWxmIGl0cyByZXF1ZXN0cyByZS1yZWFkIGEgbWFya2VyLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTID0gMTBfMDAwO1xuXG4vKipcbiAqIFRoZSByZXZhbGlkYXRpb24gdGFibGUncyBtYXJrZXIgcm93cyBhbmQgaXRzIGxvZywgd2hpY2ggYXJlIG9ubHkgZXZlciB1c2VkXG4gKiB0b2dldGhlciwgb3IgbmVpdGhlciBmb3IgdGFncyBsb2NhbCB0byB0aGlzIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCB0eXBlIFRhZ1RhYmxlID1cbiAgfCB7IG1hcmtlcnM6IFRhZ01hcmtlclRhYmxlOyBsb2c6IFJldmFsaWRhdGlvbkxvZyB9XG4gIHwgeyBtYXJrZXJzPzogdW5kZWZpbmVkOyBsb2c/OiB1bmRlZmluZWQgfTtcblxuLyoqIEhvdyB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9IGlzIGJ1aWx0LiAqL1xuZXhwb3J0IHR5cGUgVHJhY2tlZFRhZ01hcmtlcnNPcHRpb25zID0gVGFnVGFibGUgJiB7XG4gIC8qKlxuICAgKiBIb3cgb2Z0ZW4sIGF0IG1vc3QsIHtAbGluayBUcmFja2VkVGFnTWFya2Vycy5yZWZyZXNofSByZWFkcyBhbnl0aGluZy5cbiAgICogQGRlZmF1bHQgREVGQVVMVF9UQUdfUkVGUkVTSF9NU1xuICAgKi9cbiAgcmVmcmVzaEludGVydmFsTXM/OiBudW1iZXI7XG4gIG1heFRyYWNrZWRUYWdzPzogbnVtYmVyO1xuICAvKiogQHNlZSBERUZBVUxUX1RBR19SRVNZTkNfTVMgKi9cbiAgcmVzeW5jSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqIFRoZSB3YWxsIGNsb2NrIHRoZSBsb2cncyBjdXJzb3IgYW5kIHRoZSBpbnRlcnZhbHMgYXJlIGtlcHQgb24uICovXG4gIGNsb2NrPzogKCkgPT4gbnVtYmVyO1xuICAvKiogYE1hdGgucmFuZG9tYCwgZm9yIHdoZW4gZWFjaCB0YWcncyByZS1yZWFkIGNvbWVzIGR1ZS4gKi9cbiAgcmFuZG9tPzogKCkgPT4gbnVtYmVyO1xuICBkZWJ1Zz86IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQ7XG59O1xuXG4vKipcbiAqIE9uZSBpbnN0YW5jZSdzIGNvcHkgb2YgdGhlIG1hcmtlciByb3dzIG9mIHRoZSB0YWdzIGl0IGhhcyBuZWVkZWQsIGtlcHRcbiAqIGN1cnJlbnQgdGhyb3VnaCB0aGUge0BsaW5rIFJldmFsaWRhdGlvbkxvZ306IHRoZSBwcm9jZXNzJ3Mgb25lIHRhZyBtYW5pZmVzdFxuICogKGBzaGFyZWRUYWdNYW5pZmVzdGApLCBmb3IgdGhlIGAndXNlIGNhY2hlJ2AgaGFuZGxlcnMgYW5kIHRoZSBpbmNyZW1lbnRhbFxuICogY2FjaGUgYWxpa2UuXG4gKlxuICogTmV4dC5qcydzIGJ1aWx0LWluIGAndXNlIGNhY2hlJ2AgaGFuZGxlciBrZWVwcyB0YWdzIGluIGEgbW9kdWxlLWxldmVsIG1hcFxuICogKGB0YWdzLW1hbmlmZXN0LmV4dGVybmFsLmpzYCkgdGhhdCBvbmx5IGl0cyBvd24gYHVwZGF0ZVRhZ3NgIHdyaXRlcywgYW5kIGl0c1xuICogYHJlZnJlc2hUYWdzYCBpcyBhIG5vLW9wLCBzbyBhIGByZXZhbGlkYXRlVGFnYCBvbiBvbmUgaW5zdGFuY2UgbmV2ZXIgcmVhY2hlc1xuICogdGhlIG90aGVyczogdGhleSBrZWVwIHNlcnZpbmcgdGhlIHJldmFsaWRhdGVkIGVudHJ5LCBpbmNsdWRpbmcgaW5zaWRlIHBhZ2VzXG4gKiB0aGF0IGFyZSBiZWluZyByZS1yZW5kZXJlZCAqYmVjYXVzZSogb2YgdGhhdCByZXZhbGlkYXRpb24uIFRoZVxuICogYGNhY2hlSGFuZGxlcnNgIGludGVyZmFjZSdzIGFuc3dlciBpcyBgcmVmcmVzaFRhZ3NgLCBcImNhbGxlZCBiZWZvcmUgc3RhcnRpbmdcbiAqIGEgbmV3IHJlcXVlc3Qg4oCmIHRvIHJlZnJlc2ggdGhlIGxvY2FsIHRhZ3MgbWFuaWZlc3RcIiwgYW5kIHRoaXMgaXMgdGhhdFxuICogbWFuaWZlc3QsIGJhY2tlZCBieSB0aGUgc2FtZSBtYXJrZXIgcm93cyB0aGUgaW5jcmVtZW50YWwgY2FjaGUnc1xuICogYHJldmFsaWRhdGVUYWdgIHdyaXRlcyAoYHBrID0gYnVpbGRJZGAsIGBzayA9IHRhZ2ApLlxuICpcbiAqIFRoZSBjb3N0IGlzIGJvdW5kZWQgcGVyIGluc3RhbmNlLCBub3QgcGVyIHJlcXVlc3Q6XG4gKiAtIHtAbGluayBlbnN1cmV9IHJlYWRzIGEgdGFnJ3MgbWFya2VyIHRoZSBmaXJzdCB0aW1lIGl0IGlzIG5lZWRlZCBhbmQgbm90XG4gKiAgIGFnYWluIHVudGlsIGl0IGlzIGV2aWN0ZWQsIHNvIGEgdGFnIGNvc3RzIG9uZSByZWFkIHBlciBpbnN0YW5jZSwgbm90IG9uZVxuICogICBwZXIgcmVxdWVzdC5cbiAqIC0ge0BsaW5rIHJlZnJlc2h9LCBhdCBtb3N0IG9uY2UgcGVyIGByZWZyZXNoSW50ZXJ2YWxNc2AsIHNlbmRzIG9uZSBgUXVlcnlgXG4gKiAgIGZvciB0aGUgbG9nIHJvd3Mgd3JpdHRlbiBzaW5jZSB0aGUgbGFzdCBvbmUsIGFuZCBhcHBsaWVzIHRob3NlIG9mIHRhZ3NcbiAqICAgdGhpcyBpbnN0YW5jZSB0cmFja3MuIENvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSBpdC4gQWxvbmdzaWRlLCBpdCByZS1yZWFkc1xuICogICB0aGUgbWFya2VycyBvZiB1cCB0byB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSB0YWdzIG5vdCByZWFkIGZvclxuICogICB7QGxpbmsgREVGQVVMVF9UQUdfUkVTWU5DX01TfSwgaW4gb25lIGBCYXRjaEdldEl0ZW1gLlxuICogQSByZXZhbGlkYXRpb24gb24gYW5vdGhlciBpbnN0YW5jZSBpcyB0aGVyZWZvcmUgc2VlbiB3aXRoaW5cbiAqIGByZWZyZXNoSW50ZXJ2YWxNc2AgKHBsdXMgdGhlIHF1ZXJ5IGl0c2VsZikuIFRoZSBpbnN0YW5jZSB0aGF0IHJhbiBpdCBhcHBsaWVzXG4gKiBpdCBpdHNlbGYsIGF0IG9uY2UsIHdpdGgge0BsaW5rIHNldH0uXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFja2VkVGFnTWFya2VycyB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWFya2VyczogVGFnTWFya2VyVGFibGUgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nOiBSZXZhbGlkYXRpb25Mb2cgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVmcmVzaEludGVydmFsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUcmFja2VkVGFnczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc3luY0ludGVydmFsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjbG9jazogKCkgPT4gbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHJhbmRvbTogKCkgPT4gbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlYnVnOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xuICAvKiogQnkgdGFnLCBsZWFzdCByZWNlbnRseSB1c2VkIGZpcnN0LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHRhZ3MgPSBuZXcgTWFwPHN0cmluZywgVGFnTWFya2VyPigpO1xuICAvKipcbiAgICogV2hlbiBlYWNoIHRyYWNrZWQgdGFnJ3MgbWFya2VyIGlzIGR1ZSB0byBiZSByZWFkIGFnYWluOiBhIHJhbmRvbSA3NS0xMDAlXG4gICAqIG9mIGByZXN5bmNJbnRlcnZhbE1zYCBhZnRlciBpdCB3YXMgbGFzdCBrbm93biBmcm9tIHRoZSB0YWJsZSAtIHJlYWQsXG4gICAqIHdyaXR0ZW4gaGVyZSwgb3IgbmV3LiBJbiB0aGUgb3JkZXIgdGhleSBiZWNhbWUga25vd24sIGxlYXN0IHJlY2VudCBmaXJzdC5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZHVlQXQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlYWRpbmcgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx2b2lkPj4oKTtcbiAgLyoqXG4gICAqIExvZyByb3dzIGZvciB0YWdzIHdob3NlIGZpcnN0IHJlYWQgaXMgaW4gZmxpZ2h0LCBtZXJnZWQgYnkgdGFnOiB0aGUgcmVhZFxuICAgKiBtYXkgaGF2ZSBiZWVuIGFuc3dlcmVkIGJlZm9yZSB0aGUgcmV2YWxpZGF0aW9uLCBzbyB0aGV5IGFyZSBhcHBsaWVkIHRvIGl0c1xuICAgKiByZXN1bHQgcmF0aGVyIHRoYW4gZHJvcHBlZC5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1Jvd3MgPSBuZXcgTWFwPHN0cmluZywgVGFnTWFya2VyPigpO1xuICAvKiogVHJhY2tlZCB0YWdzIHdob3NlIHJlYWQgZmFpbGVkLCBmb3IgdGhlIG5leHQgcmVmcmVzaCB0byByZWFkIGFnYWluLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHVucmVhZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIGxhc3RSZWZyZXNoID0gLUluZmluaXR5O1xuICBwcml2YXRlIHJlZnJlc2hpbmc6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBXaGVyZSB0aGUgbmV4dCBsb2cgcXVlcnkgc3RhcnRzIChgY2xvY2soKWApOiB0aGUgbGFzdCBzdWNjZXNzZnVsIG9uZSdzXG4gICAqIHN0YXJ0LCBsZXNzIHtAbGluayBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TfS5cbiAgICovXG4gIHByaXZhdGUgY3Vyc29yOiBudW1iZXI7XG4gIC8qKiBXaGVuIHRoZSBsYXN0IHN1Y2Nlc3NmdWwgbG9nIHF1ZXJ5IHN0YXJ0ZWQsIG9yIHRoZSBsb2cgd2FzIGZpcnN0IHJlYWQuICovXG4gIHByaXZhdGUgbGFzdExvZ1JlYWQ6IG51bWJlcjtcbiAgLyoqIExvZyByb3dzIGF0IG9yIGFmdGVyIHRoZSBjdXJzb3IgYWxyZWFkeSBhcHBsaWVkLCBieSBzb3J0IGtleS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBhcHBsaWVkID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIHtAbGluayB1cGRhdGV9cyBvZiB0aGUgY3VycmVudCB0dXJuLCBieSB0aGVpciBhcmd1bWVudHMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBkYXRpbmcgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxib29sZWFuPj4oKTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBUcmFja2VkVGFnTWFya2Vyc09wdGlvbnMpIHtcbiAgICB0aGlzLm1hcmtlcnMgPSBvcHRpb25zLm1hcmtlcnM7XG4gICAgdGhpcy5sb2cgPSBvcHRpb25zLmxvZztcbiAgICB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID1cbiAgICAgIG9wdGlvbnMucmVmcmVzaEludGVydmFsTXMgPz8gREVGQVVMVF9UQUdfUkVGUkVTSF9NUztcbiAgICB0aGlzLm1heFRyYWNrZWRUYWdzID0gb3B0aW9ucy5tYXhUcmFja2VkVGFncyA/PyBERUZBVUxUX01BWF9UUkFDS0VEX1RBR1M7XG4gICAgdGhpcy5yZXN5bmNJbnRlcnZhbE1zID0gb3B0aW9ucy5yZXN5bmNJbnRlcnZhbE1zID8/IERFRkFVTFRfVEFHX1JFU1lOQ19NUztcbiAgICAvLyBMb29rZWQgdXAgb24gZWFjaCBjYWxsIHJhdGhlciB0aGFuIGJvdW5kIGhlcmUsIHNvIGEgdGVzdCdzIGBEYXRlLm5vd2BcbiAgICAvLyBzcHkgYXBwbGllcy5cbiAgICB0aGlzLmNsb2NrID0gb3B0aW9ucy5jbG9jayA/PyAoKCkgPT4gRGF0ZS5ub3coKSk7XG4gICAgdGhpcy5yYW5kb20gPSBvcHRpb25zLnJhbmRvbSA/PyBNYXRoLnJhbmRvbTtcbiAgICB0aGlzLmRlYnVnID0gb3B0aW9ucy5kZWJ1ZyA/PyAoKCkgPT4ge30pO1xuICAgIC8vIE5vdGhpbmcgaXMgdHJhY2tlZCB5ZXQsIHNvIG5vdGhpbmcgYmVmb3JlIHRoaXMgY2FuIGJlIG1pc3NlZDogZXZlcnkgdGFnXG4gICAgLy8gaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIgdGhlIGZpcnN0IHRpbWUgaXQgaXMgbmVlZGVkLlxuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIHRoaXMuY3Vyc29yID0gYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TO1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgfVxuXG4gIC8qKiBgdGFnYCdzIG1hcmtlciBhcyB0aGlzIGluc3RhbmNlIGtub3dzIGl0LCBpZiBpdCB0cmFja3MgYHRhZ2AuICovXG4gIGdldCh0YWc6IHN0cmluZyk6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMudGFncy5nZXQodGFnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBgdGFnYCB3aXRoIGBtYXJrZXJgOiB3aGF0IHRoaXMgaW5zdGFuY2UganVzdCB3cm90ZSwgd2hpY2ggaXQga25vd3NcbiAgICogd2l0aG91dCByZWFkaW5nIGl0IGJhY2suXG4gICAqL1xuICBzZXQodGFnOiBzdHJpbmcsIG1hcmtlcjogVGFnTWFya2VyKTogdm9pZCB7XG4gICAgdGhpcy5yZW1lbWJlcih0YWcsIG1hcmtlcik7XG4gICAgdGhpcy5rbm93bih0YWcsIHRoaXMuY2xvY2soKSk7XG4gIH1cblxuICAvKipcbiAgICogTm90ZSBhIHVzZSBvZiBgdGFnc2A6IHRob3NlIG9mIGFuIGVudHJ5IHRoaXMgaW5zdGFuY2UganVzdCBzdG9yZWQuXG4gICAqXG4gICAqIFdpdGggdGhlIHRhYmxlLCBhIHRhZyBub3QgdHJhY2tlZCB5ZXQgaXMgbGVmdCB1bnRyYWNrZWQsIHRvIGJlIHJlYWQgYnlcbiAgICoge0BsaW5rIGVuc3VyZX0gdGhlIGZpcnN0IHRpbWUgYW4gZW50cnkgbmVlZHMgaXQuIE5vdGhpbmcgcmV2YWxpZGF0ZWQgYmVmb3JlXG4gICAqIHRoZSBuZXcgZW50cnkgd2FzIGNyZWF0ZWQgYXBwbGllcyB0byAqaXQqLCBidXQgdHJhY2tpbmcgaXMgcGVyIHRhZywgbm90IHBlclxuICAgKiBlbnRyeTogdHJhY2tpbmcgdGhlIHRhZyB3aXRoIGFuIGVtcHR5IG1hcmtlciB3b3VsZCBhbHNvIHZvdWNoIGZvciBldmVyeVxuICAgKiBvbGRlciBlbnRyeSB0aGF0IGNhcnJpZXMgaXQgLSBvbmUgYW5vdGhlciBpbnN0YW5jZSBzdG9yZWQgaW4gUzMsIG9yIG9uZVxuICAgKiB0aGlzIGluc3RhbmNlIGtlcHQgaW4gbWVtb3J5IGFjcm9zcyBhIHtAbGluayBmb3JnZXR9IC0gYW5kIGEgcmV2YWxpZGF0aW9uXG4gICAqIGZyb20gYmVmb3JlIHRoZSBsb2cncyBjdXJzb3Igd291bGQgZ28gdW5zZWVuIHVudGlsIHRoZSByb2xsaW5nIHJlLXJlYWQuXG4gICAqXG4gICAqIFdpdGhvdXQgdGhlIHRhYmxlIGV2ZXJ5IHJldmFsaWRhdGlvbiBpcyB0aGlzIHByb2Nlc3MncyBvd24sIGFwcGxpZWQgd2l0aFxuICAgKiB7QGxpbmsgc2V0fSwgc28gYSB0YWcgaXMgdHJhY2tlZCBhdCBvbmNlLlxuICAgKi9cbiAgdHJhY2sodGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWFya2Vycykge1xuICAgICAgdGhpcy50cmFja1VucmVhZCh0YWdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy50b3VjaCh0YWcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBgdGFnc2AgYXMgdGhleSBhcmUga25vd24gbm93LCB3aXRob3V0IHJlYWRpbmcgdGhlbSwgd2l0aCBhbiBlbXB0eVxuICAgKiBtYXJrZXIgZm9yIGFueSBub3QgdHJhY2tlZCB5ZXQuXG4gICAqL1xuICBwcml2YXRlIHRyYWNrVW5yZWFkKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgaWYgKCF0aGlzLnRhZ3MuaGFzKHRhZykpIHtcbiAgICAgICAgdGhpcy5rbm93bih0YWcsIGF0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVtZW1iZXIodGFnLCB0aGlzLnRhZ3MuZ2V0KHRhZykgPz8ge30pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIHRoZSBtYXJrZXJzIG9mIHdoaWNoZXZlciBvZiBgdGFnc2AgdGhpcyBpbnN0YW5jZSBkb2VzIG5vdCB0cmFjayB5ZXQuXG4gICAqIE5lZWRlZCBiZWZvcmUganVkZ2luZyBhbiBlbnRyeSB0aGlzIGluc3RhbmNlIGRpZCBub3QgY3JlYXRlLCBzaW5jZSBpdHNcbiAgICogdGFncyBtYXkgaGF2ZSBiZWVuIHJldmFsaWRhdGVkIGF0IGFueSB0aW1lIGJlZm9yZS5cbiAgICovXG4gIGFzeW5jIGVuc3VyZSh0YWdzOiByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5tYXJrZXJzKSB7XG4gICAgICB0aGlzLnRyYWNrVW5yZWFkKHRhZ3MpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB3YWl0czogUHJvbWlzZTx2b2lkPltdID0gW107XG4gICAgY29uc3QgdW5yZWFkOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIG5ldyBTZXQodGFncykpIHtcbiAgICAgIGNvbnN0IGluRmxpZ2h0ID0gdGhpcy5yZWFkaW5nLmdldCh0YWcpO1xuICAgICAgaWYgKGluRmxpZ2h0KSB7XG4gICAgICAgIHdhaXRzLnB1c2goaW5GbGlnaHQpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnRhZ3MuaGFzKHRhZykpIHtcbiAgICAgICAgdGhpcy50b3VjaCh0YWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdW5yZWFkLnB1c2godGFnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHVucmVhZC5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBgcmVhZEludG9gIG5ldmVyIHJlamVjdHM6IGEgZmFpbGVkIHJlYWQgbGVhdmVzIHRoZSB0YWdzIHRyYWNrZWQuXG4gICAgICBjb25zdCByZWFkID0gdGhpcy5yZWFkSW50byh1bnJlYWQpLnRoZW4oKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHRhZyBvZiB1bnJlYWQpIHtcbiAgICAgICAgICB0aGlzLnJlYWRpbmcuZGVsZXRlKHRhZyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdW5yZWFkKSB7XG4gICAgICAgIHRoaXMucmVhZGluZy5zZXQodGFnLCByZWFkKTtcbiAgICAgIH1cbiAgICAgIHdhaXRzLnB1c2gocmVhZCk7XG4gICAgfVxuICAgIGF3YWl0IFByb21pc2UuYWxsKHdhaXRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYXRjaCB1cCBvbiByZXZhbGlkYXRpb25zIG90aGVyIGluc3RhbmNlcyByYW4sIGF0IG1vc3Qgb25jZSBwZXJcbiAgICogYHJlZnJlc2hJbnRlcnZhbE1zYC4gU2VlIHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30gZm9yIHRoZSBjb3N0LlxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZztcbiAgICBpZiAoIWxvZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWZyZXNoaW5nKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWZyZXNoaW5nO1xuICAgIH1cbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICBpZiAoYXQgLSB0aGlzLmxhc3RSZWZyZXNoIDwgdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxhc3RSZWZyZXNoID0gYXQ7XG4gICAgLy8gV2hhdGV2ZXIgZ2V0cyB0cmFja2VkIGJlZm9yZSB0aGUgbmV4dCByZWZyZXNoIGlzIHJlYWQgZnJvbSBpdHMgbWFya2VyLFxuICAgIC8vIHNvIHRoZXJlIGlzIG5vdGhpbmcgdG8gY2F0Y2ggdXAgb24geWV0LlxuICAgIGlmICh0aGlzLnRhZ3Muc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlZnJlc2hpbmcgPSB0aGlzLnN5bmMoYXQsIGxvZykuZmluYWxseSgoKSA9PiB7XG4gICAgICB0aGlzLnJlZnJlc2hpbmcgPSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYSByZXZhbGlkYXRpb24gb2YgYHRhZ3NgOiBoZXJlIGF0IG9uY2UsIGFuZCBpbiB0aGUgcmV2YWxpZGF0aW9uXG4gICAqIHRhYmxlIGZvciBldmVyeSBvdGhlciBpbnN0YW5jZSAtIHRoZSBtYXJrZXIgcm93IHBsdXMgYSBsb2cgcm93IHBlciB0YWcuXG4gICAqXG4gICAqIE5leHQuanMgY2FsbHMgYHJldmFsaWRhdGVUYWdgIG9uIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSBhbmQgYHVwZGF0ZVRhZ3NgIG9uXG4gICAqIGV2ZXJ5IGRpc3RpbmN0IGBjYWNoZUhhbmRsZXJzYCBlbnRyeSwgYWxsIGluIG9uZSBzeW5jaHJvbm91cyBsb29wXG4gICAqIChgcmV2YWxpZGF0aW9uLXV0aWxzYCksIGFuZCBhbGwgb2YgdGhlbSBzaGFyZSB0aGlzIG1hbmlmZXN0LiBTbyBhblxuICAgKiBpZGVudGljYWwgY2FsbCBpbiB0aGUgc2FtZSB0dXJuIGpvaW5zIHRoZSBmaXJzdCBpbnN0ZWFkIG9mIHdyaXRpbmcgdGhlXG4gICAqIHJvd3MgYWdhaW4uIE9uZSBpbiBhIGxhdGVyIHR1cm4gaXMgYSByZXZhbGlkYXRpb24gb2YgaXRzIG93biwgZXZlbiB3aGlsZVxuICAgKiB0aGUgZmlyc3Qgb25lJ3Mgd3JpdGVzIGFyZSBpbiBmbGlnaHQsIGFuZCBnZXRzIGl0cyBvd24sIGxhdGVyLCBtYXJrZXIuXG4gICAqIE5ldmVyIHJlamVjdHM6IHJlc29sdmVzIGBmYWxzZWAgd2hlbiBhIHJvdyBmYWlsZWQgdG8gd3JpdGUgKHRoZSBlcnJvciBpc1xuICAgKiBsb2dnZWQpLCBzbyBvdGhlciBpbnN0YW5jZXMgbWF5IG5vdCBzZWUgaXQuXG4gICAqL1xuICBhc3luYyB1cGRhdGUoXG4gICAgdGFnczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShbdGFncywgZHVyYXRpb25zID8/IG51bGxdKTtcbiAgICBjb25zdCBpbkZsaWdodCA9IHRoaXMudXBkYXRpbmcuZ2V0KGtleSk7XG4gICAgaWYgKGluRmxpZ2h0KSB7XG4gICAgICByZXR1cm4gaW5GbGlnaHQ7XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZSA9IHRoaXMud3JpdGUodGFncywgZHVyYXRpb25zKTtcbiAgICB0aGlzLnVwZGF0aW5nLnNldChrZXksIHVwZGF0ZSk7XG4gICAgLy8gRm9yZ290dGVuIGFzIHNvb24gYXMgdGhlIGN1cnJlbnQgdHVybidzIGNhbGxzIGhhdmUgYmVlbiBtYWRlLlxuICAgIHZvaWQgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB0aGlzLnVwZGF0aW5nLmRlbGV0ZShrZXkpKTtcbiAgICByZXR1cm4gdXBkYXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoYXQgdGhlIHRyYWNrZWQgbWFya2VycyBzYXkgYWJvdXQgYW4gZW50cnkgY2FycnlpbmcgYHRhZ3NgLCBjcmVhdGVkIGF0XG4gICAqIGBjcmVhdGVkQXRgOiB0aGUgbW9zdCBzZXZlcmUgYW5zd2VyIG9mIGFueSBvZiB0aGVtLlxuICAgKi9cbiAgc3RhdGUodGFnczogcmVhZG9ubHkgc3RyaW5nW10sIGNyZWF0ZWRBdDogbnVtYmVyKTogUmV2YWxpZGF0aW9uU3RhdGUge1xuICAgIC8vIGBtYXJrZXJDbG9jaygpYCwgbm90IGBEYXRlLm5vdygpYCwgaGVyZSBhbmQgd2hlcmV2ZXIgYSBtYXJrZXIgaXMgc3RhbXBlZDpcbiAgICAvLyBgY3JlYXRlZEF0YCBpcyBvbiBOZXh0LmpzJ3MgY2xvY2ssIGFuZCBhIG1hcmtlciBvbiB0aGUgd2FsbCBjbG9jayB3b3VsZCBiZVxuICAgIC8vIGNvbXBhcmVkIGFjcm9zcyB0aGUgdHdvLCBzbyBhbiBlbnRyeSByZWdlbmVyYXRlZCBqdXN0IGFmdGVyIGFcbiAgICAvLyByZXZhbGlkYXRpb24gY291bGQgc3RpbGwgcmVhZCBhcyBvbGRlciB0aGFuIGl0IHdoZXJldmVyIHRoZXkgZHJpZnQuXG4gICAgY29uc3QgYXQgPSBtYXJrZXJDbG9jaygpO1xuICAgIGxldCBzdGF0ZTogUmV2YWxpZGF0aW9uU3RhdGUgPSBcImZyZXNoXCI7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy5nZXQodGFnKTtcbiAgICAgIGlmICghbWFya2VyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFnU3RhdGUgPSBtYXJrZXJTdGF0ZShtYXJrZXIsIGNyZWF0ZWRBdCwgYXQpO1xuICAgICAgaWYgKHRhZ1N0YXRlID09PSBcImV4cGlyZWRcIikge1xuICAgICAgICByZXR1cm4gXCJleHBpcmVkXCI7XG4gICAgICB9XG4gICAgICBpZiAodGFnU3RhdGUgPT09IFwic3RhbGVcIikge1xuICAgICAgICBzdGF0ZSA9IFwic3RhbGVcIjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIGBnZXRFeHBpcmF0aW9uYCdzIGFuc3dlcjogdGhlIGxhdGVzdCB0aW1lIGFueSBvZiBgdGFnc2AgZXhwaXJlZCwgYDBgIGlmXG4gICAqIG5vbmUgaGFzLiBPbmx5IGV4cGlyYXRpb25zIGFscmVhZHkgcGFzdCBjb3VudCAtIGEgcHJvZmlsZSdzIGZ1dHVyZVxuICAgKiBgZXhwaXJlYCBpcyBub3QgYW4gZXhwaXJhdGlvbiB5ZXQgLSBhbmQgYSBzdGFsZSBtYXJrIGRvZXMgbm90LCBtYXRjaGluZ1xuICAgKiBOZXh0LmpzJ3MgZGVmYXVsdCBoYW5kbGVyLCB3aGljaCByZWFkcyBvbmx5IGBleHBpcmVkYCBmb3IgaW1wbGljaXQgdGFncy5cbiAgICovXG4gIGV4cGlyYXRpb24odGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiBudW1iZXIge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBsZXQgbGF0ZXN0ID0gMDtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBjb25zdCBtYXJrZXIgPSB0aGlzLmdldCh0YWcpO1xuICAgICAgaWYgKCFtYXJrZXIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAobWFya2VyLnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5yZXZhbGlkYXRlZEF0KTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXJrZXIuZXhwaXJlZEF0ICE9PSB1bmRlZmluZWQgJiYgbWFya2VyLmV4cGlyZWRBdCA8PSBhdCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5leHBpcmVkQXQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbGF0ZXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZShcbiAgICB0YWdzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBjb25zdCBtYXJrZXIgPSBtYXJrZXJGb3IoYXQsIGR1cmF0aW9ucyk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy5zZXQodGFnLCBhcHBseU1hcmtlcih0aGlzLmdldCh0YWcpLCBtYXJrZXIpKTtcbiAgICB9XG4gICAgY29uc3QgeyBtYXJrZXJzLCBsb2cgfSA9IHRoaXM7XG4gICAgaWYgKCFtYXJrZXJzIHx8ICFsb2cpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB3cml0ZXM6IFtzdHJpbmcsIFByb21pc2U8dW5rbm93bj5dW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBuZXcgU2V0KHRhZ3MpKSB7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIG1hcmtlcjpcIixcbiAgICAgICAgLy8gVGhlIHJvdyBhcyBpdCBpcyBub3csIHdoaWNoIGNhcnJpZXMgYW55IGVhcmxpZXIgYHJldmFsaWRhdGVkQXRgXG4gICAgICAgIC8vIGFub3RoZXIgaW5zdGFuY2Ugd3JvdGU6IHRyYWNraW5nIG9ubHkgd2hhdCB0aGlzIGNhbGwgc2V0IHdvdWxkXG4gICAgICAgIC8vIGhpZGUgdGhhdCBvbmUgdW50aWwgdGhlIHJvbGxpbmcgcmUtcmVhZCwgYW5kIGFuIGVudHJ5IG9sZGVyIHRoYW4gaXRcbiAgICAgICAgLy8gd291bGQgcmVhZCBhcyBtZXJlbHkgc3RhbGUuXG4gICAgICAgIG1hcmtlcnMud3JpdGUodGFnLCBhdCwgZHVyYXRpb25zKS50aGVuKChyb3cpID0+IHtcbiAgICAgICAgICBpZiAocm93KSB7XG4gICAgICAgICAgICB0aGlzLnNldCh0YWcsIG1lcmdlTWFya2Vycyh0aGlzLmdldCh0YWcpLCByb3cpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIGxvZyByb3c6XCIsXG4gICAgICAgIHRoaXMucHV0TG9nUm93KGxvZywgdGFnLCBtYXJrZXIpLFxuICAgICAgXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQod3JpdGVzLm1hcCgoWywgd3JpdGVdKSA9PiB3cml0ZSkpO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3Iod3JpdGVzW2ldWzBdLCByZXN1bHQucmVhc29uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cy5ldmVyeSgocmVzdWx0KSA9PiByZXN1bHQuc3RhdHVzID09PSBcImZ1bGZpbGxlZFwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXQgYHRhZ2AncyBsb2cgcm93LCBzdGFtcGVkIG9uIHRoZSB3YWxsIGNsb2NrICh0aGUgbWFya2VyIHZhbHVlcyBhcmUgb25cbiAgICogTmV4dC5qcydzOiBzZWUge0BsaW5rIFJldmFsaWRhdGlvbkxvZ30pLlxuICAgKlxuICAgKiBSZWFkZXJzIG9ubHkgbG9vayB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NU30gYmVoaW5kIHRoZWlyIGxhc3RcbiAgICogcXVlcnksIHNvIGEgcm93IHRoYXQgc2hvd3MgdXAgbXVjaCBsYXRlciB0aGFuIGl0cyB0aW1lc3RhbXAgLSBhIHNsb3dcbiAgICogY29ubmVjdGlvbiwgcmV0cmllcyB1bmRlciB0aHJvdHRsaW5nIC0gaXMgYmVoaW5kIGV2ZXJ5IGN1cnNvciBhbmQgbmV2ZXJcbiAgICogcmVhZC4gQSBzbG93IHB1dCBpcyB0aGVyZWZvcmUgbWFkZSBhZ2FpbiB1bmRlciBhIGZyZXNoIHRpbWVzdGFtcCwgd2hpY2hcbiAgICogcmVhZGVycyB3aWxsIHNlZTsgb25lIHNsb3cgdHdpY2UgaXMgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwdXRMb2dSb3coXG4gICAgbG9nOiBSZXZhbGlkYXRpb25Mb2csXG4gICAgdGFnOiBzdHJpbmcsXG4gICAgbWFya2VyOiBUYWdNYXJrZXIsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgMjsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICAgIGF3YWl0IGxvZy5wdXQodGFnLCBhdCwgbWFya2VyKTtcbiAgICAgIGlmICh0aGlzLmNsb2NrKCkgLSBhdCA8PSBNQVhfTE9HX1BVVF9NUykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgcmV2YWxpZGF0aW9uIGxvZyByb3cgZm9yICR7dGFnfSB0b29rIGxvbmdlciB0aGFuIHJlYWRlcnMgbG9vayBiYWNrYCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIE9uZSByZWZyZXNoIHN0YXJ0ZWQgYXQgYGF0YDogdGhlIGxvZyByb3dzIHNpbmNlIHRoZSBjdXJzb3IsIGFuZCB0aGUgbmV4dFxuICAgKiBzbGljZSBvZiB0aGUgcm9sbGluZyByZS1yZWFkLlxuICAgKlxuICAgKiBBIGZhaWxlZCBxdWVyeSBjaGFuZ2VzIG5vdGhpbmcgYnV0IHRoZSBsb2c6IHRoZSB0YWdzIHN0YXkgdHJhY2tlZCBhcyB0aGV5XG4gICAqIHdlcmUsIGFuZCB0aGUgbmV4dCByZWZyZXNoIGFza3MgYWdhaW4gZnJvbSB0aGUgc2FtZSBjdXJzb3IuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN5bmMoYXQ6IG51bWJlciwgbG9nOiBSZXZhbGlkYXRpb25Mb2cpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoYXQgLSB0aGlzLmxhc3RMb2dSZWFkID4gTUFYX1JFVkFMSURBVElPTl9MT0dfR0FQX01TKSB7XG4gICAgICB0aGlzLmZvcmdldChcbiAgICAgICAgYXQsXG4gICAgICAgIFwidGhlIHJldmFsaWRhdGlvbiBsb2cgbWF5IG5vdCBjb3ZlciB0aGUgZ2FwIHNpbmNlIGl0IHdhcyBsYXN0IHJlYWRcIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtyZXN1bHRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgbG9nLnF1ZXJ5KHRoaXMuY3Vyc29yKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgdGFnIHJldmFsaWRhdGlvbiBsb2c6XCIsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0pLFxuICAgICAgdGhpcy5yZWFkSW50byh0aGlzLmR1ZShhdCkpLFxuICAgIF0pO1xuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZXN1bHQudHJ1bmNhdGVkKSB7XG4gICAgICB0aGlzLmZvcmdldChcbiAgICAgICAgYXQsXG4gICAgICAgIFwidGhlIHJldmFsaWRhdGlvbiBsb2cgaGFzIG1vcmUgcm93cyB0aGFuIG9uZSBxdWVyeSByZWFkc1wiLFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGFwcGxpZWQgPSAwO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJlc3VsdC5yb3dzKSB7XG4gICAgICBpZiAodGhpcy5hcHBsaWVkLmhhcyhyb3cuc2spKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldChyb3cudGFnKTtcbiAgICAgIGlmIChtYXJrZXIpIHtcbiAgICAgICAgLy8gYHNldGAgb24gYSBrZXkgYWxyZWFkeSB0aGVyZSBrZWVwcyBpdHMgcGxhY2UgaW4gdGhlIExSVSBvcmRlcjogYmVpbmdcbiAgICAgICAgLy8gcmV2YWxpZGF0ZWQgZWxzZXdoZXJlIGlzIG5vdCBhIHVzZS5cbiAgICAgICAgdGhpcy50YWdzLnNldChyb3cudGFnLCBtZXJnZU1hcmtlcnMobWFya2VyLCByb3cubWFya2VyKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMucmVhZGluZy5oYXMocm93LnRhZykpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nUm93cy5zZXQoXG4gICAgICAgICAgcm93LnRhZyxcbiAgICAgICAgICBtZXJnZU1hcmtlcnModGhpcy5wZW5kaW5nUm93cy5nZXQocm93LnRhZyksIHJvdy5tYXJrZXIpLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSB0YWcgdGhpcyBpbnN0YW5jZSBkb2VzIG5vdCB0cmFjayBpcyByZWFkIGZyb20gaXRzIG1hcmtlciB3aGVuIGl0XG4gICAgICAgIC8vIGlzIG5leHQgbmVlZGVkIC0gYnV0IG5vdCB5ZXQgbWFya2VkIGFwcGxpZWQsIGJlY2F1c2UgdGhhdCByZWFkIG1heVxuICAgICAgICAvLyBtaXNzIHRoaXMgdmVyeSByZXZhbGlkYXRpb246IHRoZSB3cml0ZXIgcHV0cyB0aGUgbG9nIHJvdyBhbmQgdGhlXG4gICAgICAgIC8vIG1hcmtlciBhdCB0aGUgc2FtZSB0aW1lLCBhbmQgdGhlIHJlYWQgaXMgYW4gZXZlbnR1YWxseSBjb25zaXN0ZW50XG4gICAgICAgIC8vIGBCYXRjaEdldEl0ZW1gIHRoYXQgY2FuIGxhbmQgbWlsbGlzZWNvbmRzIGFmdGVyIHRoZSByb3cgc2hvd2VkIGhlcmUuXG4gICAgICAgIC8vIE1hcmtlZCBhcHBsaWVkLCB0aGUgcm93IHdhcyBza2lwcGVkIGJ5IGV2ZXJ5IHF1ZXJ5IHRoZSBsb29rYmFja1xuICAgICAgICAvLyByZXR1cm5lZCBpdCB0bywgYW5kIHRoZSBwcmUtcmV2YWxpZGF0aW9uIG1hcmtlciBzdG9vZCB1bnRpbCB0aGVcbiAgICAgICAgLy8gcm9sbGluZyByZS1yZWFkLiBMZWZ0IHVubWFya2VkLCB0aGUgbmV4dCByZWZyZXNoIGFwcGxpZXMgaXQgdG9cbiAgICAgICAgLy8gd2hhdGV2ZXIgdGhhdCByZWFkIGZvdW5kOyBpdCBjb3N0cyBubyByZWFkLCBvbmx5IHRoZSByb3cgYmVpbmdcbiAgICAgICAgLy8gbG9va2VkIGF0IGFnYWluIHdoaWxlIGl0IGlzIGluc2lkZSB0aGUgbG9va2JhY2suXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hcHBsaWVkLnNldChyb3cuc2ssIHJvdy5hdCk7XG4gICAgICBhcHBsaWVkKys7XG4gICAgfVxuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgICB0aGlzLmFkdmFuY2UoYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TKTtcbiAgICB0aGlzLmRlYnVnKFxuICAgICAgYHJlYWQgJHtyZXN1bHQucm93cy5sZW5ndGh9IHJldmFsaWRhdGlvbiBsb2cgcm93cyAoJHthcHBsaWVkfSBhcHBsaWVkKWAsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGFncyB0byByZWFkIG9uIHRoaXMgcmVmcmVzaCwgYXQgbW9zdCBvbmUgYEJhdGNoR2V0SXRlbWAncyB3b3J0aDpcbiAgICogdGhvc2Ugd2hvc2UgcmVhZCBmYWlsZWQsIHRoZW4gdGhvc2Ugd2hvc2UgcmUtcmVhZCBoYXMgY29tZSBkdWUsIGluIHRoZVxuICAgKiBvcmRlciB0aGV5IHdlcmUgbGFzdCByZWFkLlxuICAgKi9cbiAgcHJpdmF0ZSBkdWUoYXQ6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBkdWU6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGhpcy51bnJlYWQpIHtcbiAgICAgIGlmIChkdWUubGVuZ3RoID49IEJBVENIX0dFVF9NQVhfS0VZUykgcmV0dXJuIGR1ZTtcbiAgICAgIGR1ZS5wdXNoKHRhZyk7XG4gICAgfVxuICAgIC8vIEtub3duIGluIHRpbWUgb3JkZXIsIGFuZCBlYWNoIGR1ZSBhdCBtb3N0IGBqaXR0ZXJgIGVhcmxpZXIgdGhhbiB0aGVcbiAgICAvLyB0YWdzIGFmdGVyIGl0OiBwYXN0IGEgdGFnIGR1ZSBtb3JlIHRoYW4gdGhhdCBmcm9tIG5vdywgbm9uZSBpcyBkdWUuXG4gICAgY29uc3Qgaml0dGVyID0gdGhpcy5yZXN5bmNJbnRlcnZhbE1zICogVEFHX1JFU1lOQ19KSVRURVI7XG4gICAgZm9yIChjb25zdCBbdGFnLCBkdWVBdF0gb2YgdGhpcy5kdWVBdCkge1xuICAgICAgaWYgKGR1ZS5sZW5ndGggPj0gQkFUQ0hfR0VUX01BWF9LRVlTIHx8IGR1ZUF0IC0gaml0dGVyID4gYXQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoZHVlQXQgPD0gYXQgJiYgIXRoaXMudW5yZWFkLmhhcyh0YWcpKSB7XG4gICAgICAgIGR1ZS5wdXNoKHRhZyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkdWU7XG4gIH1cblxuICAvKipcbiAgICogRm9yZ2V0IGV2ZXJ5IHRyYWNrZWQgbWFya2VyLCBhbmQgZm9sbG93IHRoZSBsb2cgZnJvbSBgYXRgOiB3aGF0IGlzIG5lZWRlZFxuICAgKiBuZXh0IGlzIHJlYWQgZnJvbSBpdHMgbWFya2VyIGFzIGl0IGlzIG5lZWRlZCwgc3ByZWFkIG92ZXIgdGhlIHJlcXVlc3RzXG4gICAqIHRoYXQgbmVlZCBpdCwgcmF0aGVyIHRoYW4gZXZlcnkgdHJhY2tlZCB0YWcgcmUtcmVhZCBhdCBvbmNlLlxuICAgKi9cbiAgcHJpdmF0ZSBmb3JnZXQoYXQ6IG51bWJlciwgd2h5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmRlYnVnKGBmb3JnZXR0aW5nICR7dGhpcy50YWdzLnNpemV9IHRyYWNrZWQgdGFnczogJHt3aHl9YCk7XG4gICAgdGhpcy50YWdzLmNsZWFyKCk7XG4gICAgdGhpcy5kdWVBdC5jbGVhcigpO1xuICAgIHRoaXMudW5yZWFkLmNsZWFyKCk7XG4gICAgdGhpcy5hcHBsaWVkLmNsZWFyKCk7XG4gICAgdGhpcy5jdXJzb3IgPSBhdCAtIFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVM7XG4gICAgdGhpcy5sYXN0TG9nUmVhZCA9IGF0O1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGN1cnNvciBmb3J3YXJkIHRvIGBjdXJzb3JgLCBmb3JnZXR0aW5nIGFwcGxpZWQgcm93cyBiZWZvcmUgaXQ6XG4gICAqIG5vIHF1ZXJ5IHJldHVybnMgdGhlbSBhZ2Fpbi5cbiAgICovXG4gIHByaXZhdGUgYWR2YW5jZShjdXJzb3I6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChjdXJzb3IgPD0gdGhpcy5jdXJzb3IpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jdXJzb3IgPSBjdXJzb3I7XG4gICAgZm9yIChjb25zdCBbc2ssIGF0XSBvZiB0aGlzLmFwcGxpZWQpIHtcbiAgICAgIGlmIChhdCA8IGN1cnNvcikge1xuICAgICAgICB0aGlzLmFwcGxpZWQuZGVsZXRlKHNrKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBgdGFnc2AgZnJvbSB0aGUgdGFibGUsIGFuZCByZXBvcnQgd2hldGhlciB0aGF0IHdvcmtlZC4gQSByZWFkIHRoYXRcbiAgICogZmFpbHMgbGVhdmVzIHRoZW0gdHJhY2tlZCBhcyB0aGV5IHdlcmUsIGFuZCB0aGUgbmV4dCByZWZyZXNoIHJlYWRzIHRoZW1cbiAgICogYWdhaW46IHRoZSBzYW1lIFwiYXNzdW1lIHRoZSBlbnRyeSBpcyB2YWxpZFwiIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSBoYXNcbiAgICogYWx3YXlzIGFuc3dlcmVkIHdpdGgsIHJhdGhlciB0aGFuIGEgcmVhZCBvbiBldmVyeSByZXF1ZXN0IHdoaWxlIER5bmFtb0RCXG4gICAqIGlzIHVuYXZhaWxhYmxlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWFkSW50byh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0YWdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZWFkID0gYXdhaXQgdGhpcy5tYXJrZXJzIS5yZWFkKHRhZ3MpO1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnVucmVhZC5kZWxldGUodGFnKTtcbiAgICAgICAgdGhpcy5yZW1lbWJlcihcbiAgICAgICAgICB0YWcsXG4gICAgICAgICAgbWVyZ2VNYXJrZXJzKFxuICAgICAgICAgICAgbWVyZ2VNYXJrZXJzKHRoaXMudGFncy5nZXQodGFnKSwgcmVhZC5nZXQodGFnKSksXG4gICAgICAgICAgICB0aGlzLnRha2VQZW5kaW5nUm93cyh0YWcpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMua25vd24odGFnLCBhdCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlYnVnKGByZWFkICR7dGFncy5sZW5ndGh9IHRhZyBtYXJrZXJzICgke3JlYWQuc2l6ZX0gc2V0KWApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciByZWFkaW5nIHRhZyBtYXJrZXJzOlwiLCBlcnJvcik7XG4gICAgICB0aGlzLnRyYWNrVW5yZWFkKHRhZ3MpO1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnVucmVhZC5hZGQodGFnKTtcbiAgICAgICAgY29uc3QgcGVuZGluZyA9IHRoaXMudGFrZVBlbmRpbmdSb3dzKHRhZyk7XG4gICAgICAgIGlmIChwZW5kaW5nKSB7XG4gICAgICAgICAgdGhpcy5yZW1lbWJlcih0YWcsIG1lcmdlTWFya2Vycyh0aGlzLnRhZ3MuZ2V0KHRhZyksIHBlbmRpbmcpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdGFrZVBlbmRpbmdSb3dzKHRhZzogc3RyaW5nKTogVGFnTWFya2VyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nUm93cy5nZXQodGFnKTtcbiAgICB0aGlzLnBlbmRpbmdSb3dzLmRlbGV0ZSh0YWcpO1xuICAgIHJldHVybiBwZW5kaW5nO1xuICB9XG5cbiAgLyoqIFJlY29yZCB0aGF0IGB0YWdgJ3MgbWFya2VyIHdhcyBrbm93biBmcm9tIHRoZSB0YWJsZSBhdCBgYXRgLiAqL1xuICBwcml2YXRlIGtub3duKHRhZzogc3RyaW5nLCBhdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5kdWVBdC5kZWxldGUodGFnKTtcbiAgICB0aGlzLmR1ZUF0LnNldChcbiAgICAgIHRhZyxcbiAgICAgIGF0ICsgdGhpcy5yZXN5bmNJbnRlcnZhbE1zICogKDEgLSBUQUdfUkVTWU5DX0pJVFRFUiAqIHRoaXMucmFuZG9tKCkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlbWVtYmVyKHRhZzogc3RyaW5nLCBtYXJrZXI6IFRhZ01hcmtlcik6IHZvaWQge1xuICAgIHRoaXMudGFncy5kZWxldGUodGFnKTtcbiAgICB0aGlzLnRhZ3Muc2V0KHRhZywgbWFya2VyKTtcbiAgICBmb3IgKGNvbnN0IG9sZGVzdCBvZiB0aGlzLnRhZ3Mua2V5cygpKSB7XG4gICAgICBpZiAodGhpcy50YWdzLnNpemUgPD0gdGhpcy5tYXhUcmFja2VkVGFncykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHRoaXMudGFncy5kZWxldGUob2xkZXN0KTtcbiAgICAgIHRoaXMuZHVlQXQuZGVsZXRlKG9sZGVzdCk7XG4gICAgICB0aGlzLnVucmVhZC5kZWxldGUob2xkZXN0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRvdWNoKHRhZzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldCh0YWcpO1xuICAgIGlmIChtYXJrZXIpIHtcbiAgICAgIHRoaXMucmVtZW1iZXIodGFnLCBtYXJrZXIpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBsb25nZXN0IGEgbG9nIHJvdydzIHB1dCBtYXkgdGFrZSBhbmQgc3RpbGwgYmUgc2VlbiBieSBldmVyeSByZWFkZXI6IGhhbGZcbiAqIHRoZSBsb29rYmFjaywgbGVhdmluZyB0aGUgcmVzdCBmb3Igd3JpdGVycycgY2xvY2tzIGFuZCBldmVudHVhbGx5IGNvbnNpc3RlbnRcbiAqIHF1ZXJpZXMuXG4gKi9cbmNvbnN0IE1BWF9MT0dfUFVUX01TID0gUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyAvIDI7XG5cbi8qKlxuICogQSBtYXJrZXIgYXMgcmVhZCBmcm9tIHRoZSB0YWJsZSBvciB0aGUgbG9nLCBrZWVwaW5nIHdoYXRldmVyIHRoaXMgaW5zdGFuY2VcbiAqIGFscmVhZHkga25vd3MgdGhhdCB0aGUgcmVhZCBkb2VzIG5vdCBzaG93IHlldDogcmVhZHMgYXJlIGV2ZW50dWFsbHlcbiAqIGNvbnNpc3RlbnQsIGFuZCBhIHJlYWQgc3RyYWlnaHQgYWZ0ZXIgdGhpcyBpbnN0YW5jZSdzIG93biByZXZhbGlkYXRpb24gY291bGRcbiAqIG90aGVyd2lzZSB0YWtlIGl0IGJhY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZU1hcmtlcnMoXG4gIGxvY2FsOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQsXG4gIHJlbW90ZTogVGFnTWFya2VyIHwgdW5kZWZpbmVkLFxuKTogVGFnTWFya2VyIHtcbiAgaWYgKCFsb2NhbCkge1xuICAgIHJldHVybiByZW1vdGUgPz8ge307XG4gIH1cbiAgaWYgKCFyZW1vdGUpIHtcbiAgICByZXR1cm4gbG9jYWw7XG4gIH1cbiAgLy8gYGV4cGlyZWRBdGAgaXMgd3JpdHRlbiB3aXRoIGBzdGFsZUF0YCwgc28gaXQgYmVsb25ncyB0byB3aGljaGV2ZXIgaXNcbiAgLy8gbmV3ZXIgLSB1bmxlc3MgdGhhdCByZXZhbGlkYXRpb24ncyBwcm9maWxlIGhhZCBubyBgZXhwaXJlYCBhbmQgbGVmdCBpdC5cbiAgY29uc3QgW29sZGVyLCBuZXdlcl0gPVxuICAgIChsb2NhbC5zdGFsZUF0ID8/IC0xKSA+IChyZW1vdGUuc3RhbGVBdCA/PyAtMSlcbiAgICAgID8gW3JlbW90ZSwgbG9jYWxdXG4gICAgICA6IFtsb2NhbCwgcmVtb3RlXTtcbiAgcmV0dXJuIHtcbiAgICAuLi5hcHBseU1hcmtlcihvbGRlciwgbmV3ZXIpLFxuICAgIHJldmFsaWRhdGVkQXQ6IG1heERlZmluZWQobG9jYWwucmV2YWxpZGF0ZWRBdCwgcmVtb3RlLnJldmFsaWRhdGVkQXQpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBtYXhEZWZpbmVkKGE6IG51bWJlciB8IHVuZGVmaW5lZCwgYjogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gIGlmIChhID09PSB1bmRlZmluZWQpIHJldHVybiBiO1xuICBpZiAoYiA9PT0gdW5kZWZpbmVkKSByZXR1cm4gYTtcbiAgcmV0dXJuIE1hdGgubWF4KGEsIGIpO1xufVxuXG4vKipcbiAqIFRoZSBjYWNoZSBidWNrZXQsIGFzIHRoZSBoYW5kbGVycyB1c2UgaXQ6IHdob2xlIG9iamVjdHMgcmVhZCBhbmQgd3JpdHRlbiBhc1xuICogVVRGLTggdGV4dCB1bmRlciB0aGUga2V5cyBhYm92ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIENhY2hlQnVja2V0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFMzQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYnVja2V0TmFtZTogc3RyaW5nLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFRoZSBib2R5IG9mIHRoZSBvYmplY3QgYXQgYGtleWAsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm9uZSAoYE5vU3VjaEtleWAsIG9yIGFuXG4gICAqIGVtcHR5IHJlc3BvbnNlIGJvZHkpLiBBbnkgb3RoZXIgZXJyb3IgaXMgdGhyb3duOiB0aGUgaGFuZGxlcnMgZGlzYWdyZWUgb25cbiAgICogd2hldGhlciBvbmUgaXMgd29ydGggbG9nZ2luZy5cbiAgICovXG4gIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgbmV3IEdldE9iamVjdENvbW1hbmQoeyBCdWNrZXQ6IHRoaXMuYnVja2V0TmFtZSwgS2V5OiBrZXkgfSksXG4gICAgICApO1xuICAgICAgaWYgKCFyZXNwb25zZS5Cb2R5KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXdhaXQgcmVzcG9uc2UuQm9keS50cmFuc2Zvcm1Ub1N0cmluZyhcInV0Zi04XCIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb1N1Y2hLZXkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBXcml0ZSBgYm9keWAgYXMgYSBKU09OIG9iamVjdCBhdCBga2V5YC4gKi9cbiAgYXN5bmMgcHV0SnNvbihrZXk6IHN0cmluZywgYm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgIG5ldyBQdXRPYmplY3RDb21tYW5kKHtcbiAgICAgICAgQnVja2V0OiB0aGlzLmJ1Y2tldE5hbWUsXG4gICAgICAgIEtleToga2V5LFxuICAgICAgICBCb2R5OiBib2R5LFxuICAgICAgICBDb250ZW50VHlwZTogXCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XCIsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG59XG4iXX0=
|
|
1470
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNhY2hlLXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvYXdzLWNhY2hlLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWdEQSxzREFPQztBQVNELGdDQUVDO0FBR0Qsa0NBRUM7QUFtQkQsc0NBRUM7QUFxQ0Qsa0NBZ0JDO0FBV0Qsa0NBRUM7QUFXRCw4QkFXQztBQVFELGtDQVdDO0FBR0Qsb0NBZUM7QUFpREQsOEJBRUM7QUFZRCxnQ0FFQztBQW8yQ0Qsb0NBb0JDO0FBbHBERDs7Ozs7Ozs7O0VBU0U7QUFDRixzREFBc0Q7QUFDdEQsdURBQXFEO0FBQ3JELHlDQUFpQztBQUNqQyw4REFTa0M7QUFDbEMsa0RBSzRCO0FBQzVCLCtDQUE2RTtBQWtCN0UsOENBQThDO0FBQzlDLFNBQWdCLHFCQUFxQjtJQUNuQyxPQUFPO1FBQ0wsVUFBVSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLElBQUksRUFBRTtRQUMxRCxTQUFTLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQ0FBa0MsSUFBSSxFQUFFO1FBQy9ELE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxXQUFXO1FBQzdDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLEVBQUU7S0FDL0MsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixVQUFVLENBQUMsT0FBZSxFQUFFLFFBQWdCO0lBQzFELE9BQU8sSUFBQSxnQkFBSSxFQUFDLE9BQU8sRUFBRSxJQUFBLDhCQUFnQixFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDbkQsQ0FBQztBQUVELG1GQUFtRjtBQUNuRixTQUFnQixXQUFXLENBQUMsT0FBZSxFQUFFLFFBQWdCO0lBQzNELE9BQU8sSUFBQSxnQkFBSSxFQUFDLE9BQU8sRUFBRSxJQUFBLDZCQUFlLEVBQUMsUUFBUSxDQUFDLENBQUMs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QkFBZ0IsQ0FBQztZQUNuQixNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDdkIsR0FBRyxFQUFFLEdBQUc7WUFDUixJQUFJLEVBQUUsSUFBSTtZQUNWLFdBQVcsRUFBRSxpQ0FBaUM7U0FDL0MsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0NBQ0Y7QUF2Q0Qsa0NBdUNDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgVGhlIFMzIC8gRHluYW1vREIgcGx1bWJpbmcgc2hhcmVkIGJ5IGV2ZXJ5IGNkay1uZXh0anMgY2FjaGUgaGFuZGxlcjogdGhlXG4gIGluY3JlbWVudGFsIGBjYWNoZUhhbmRsZXJgIChgUzNDYWNoZUhhbmRsZXJgKSBhbmQgdGhlIGBjYWNoZUhhbmRsZXJzYCBmb3JcbiAgYCd1c2UgY2FjaGUnYCAvIGAndXNlIGNhY2hlOiByZW1vdGUnYC5cblxuICBXaGF0IGxpdmVzIGhlcmUgaXMgd2hhdCBoYXMgdG8gYWdyZWUgYmV0d2VlbiB0aGVtIC0gd2hlcmUgdGhlIGNvbmZpZ3VyYXRpb25cbiAgY29tZXMgZnJvbSwgaG93IGEgY2FjaGUga2V5IGJlY29tZXMgYW4gUzMga2V5LCBhbmQgd2hhdCBhIHRhZydzIG1hcmtlciByb3cgaW5cbiAgdGhlIHJldmFsaWRhdGlvbiB0YWJsZSBsb29rcyBsaWtlIGFuZCBtZWFucy4gQSBgcmV2YWxpZGF0ZVRhZ2AgcmVhY2hlcyBib3RoXG4gIGtpbmRzIG9mIGhhbmRsZXIsIGFuZCB0aGV5IG11c3QgcmVhZCBlYWNoIG90aGVyJ3MgbWFya2VycyB0aGUgc2FtZSB3YXkuXG4qL1xuLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBBc3luY0xvY2FsU3RvcmFnZSB9IGZyb20gXCJub2RlOmFzeW5jX2hvb2tzXCI7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlVmFsdWUsXG4gIEJhdGNoR2V0SXRlbUNvbW1hbmQsXG4gIEJhdGNoR2V0SXRlbUNvbW1hbmRPdXRwdXQsXG4gIER5bmFtb0RCQ2xpZW50LFxuICBQdXRJdGVtQ29tbWFuZCxcbiAgUXVlcnlDb21tYW5kLFxuICBRdWVyeUNvbW1hbmRPdXRwdXQsXG4gIFVwZGF0ZUl0ZW1Db21tYW5kLFxufSBmcm9tIFwiQGF3cy1zZGsvY2xpZW50LWR5bmFtb2RiXCI7XG5pbXBvcnQge1xuICBHZXRPYmplY3RDb21tYW5kLFxuICBOb1N1Y2hLZXksXG4gIFB1dE9iamVjdENvbW1hbmQsXG4gIFMzQ2xpZW50LFxufSBmcm9tIFwiQGF3cy1zZGsvY2xpZW50LXMzXCI7XG5pbXBvcnQgeyBjYWNoZUtleUZpbGVOYW1lLCBjYWNoZU9iamVjdE5hbWUsIHNoYTI1NkhleCB9IGZyb20gXCIuL2NhY2hlLXV0aWxzXCI7XG5cbi8qKlxuICogV2hlcmUgdGhlIGNhY2hlIGxpdmVzLCBhcyB0aGUgY29uc3RydWN0cyBwYXNzIGl0IHRvIHRoZSBjb21wdXRlIHRocm91Z2ggdGhlXG4gKiBlbnZpcm9ubWVudCAoYE5leHRqc0Z1bmN0aW9uc2AsIGBOZXh0anNDb250YWluZXJzYCkuIEVtcHR5IHN0cmluZ3MgZm9yIHdoYXQgaXNcbiAqIG5vdCBjb25maWd1cmVkLCB3aGljaCBlYWNoIGhhbmRsZXIgcmVhZHMgYXMgXCJ0aGF0IGxheWVyIGlzIGRpc2FibGVkXCIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXdzQ2FjaGVDb25maWcge1xuICAvKiogYENES19ORVhUSlNfQ0FDSEVfQlVDS0VUX05BTUVgLiAqL1xuICBidWNrZXROYW1lOiBzdHJpbmc7XG4gIC8qKiBgQ0RLX05FWFRKU19SRVZBTElEQVRJT05fVEFCTEVfTkFNRWAuICovXG4gIHRhYmxlTmFtZTogc3RyaW5nO1xuICAvKiogYEFXU19SRUdJT05gLCBgdXMtZWFzdC0xYCB3aGVuIHVuc2V0LiAqL1xuICByZWdpb246IHN0cmluZztcbiAgLyoqIGBDREtfTkVYVEpTX0JVSUxEX0lEYDogZXZlcnkgUzMga2V5IGFuZCBldmVyeSBtYXJrZXIgcm93IGlzIHNjb3BlZCB0byBpdC4gKi9cbiAgYnVpbGRJZDogc3RyaW5nO1xufVxuXG4vKiogVGhlIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgZW52aXJvbm1lbnQuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUF3c0NhY2hlQ29uZmlnKCk6IEF3c0NhY2hlQ29uZmlnIHtcbiAgcmV0dXJuIHtcbiAgICBidWNrZXROYW1lOiBwcm9jZXNzLmVudi5DREtfTkVYVEpTX0NBQ0hFX0JVQ0tFVF9OQU1FIHx8IFwiXCIsXG4gICAgdGFibGVOYW1lOiBwcm9jZXNzLmVudi5DREtfTkVYVEpTX1JFVkFMSURBVElPTl9UQUJMRV9OQU1FIHx8IFwiXCIsXG4gICAgcmVnaW9uOiBwcm9jZXNzLmVudi5BV1NfUkVHSU9OIHx8IFwidXMtZWFzdC0xXCIsXG4gICAgYnVpbGRJZDogcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19CVUlMRF9JRCB8fCBcIlwiLFxuICB9O1xufVxuXG4vKipcbiAqIGB7YnVpbGRJZH0ve2NhY2hlS2V5fS5qc29uYCwgdGhlIGluY3JlbWVudGFsIGNhY2hlJ3Mga2V5IGNvbnZlbnRpb24uXG4gKlxuICogVGhlIHJvb3QgcGF0aCBiZWNvbWVzIGBpbmRleGAsIGFuZCBhIGxlYWRpbmcgc2xhc2ggaXMgZHJvcHBlZCBzbyB0aGVyZSBpcyBub1xuICogZW1wdHkgZm9sZGVyIHVuZGVyIHRoZSBidWlsZCBwcmVmaXguIEV2ZXJ5dGhpbmcgdGhpcyByZXR1cm5zIGVuZHMgaW4gYC5qc29uYCxcbiAqIHdoaWNoIGlzIHdoYXQga2VlcHMgaXQgZGlzam9pbnQgZnJvbSB7QGxpbmsgdXNlQ2FjaGVTM0tleX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFMzS2V5KGJ1aWxkSWQ6IHN0cmluZywgY2FjaGVLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGJ1aWxkSWQsIGNhY2hlS2V5RmlsZU5hbWUoY2FjaGVLZXkpKTtcbn1cblxuLyoqIGB7YnVpbGRJZH0vYCArIHtAbGluayBjYWNoZU9iamVjdE5hbWV9OiB0aGUgUzMgb2JqZWN0IGFuIGVudHJ5IGlzIHN0b3JlZCBpbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzM09iamVjdEtleShidWlsZElkOiBzdHJpbmcsIGNhY2hlS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihidWlsZElkLCBjYWNoZU9iamVjdE5hbWUoY2FjaGVLZXkpKTtcbn1cblxuLyoqXG4gKiBUaGUgZm9sZGVyIHVuZGVyIHRoZSBidWlsZCBwcmVmaXggdGhhdCBgJ3VzZSBjYWNoZSdgIGVudHJpZXMgYXJlIHN0b3JlZCBpbi5cbiAqIEBzZWUgdXNlQ2FjaGVTM0tleVxuICovXG5leHBvcnQgY29uc3QgVVNFX0NBQ0hFX0tFWV9QUkVGSVggPSBcIl91c2UtY2FjaGVcIjtcblxuLyoqXG4gKiBge2J1aWxkSWR9L191c2UtY2FjaGUve2hhc2h9LmVudHJ5YCwgd2hlcmUgYSBgY2FjaGVIYW5kbGVyc2AgZW50cnkgaXMgc3RvcmVkLlxuICpcbiAqIEhhc2hlZCBiZWNhdXNlIGEgYCd1c2UgY2FjaGUnYCBrZXkgaXMgdGhlIHNlcmlhbGl6ZWQgYXJndW1lbnRzIG9mIHRoZSBjYWxsIGFuZFxuICogaGFzIG5vIGxlbmd0aCBsaW1pdCwgd2hlcmUgYW4gUzMga2V5IHN0b3BzIGF0IDEwMjQgYnl0ZXMuIFRoZSBgLmVudHJ5YCBzdWZmaXhcbiAqIHJhdGhlciB0aGFuIGAuanNvbmAgaXMgd2hhdCBtYWtlcyBhIGNvbGxpc2lvbiB3aXRoIHRoZSBpbmNyZW1lbnRhbCBjYWNoZVxuICogaW1wb3NzaWJsZSByYXRoZXIgdGhhbiB1bmxpa2VseTogZXZlcnkgb2JqZWN0IHtAbGluayBzM09iamVjdEtleX0gbmFtZXMgZW5kc1xuICogaW4gYC5qc29uYCBvciBgLmxvbmdgLCBpbmNsdWRpbmcgb25lIGZvciBhIHJvdXRlIHRoYXQgaGFwcGVucyB0byBiZSBuYW1lZFxuICogYC9fdXNlLWNhY2hlL+KApmAuXG4gKiBTdGlsbCB1bmRlciB0aGUgYnVpbGQgcHJlZml4LCBzbyBwb3N0LWRlcGxveSBwcnVuaW5nIGRyb3BzIHRoZW0gd2l0aCB0aGUgYnVpbGQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VDYWNoZVMzS2V5KGJ1aWxkSWQ6IHN0cmluZywga2V5SGFzaDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oYnVpbGRJZCwgVVNFX0NBQ0hFX0tFWV9QUkVGSVgsIGAke2tleUhhc2h9LmVudHJ5YCk7XG59XG5cbi8qKlxuICogVGhlIGBkdXJhdGlvbnNgIE5leHQuanMgMTYgcGFzc2VzIGEgdGFnIHJldmFsaWRhdGlvbiBmb3IgYSBwcm9maWxlOlxuICogYHJldmFsaWRhdGVUYWcoXCJwb3N0c1wiLCBcIm1heFwiKWAgYXJyaXZlcyBhcyBgeyBleHBpcmU6IDx0aGUgcHJvZmlsZSdzIGV4cGlyZT4gfWAuXG4gKiBBYnNlbnQgZm9yIGB1cGRhdGVUYWdgIGFuZCBhIGJhcmUgYHJldmFsaWRhdGVUYWdgLCB3aGljaCBleHBpcmUgaW1tZWRpYXRlbHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmV2YWxpZGF0ZUR1cmF0aW9ucyB7XG4gIGV4cGlyZT86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBBIHRhZydzIG1hcmtlciByb3csIGFzIHRpbWVzdGFtcHMgaW4gbWlsbGlzZWNvbmRzLiBXcml0dGVuIGJ5XG4gKiB7QGxpbmsgbWFya2VyVXBkYXRlfTsgZWFjaCBmaWVsZCBpcyBhYnNlbnQgdW50aWwgYSByZXZhbGlkYXRpb24gb2YgdGhhdCBzaGFwZVxuICogaGFzIGhhcHBlbmVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhZ01hcmtlciB7XG4gIC8qKiBFeHBpcmVkIG91dHJpZ2h0OiBgdXBkYXRlVGFnYCwgb3IgYHJldmFsaWRhdGVUYWdgIHdpdGggbm8gcHJvZmlsZS4gKi9cbiAgcmV2YWxpZGF0ZWRBdD86IG51bWJlcjtcbiAgLyoqIFN0YWxlIGZyb20gaGVyZTogYHJldmFsaWRhdGVUYWcodGFnLCBwcm9maWxlKWAuICovXG4gIHN0YWxlQXQ/OiBudW1iZXI7XG4gIC8qKiBXaGVuIHRoZSBwcm9maWxlJ3MgYGV4cGlyZWAgcnVucyBvdXQsIHdoaWNoIG1heSBiZSBpbiB0aGUgZnV0dXJlLiAqL1xuICBleHBpcmVkQXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogV2hhdCB0aGUgdGFnIG1hcmtlcnMgc2F5IGFib3V0IGFuIGVudHJ5OiB1bnRvdWNoZWQsIHNlcnZlZCBzdGFsZSB3aGlsZSBhXG4gKiBiYWNrZ3JvdW5kIHJlbmRlciByZXBsYWNlcyBpdCwgb3IgZXhwaXJlZCBhbmQgcmUtcmVuZGVyZWQgYmVmb3JlIGFuc3dlcmluZy5cbiAqL1xuZXhwb3J0IHR5cGUgUmV2YWxpZGF0aW9uU3RhdGUgPSBcImZyZXNoXCIgfCBcInN0YWxlXCIgfCBcImV4cGlyZWRcIjtcblxuLyoqXG4gKiBXaGF0IGBtYXJrZXJgIG1lYW5zIGZvciBhbiBlbnRyeSBjcmVhdGVkIGF0IGBjcmVhdGVkQXRgLCBhdCBgbm93YC5cbiAqXG4gKiBgZXhwaXJlZEF0YCBpbiB0aGUgZnV0dXJlIGlzIGEgcHJvZmlsZSdzIGBleHBpcmVgIHRoYXQgaGFzIG5vdCBjb21lIHlldCxcbiAqIGNvbXBhcmVkIHRoZSB3YXkgTmV4dC5qcydzIGBhcmVUYWdzRXhwaXJlZGAgZG9lcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtlclN0YXRlKFxuICBtYXJrZXI6IFRhZ01hcmtlcixcbiAgY3JlYXRlZEF0OiBudW1iZXIsXG4gIG5vdzogbnVtYmVyLFxuKTogUmV2YWxpZGF0aW9uU3RhdGUge1xuICBjb25zdCB7IHJldmFsaWRhdGVkQXQsIGV4cGlyZWRBdCwgc3RhbGVBdCB9ID0gbWFya2VyO1xuICBpZiAoXG4gICAgKHJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCAmJiByZXZhbGlkYXRlZEF0ID4gY3JlYXRlZEF0KSB8fFxuICAgIChleHBpcmVkQXQgIT09IHVuZGVmaW5lZCAmJiBleHBpcmVkQXQgPD0gbm93ICYmIGV4cGlyZWRBdCA+IGNyZWF0ZWRBdClcbiAgKSB7XG4gICAgcmV0dXJuIFwiZXhwaXJlZFwiO1xuICB9XG4gIGlmIChzdGFsZUF0ICE9PSB1bmRlZmluZWQgJiYgc3RhbGVBdCA+IGNyZWF0ZWRBdCkge1xuICAgIHJldHVybiBcInN0YWxlXCI7XG4gIH1cbiAgcmV0dXJuIFwiZnJlc2hcIjtcbn1cblxuLyoqXG4gKiBUaGUgY2xvY2sgZXZlcnkgdGFnIG1hcmtlciBpcyBzdGFtcGVkIHdpdGgsIGFuZCBldmVyeSBlbnRyeSB0aW1lc3RhbXAgaXQgaXNcbiAqIGNvbXBhcmVkIGFnYWluc3Q6IHRoZSBvbmUgTmV4dC5qcyBzdGFtcHMgYENhY2hlRW50cnkudGltZXN0YW1wYCB3aXRoXG4gKiAoYHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKWAsIGluIGB1c2UtY2FjaGUtd3JhcHBlci5qc2AgYW5kXG4gKiB0aGUgZGVmYXVsdCBoYW5kbGVyKSwgcmF0aGVyIHRoYW4gYERhdGUubm93KClgLiBCb3RoIGhhbmRsZXJzIHdyaXRlIHRoZSBzYW1lXG4gKiBtYXJrZXIgcm93cywgc28gYm90aCBoYXZlIHRvIHVzZSBpdDogdHdvIGNsb2NrcyBvbiBvbmUgcm93IGxldCB0aGUgbGFzdCB3cml0ZXJcbiAqIGRlY2lkZSB3aGljaCBjbG9jayB0aGUgb3RoZXJzIGNvbXBhcmUgYWdhaW5zdCwgYW5kIHRoZXkgZHJpZnQgYXBhcnQgZm9yIGFzXG4gKiBsb25nIGFzIGEgTGFtYmRhIHNhbmRib3ggb3IgRmFyZ2F0ZSB0YXNrIGxpdmVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyQ2xvY2soKTogbnVtYmVyIHtcbiAgcmV0dXJuIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKTtcbn1cblxuLyoqXG4gKiBUaGUgbWFya2VyIGZpZWxkcyBhIHRhZyByZXZhbGlkYXRlZCBhdCBgbm93YCBzZXRzLlxuICpcbiAqIFdpdGhvdXQgYGR1cmF0aW9uc2AgLSBgdXBkYXRlVGFnYCwgb3IgYHJldmFsaWRhdGVUYWdgIHdpdGggbm8gcHJvZmlsZSAtIHRoZVxuICogdGFnJ3MgZW50cmllcyBleHBpcmUgaW1tZWRpYXRlbHkgKGByZXZhbGlkYXRlZEF0YCkuIFdpdGggdGhlbSB0aGUgZW50cmllcyBnb1xuICogc3RhbGUgbm93IGFuZCBleHBpcmUgYWZ0ZXIgdGhlIHByb2ZpbGUncyBgZXhwaXJlYCwgdGhlIHNhbWUgcGFpciBvZlxuICogdGltZXN0YW1wcyBOZXh0LmpzJ3MgYEZpbGVTeXN0ZW1DYWNoZS5yZXZhbGlkYXRlVGFnYCByZWNvcmRzLiBBIHByb2ZpbGUgd2l0aFxuICogbm8gYGV4cGlyZWAgc2V0cyBvbmx5IGBzdGFsZUF0YCwgYW5kIHdoYXRldmVyIGBleHBpcmVkQXRgIHRoZSB0YWcgaGFkIHN0YXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyRm9yKFxuICBub3c6IG51bWJlcixcbiAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuKTogVGFnTWFya2VyIHtcbiAgaWYgKCFkdXJhdGlvbnMpIHtcbiAgICByZXR1cm4geyByZXZhbGlkYXRlZEF0OiBub3cgfTtcbiAgfVxuICBpZiAoZHVyYXRpb25zLmV4cGlyZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHsgc3RhbGVBdDogbm93IH07XG4gIH1cbiAgcmV0dXJuIHsgc3RhbGVBdDogbm93LCBleHBpcmVkQXQ6IG5vdyArIGR1cmF0aW9ucy5leHBpcmUgKiAxMDAwIH07XG59XG5cbmNvbnN0IE1BUktFUl9GSUVMRFMgPSBbXCJyZXZhbGlkYXRlZEF0XCIsIFwic3RhbGVBdFwiLCBcImV4cGlyZWRBdFwiXSBhcyBjb25zdDtcblxuLyoqXG4gKiBgZXhpc3RpbmdgIHdpdGggdGhlIGZpZWxkcyBgdXBkYXRlYCBzZXRzLCBhcyBhIHtAbGluayBtYXJrZXJVcGRhdGV9IGxlYXZlc1xuICogdGhlIHJvdzogYSBmaWVsZCBgdXBkYXRlYCBkb2VzIG5vdCBzZXQga2VlcHMgaXRzIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlNYXJrZXIoXG4gIGV4aXN0aW5nOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQsXG4gIHVwZGF0ZTogVGFnTWFya2VyLFxuKTogVGFnTWFya2VyIHtcbiAgY29uc3QgbWFya2VyID0geyAuLi5leGlzdGluZyB9O1xuICBmb3IgKGNvbnN0IGZpZWxkIG9mIE1BUktFUl9GSUVMRFMpIHtcbiAgICBpZiAodXBkYXRlW2ZpZWxkXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtYXJrZXJbZmllbGRdID0gdXBkYXRlW2ZpZWxkXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1hcmtlcjtcbn1cblxuLyoqIFRoZSBtYXJrZXItcm93IHVwZGF0ZSB0aGF0IHNldHMge0BsaW5rIG1hcmtlckZvcn0ncyBmaWVsZHMuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyVXBkYXRlKFxuICBub3c6IG51bWJlcixcbiAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuKTogUGljazxcbiAgQ29uc3RydWN0b3JQYXJhbWV0ZXJzPHR5cGVvZiBVcGRhdGVJdGVtQ29tbWFuZD5bMF0sXG4gIFwiVXBkYXRlRXhwcmVzc2lvblwiIHwgXCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzXCJcbj4ge1xuICBjb25zdCBtYXJrZXIgPSBtYXJrZXJGb3Iobm93LCBkdXJhdGlvbnMpO1xuICBjb25zdCBmaWVsZHMgPSBNQVJLRVJfRklFTERTLmZpbHRlcigoZmllbGQpID0+IG1hcmtlcltmaWVsZF0gIT09IHVuZGVmaW5lZCk7XG4gIHJldHVybiB7XG4gICAgVXBkYXRlRXhwcmVzc2lvbjogYFNFVCAke2ZpZWxkcy5tYXAoKGZpZWxkKSA9PiBgJHtmaWVsZH0gPSA6JHtmaWVsZH1gKS5qb2luKFwiLCBcIil9YCxcbiAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBmaWVsZHMubWFwKChmaWVsZCkgPT4gW2A6JHtmaWVsZH1gLCB7IE46IFN0cmluZyhtYXJrZXJbZmllbGRdKSB9XSksXG4gICAgKSxcbiAgfTtcbn1cblxuLyoqIEEgRHluYW1vREIgbnVtYmVyIGF0dHJpYnV0ZSBhcyBhIG51bWJlciwgb3IgYHVuZGVmaW5lZGAgd2hlbiBhYnNlbnQuICovXG5mdW5jdGlvbiBudW1iZXJBdHRyaWJ1dGUoXG4gIHZhbHVlOiBBdHRyaWJ1dGVWYWx1ZSB8IHVuZGVmaW5lZCxcbik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB2YWx1ZT8uTiA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogTnVtYmVyKHZhbHVlLk4pO1xufVxuXG4vKiogVGhlIG1hcmtlciBmaWVsZHMgb2YgYSBtYXJrZXIgb3IgbG9nIHJvdy4gKi9cbmZ1bmN0aW9uIG1hcmtlck9mKGl0ZW06IFJlY29yZDxzdHJpbmcsIEF0dHJpYnV0ZVZhbHVlPik6IFRhZ01hcmtlciB7XG4gIHJldHVybiB7XG4gICAgcmV2YWxpZGF0ZWRBdDogbnVtYmVyQXR0cmlidXRlKGl0ZW0ucmV2YWxpZGF0ZWRBdCksXG4gICAgc3RhbGVBdDogbnVtYmVyQXR0cmlidXRlKGl0ZW0uc3RhbGVBdCksXG4gICAgZXhwaXJlZEF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5leHBpcmVkQXQpLFxuICB9O1xufVxuXG4vKiogRHluYW1vREIncyBjYXAgb24ga2V5cyBpbiBvbmUgYEJhdGNoR2V0SXRlbWAuICovXG5leHBvcnQgY29uc3QgQkFUQ0hfR0VUX01BWF9LRVlTID0gMTAwO1xuXG4vKipcbiAqIEhvdyBvZnRlbiwgYXQgbW9zdCwgYW4gaW5zdGFuY2UgY2F0Y2hlcyB1cCBvbiByZXZhbGlkYXRpb25zIG90aGVyIGluc3RhbmNlc1xuICogcmFuLCB1bmxlc3MgYENES19ORVhUSlNfVEFHX1JFRlJFU0hfTVNgIHNheXMgb3RoZXJ3aXNlOiB0aGUgc3RhbGVuZXNzIHdpbmRvd1xuICogZm9yIGEgYHJldmFsaWRhdGVUYWdgIHJ1biBlbHNld2hlcmUuIEV2ZXJ5IGNhY2hlIGhpdCBjaGVja3MgaXRzIHRhZ3MnXG4gKiBtYXJrZXJzLCBhbmQgZXZlcnkgbWFya2VyIG9mIGEgZGVwbG95bWVudCBzaGFyZXMgb25lIHBhcnRpdGlvbiBrZXksIHNvXG4gKiByZWFkaW5nIHRoZW0gcGVyIHJlcXVlc3QgY2FwcGVkIGEgcm91dGUncyBjYWNoZSBoaXRzIGF0IHRoZSBwYXJ0aXRpb24ncyByZWFkXG4gKiB0aHJvdWdocHV0ICh+MSw5MDAgcmVxL3Mgb24gTmV4dGpzUmVnaW9uYWxGdW5jdGlvbnMpLiBPbmNlIGEgc2Vjb25kLCBmcm9tIHRoZVxuICogcmV2YWxpZGF0aW9uIGxvZywgdGhlIHJlYWRzIHNjYWxlIHdpdGggaW5zdGFuY2VzIGluc3RlYWQgb2YgcmVxdWVzdHMgb3IgdGFncy5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVEFHX1JFRlJFU0hfTVMgPSAxMDAwO1xuXG4vKipcbiAqIEhvdyBmYXIgcGFzdCBgcmVmcmVzaEludGVydmFsTXNgIHRoZSBsYXN0IHJlZnJlc2ggbWF5IGhhdmUgc2V0dGxlZCBiZWZvcmUgYVxuICogYCd1c2UgY2FjaGUnYCByZXF1ZXN0IHdhaXRzIGZvciB0aGUgbmV4dCBvbmUgKHNlZVxuICoge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzLmJlaGluZH0pLiBBbiBpbnN0YW5jZSBzZXJ2aW5nIHN0ZWFkeSB0cmFmZmljIHN0YXlzXG4gKiBpbnNpZGUgaXQ7IG9uZSB0aGF0IHNhdCBpZGxlLCBvciBmcm96ZW4gYmV0d2VlbiBMYW1iZGEgaW52b2NhdGlvbnMsIGRvZXMgbm90LlxuICovXG5leHBvcnQgY29uc3QgVEFHX1JFRlJFU0hfR1JBQ0VfTVMgPSAxMDAwO1xuXG4vKiogRHluYW1vREIncyBsaW1pdCBvbiBhIHNvcnQga2V5LCBpbiBVVEYtOCBieXRlcy4gKi9cbmV4cG9ydCBjb25zdCBNQVhfU09SVF9LRVlfQllURVMgPSAxMDI0O1xuXG4vKipcbiAqIGAjPHNoYTI1Nih0YWcpPmAsIHN0YW5kaW5nIGluIGZvciBhIHRhZyBpbiBhIHNvcnQga2V5IGl0IHdvdWxkIHB1c2ggcGFzdFxuICoge0BsaW5rIE1BWF9TT1JUX0tFWV9CWVRFU30uIE5leHQuanMgY2FwcyB0aGUgdGFncyBhbiBhcHAgbmFtZXMsIGJ1dCBub3QgYW5cbiAqIGltcGxpY2l0IGBfTl9UXy/igKZgIHRhZywgd2hpY2ggaXMgYXMgbG9uZyBhcyBpdHMgcGF0aCwgYW5kIGEgcmVqZWN0ZWQgd3JpdGVcbiAqIGxlZnQgYHJldmFsaWRhdGVQYXRoYCBvbiBhIGxvbmcgcGF0aCByZWNvcmRlZCBub3doZXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaGVkVGFnKHRhZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAjJHtzaGEyNTZIZXgodGFnKX1gO1xufVxuXG4vKipcbiAqIFRoZSBsb25nZXN0IHRhZyBhIHNvcnQga2V5IHNwZWxscyBvdXQ7IHBhc3QgaXQsIHtAbGluayBzb3J0S2V5VGFnfSBoYXNoZXNcbiAqIGl0LiBPbmUgY2FwIGZvciBldmVyeSByb3cgdGhlIHRhZyBpcyBpbiwgc28gYSByb3cncyB3cml0ZXIgYW5kIHJlYWRlciBhZ3JlZVxuICogd2l0aG91dCBlYWNoIHdvcmtpbmcgb3V0IHdoYXQgZWxzZSBzaGFyZXMgaXRzIGtleS4gSXQgbGVhdmVzIHJvb20gZm9yIHRoZVxuICogbW9zdCBhbnkgcm93IHB1dHMgYmVzaWRlIHRoZSB0YWc6IGEgbWFwcGluZyByb3cncyBgIzxidWlsZElkPi8jPHNoYTI1Nj5gLFxuICogd2l0aCB0aGUgYnVpbGQgSUQgY2FwcGVkIGF0IGBNQVhfQlVJTERfSURfQllURVNgLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1RBR19CWVRFUyA9IDc2ODtcblxuLyoqIGB0YWdgIGFzIGEgc29ydCBrZXkgc3BlbGxzIGl0OiBpdHNlbGYsIG9yIHtAbGluayBoYXNoZWRUYWd9IHBhc3Qge0BsaW5rIE1BWF9UQUdfQllURVN9LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvcnRLZXlUYWcodGFnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gQnVmZmVyLmJ5dGVMZW5ndGgodGFnKSA8PSBNQVhfVEFHX0JZVEVTID8gdGFnIDogaGFzaGVkVGFnKHRhZyk7XG59XG5cbi8qKlxuICogVGhlIGJhcmUtdGFnIG1hcmtlciByb3dzIG9mIHRoZSByZXZhbGlkYXRpb24gdGFibGUgKGBwayA9IGJ1aWxkSWRgLFxuICogYHNrID0gdGFnYCwgb3Ige0BsaW5rIGhhc2hlZFRhZ30gcGFzdCB7QGxpbmsgTUFYX1RBR19CWVRFU30pLCB3aGljaCByZWNvcmQgd2hlbiBhIHRhZ1xuICogd2FzIGxhc3QgcmV2YWxpZGF0ZWQgYW5kIGhvdy5cbiAqXG4gKiBUaGUgdGFibGUgYWxzbyBob2xkcyB0aGUgaW5jcmVtZW50YWwgY2FjaGUncyBgdGFnI3MzS2V5YCBtYXBwaW5nIHJvd3MsIHdoaWNoXG4gKiBhcmUgaXRzIG93biBidXNpbmVzcyBhbmQgc3RheSBpbiBgUzNDYWNoZUhhbmRsZXJgOiBvbmx5IHRoZSBtYXJrZXJzIG1lYW4gdGhlXG4gKiBzYW1lIHRoaW5nIHRvIGV2ZXJ5IGhhbmRsZXIuIFdoYXQgYW4gaW5zdGFuY2Uga2VlcHMgb2YgdGhlbSBiZXR3ZWVuIHJlYWRzIGlzXG4gKiB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9LlxuICovXG5leHBvcnQgY2xhc3MgVGFnTWFya2VyVGFibGUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogRHluYW1vREJDbGllbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJ1aWxkSWQ6IHN0cmluZyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYHRhZ2AncyByZXZhbGlkYXRpb24gYXQgYG5vd2AuIFNlZSB7QGxpbmsgbWFya2VyVXBkYXRlfS5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgcm93IGFzIHRoaXMgd3JpdGUgbGVmdCBpdCwgc28gdGhlIGluc3RhbmNlIHRoYXQgd3JvdGUgaXQgY2FuXG4gICAqIHRyYWNrIGl0IHJhdGhlciB0aGFuIHJlYWQgaXQgYmFjazogcmVhZHMgYXJlIGV2ZW50dWFsbHkgY29uc2lzdGVudCwgYW5kIGFcbiAgICogcmVhZC1iYWNrIHJhY2luZyByZXBsaWNhdGlvbiBjb3VsZCByZXR1cm4gdGhlIG1hcmtlciBmcm9tIGJlZm9yZSB0aGUgd3JpdGUuXG4gICAqL1xuICBhc3luYyB3cml0ZShcbiAgICB0YWc6IHN0cmluZyxcbiAgICBub3c6IG51bWJlcixcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8VGFnTWFya2VyIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgbmV3IFVwZGF0ZUl0ZW1Db21tYW5kKHtcbiAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgS2V5OiB7XG4gICAgICAgICAgcGs6IHsgUzogdGhpcy5idWlsZElkIH0sXG4gICAgICAgICAgc2s6IHsgUzogc29ydEtleVRhZyh0YWcpIH0sXG4gICAgICAgIH0sXG4gICAgICAgIC4uLm1hcmtlclVwZGF0ZShub3csIGR1cmF0aW9ucyksXG4gICAgICAgIFJldHVyblZhbHVlczogXCJBTExfTkVXXCIsXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiByZXNwb25zZT8uQXR0cmlidXRlcyA/IG1hcmtlck9mKHJlc3BvbnNlLkF0dHJpYnV0ZXMpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBtYXJrZXIgcm93cyBmb3IgYHRhZ3NgIHRoYXQgZXhpc3QsIGJ5IHRhZywgaW4gb25lIGBCYXRjaEdldEl0ZW1gIHBlclxuICAgKiB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSB0YWdzIHJhdGhlciB0aGFuIGEgYEdldEl0ZW1gIGVhY2g6IGEgcGFnZVxuICAgKiBjYXJyaWVzIGl0cyB3aG9sZSBpbXBsaWNpdCBgX05fVF8v4oCmYCBjaGFpbiBwbHVzIHRoZSBhcHAncyBvd24gdGFncywgYVxuICAgKiBwYWdlIHdpdGggYSBmZXcgZmV0Y2hlcyBjaGVja3MgZWFjaCBvZiB0aGVtIHRvbywgYW5kIGV2ZXJ5IG9uZSBpcyBvbiB0aGVcbiAgICogcmVxdWVzdCBwYXRoLiBBIHRhZyB3aXRoIG5vIHJvdyBpcyBhYnNlbnQgZnJvbSB0aGUgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgcmVhZCh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8TWFwPHN0cmluZywgVGFnTWFya2VyPj4ge1xuICAgIGNvbnN0IHsgdGFibGVOYW1lLCBidWlsZElkIH0gPSB0aGlzO1xuICAgIGNvbnN0IHVuaXF1ZSA9IEFycmF5LmZyb20obmV3IFNldCh0YWdzKSk7XG4gICAgY29uc3QgbWFya2VycyA9IG5ldyBNYXA8c3RyaW5nLCBUYWdNYXJrZXI+KCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVuaXF1ZS5sZW5ndGg7IGkgKz0gQkFUQ0hfR0VUX01BWF9LRVlTKSB7XG4gICAgICAvLyBBIGhhc2hlZCBzb3J0IGtleSBuYW1lcyBubyB0YWcsIHNvIGVhY2ggcm93IGlzIG1hdGNoZWQgYmFjayBieSBrZXkuXG4gICAgICBjb25zdCB0YWdCeVNrID0gbmV3IE1hcChcbiAgICAgICAgdW5pcXVlXG4gICAgICAgICAgLnNsaWNlKGksIGkgKyBCQVRDSF9HRVRfTUFYX0tFWVMpXG4gICAgICAgICAgLm1hcCgodGFnKSA9PiBbc29ydEtleVRhZyh0YWcpLCB0YWddKSxcbiAgICAgICk7XG4gICAgICBsZXQga2V5czogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+W10gfCB1bmRlZmluZWQgPSBBcnJheS5mcm9tKFxuICAgICAgICB0YWdCeVNrLmtleXMoKSxcbiAgICAgICAgKHNrKSA9PiAoeyBwazogeyBTOiBidWlsZElkIH0sIHNrOiB7IFM6IHNrIH0gfSksXG4gICAgICApO1xuICAgICAgLy8gYFVucHJvY2Vzc2VkS2V5c2AgaXMgRHluYW1vREIgZGVjbGluaW5nIHBhcnQgb2YgdGhlIGJhdGNoIHVuZGVyIGxvYWQ7XG4gICAgICAvLyBhIG1hcmtlciBsZWZ0IHVucmVhZCBpcyBhIHJldmFsaWRhdGlvbiBtaXNzZWQsIHNvIGl0IGlzIGFza2VkIGFnYWluLlxuICAgICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGtleXM/Lmxlbmd0aCAmJiBhdHRlbXB0IDwgMzsgYXR0ZW1wdCsrKSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlOiBCYXRjaEdldEl0ZW1Db21tYW5kT3V0cHV0ID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgQmF0Y2hHZXRJdGVtQ29tbWFuZCh7XG4gICAgICAgICAgICBSZXF1ZXN0SXRlbXM6IHtcbiAgICAgICAgICAgICAgW3RhYmxlTmFtZV06IHtcbiAgICAgICAgICAgICAgICBLZXlzOiBrZXlzLFxuICAgICAgICAgICAgICAgIFByb2plY3Rpb25FeHByZXNzaW9uOiBcInNrLCByZXZhbGlkYXRlZEF0LCBzdGFsZUF0LCBleHBpcmVkQXRcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiByZXNwb25zZS5SZXNwb25zZXM/Llt0YWJsZU5hbWVdID8/IFtdKSB7XG4gICAgICAgICAgY29uc3QgdGFnID0gdGFnQnlTay5nZXQoaXRlbS5zaz8uUyA/PyBcIlwiKTtcbiAgICAgICAgICBpZiAodGFnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG1hcmtlcnMuc2V0KHRhZywgbWFya2VyT2YoaXRlbSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBrZXlzID0gcmVzcG9uc2UuVW5wcm9jZXNzZWRLZXlzPy5bdGFibGVOYW1lXT8uS2V5cztcbiAgICAgIH1cbiAgICAgIGlmIChrZXlzPy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBEeW5hbW9EQiBsZWZ0ICR7a2V5cy5sZW5ndGh9IHRhZyBtYXJrZXJzIHVucmVhZCBhZnRlciByZXRyeWluZ2AsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXJrZXJzO1xuICB9XG59XG5cbi8qKlxuICogSG93IGxvbmcgYSByZXZhbGlkYXRpb24gbG9nIHJvdyBpcyBrZXB0IChgdHRsYCwgZXBvY2ggc2Vjb25kcykuIER5bmFtb0RCIG5ldmVyXG4gKiBkZWxldGVzIGFuIGl0ZW0gYmVmb3JlIGl0cyBUVEwsIG9ubHkgc29tZSB0aW1lIGFmdGVyLCBzbyBhIHJlYWRlciB0aGF0IGxhc3RcbiAqIHF1ZXJpZWQgbGVzcyB0aGFuIHRoaXMgbG9uZyBhZ28gKGxlc3MgYSBtYXJnaW4gZm9yIHdyaXRlcnMnIGNsb2NrcykgaXMgc3VyZVxuICogdG8gZmluZCBldmVyeSByb3cgaXQgaGFzIG5vdCBzZWVuIHlldC5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfVFRMX01TID0gMTUgKiA2MCAqIDEwMDA7XG5cbi8qKiBUaGUgbW9zdCBgUXVlcnlgIHBhZ2VzIG9uZSB7QGxpbmsgUmV2YWxpZGF0aW9uTG9nLnF1ZXJ5fSByZWFkcy4gKi9cbmV4cG9ydCBjb25zdCBSRVZBTElEQVRJT05fTE9HX01BWF9QQUdFUyA9IDU7XG5cbi8qKiBIb3cgbWFueSBzb3J0IGtleXMge0BsaW5rIFJldmFsaWRhdGlvbkxvZy5wdXR9IHRyaWVzIGJlZm9yZSBnaXZpbmcgdXAuICovXG5jb25zdCBMT0dfUFVUX0FUVEVNUFRTID0gNTtcblxuLyoqIERpZ2l0cyBhIGxvZyByb3cncyB0aW1lc3RhbXAgaXMgemVyby1wYWRkZWQgdG8sIHNvIHNvcnQga2V5cyBzb3J0IGJ5IHRpbWUuICovXG5jb25zdCBMT0dfU0tfRElHSVRTID0gMTU7XG5cbi8qKiBBIHJldmFsaWRhdGlvbiByZWFkIGJhY2sgZnJvbSB0aGUgbG9nLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXZhbGlkYXRpb25Mb2dSb3cge1xuICAvKiogVGhlIHJvdydzIHNvcnQga2V5OiB1bmlxdWUgcGVyIHJldmFsaWRhdGlvbiBvZiBhIHRhZy4gKi9cbiAgc2s6IHN0cmluZztcbiAgLyoqIFdoZW4gaXQgd2FzIHdyaXR0ZW4sIG9uIHRoZSB3cml0ZXIncyBgRGF0ZS5ub3coKWAuICovXG4gIGF0OiBudW1iZXI7XG4gIHRhZzogc3RyaW5nO1xuICAvKiogVGhlIG1hcmtlciBmaWVsZHMgdGhlIHJldmFsaWRhdGlvbiBzZXQsIGFzIHtAbGluayBtYXJrZXJGb3J9IHJldHVybnMgdGhlbS4gKi9cbiAgbWFya2VyOiBUYWdNYXJrZXI7XG59XG5cbi8qKlxuICogVGhlIHJldmFsaWRhdGlvbiBsb2c6IG9uZSByb3cgcGVyIHRhZyByZXZhbGlkYXRpb24gKGBwayA9IDxidWlsZElkPiNsb2dgLFxuICogYHNrID0gPERhdGUubm93KCksIHplcm8tcGFkZGVkPiM8dGFnPmApLCB3aGljaCBleHBpcmVzIGFmdGVyXG4gKiB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19UVExfTVN9LiBBIHRhZyBwYXN0IHtAbGluayBNQVhfVEFHX0JZVEVTfSBpc1xuICoge0BsaW5rIGhhc2hlZFRhZ30gdGhlcmUsIGFuZCBzcGVsbGVkIG91dCBpbiB0aGUgcm93J3MgYGxvbmdUYWdgIGluc3RlYWQuXG4gKlxuICogVGhlIG1hcmtlciByb3dzIHN0YXkgdGhlIHNvdXJjZSBvZiB0cnV0aC4gVGhlIGxvZyBleGlzdHMgc28gYW4gaW5zdGFuY2VcbiAqIGNhbiBhc2sgXCJ3aGF0IHdhcyByZXZhbGlkYXRlZCBzaW5jZSBJIGxhc3QgbG9va2VkP1wiIGluIG9uZSBgUXVlcnlgLCBpbnN0ZWFkXG4gKiBvZiByZS1yZWFkaW5nIGV2ZXJ5IHRhZyBpdCB0cmFja3MgdG8gZmluZCBvdXQgdGhhdCBhbG1vc3Qgbm9uZSBjaGFuZ2VkLiBFdmVyeVxuICogbWFya2VyIHJvdyBvZiBhIGRlcGxveW1lbnQgc2hhcmVzIG9uZSBwYXJ0aXRpb24sIGFuZCB0aG9zZSByZS1yZWFkcyBmcm9tIGFcbiAqIGhhbmRmdWwgb2YgYnVzeSBpbnN0YW5jZXMgd2VyZSBlbm91Z2ggdG8gdGhyb3R0bGUgaXQuXG4gKlxuICogVGhlIHNvcnQga2V5J3MgdGltZXN0YW1wIGlzIHRoZSB3cml0ZXIncyB3YWxsIGNsb2NrIChgRGF0ZS5ub3coKWApLCBub3QgdGhlXG4gKiBwZXJmb3JtYW5jZSBjbG9jayAoe0BsaW5rIG1hcmtlckNsb2NrfSkgdGhlIG1hcmtlciB2YWx1ZXMgYXJlIHN0YW1wZWQgd2l0aCBieSBib3RoXG4gKiBoYW5kbGVyczogaXQgb25seSBvcmRlcnMgcm93cyBmb3IgcmVhZGVycycgY3Vyc29ycywgd2hpY2ggYXJlIG9uIHRoZWlyIG93blxuICogd2FsbCBjbG9ja3MsIGFuZCBpcyBuZXZlciBjb21wYXJlZCB3aXRoIGFuIGVudHJ5J3MgdGltZXN0YW1wLlxuICovXG5leHBvcnQgY2xhc3MgUmV2YWxpZGF0aW9uTG9nIHtcbiAgcHJpdmF0ZSByZWFkb25seSBwazogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBEeW5hbW9EQkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGJ1aWxkSWQ6IHN0cmluZyxcbiAgKSB7XG4gICAgdGhpcy5wayA9IGAke2J1aWxkSWR9I2xvZ2A7XG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkIHRoYXQgYHRhZ2Agd2FzIHJldmFsaWRhdGVkIGF0IGBhdGAgKGBEYXRlLm5vdygpYCksIHNldHRpbmcgYG1hcmtlcmAuXG4gICAqXG4gICAqIFR3byByZXZhbGlkYXRpb25zIG9mIGB0YWdgIGluIHRoZSBzYW1lIG1pbGxpc2Vjb25kIHdvdWxkIHNoYXJlIGEgc29ydCBrZXksXG4gICAqIGFuZCB0aGUgc2Vjb25kIHdvdWxkIG92ZXJ3cml0ZSB0aGUgZmlyc3QuIFNvIHRoZSByb3cgaXMgb25seSB3cml0dGVuIHdoZXJlXG4gICAqIGl0cyBrZXkgaXMgZnJlZSwgYW5kIG9uIGEgY29sbGlzaW9uIGl0IG1vdmVzIHRvIHRoZSBuZXh0IG1pbGxpc2Vjb25kLCB1cFxuICAgKiB0byB7QGxpbmsgTE9HX1BVVF9BVFRFTVBUU30gdGltZXMuXG4gICAqL1xuICBhc3luYyBwdXQodGFnOiBzdHJpbmcsIGF0OiBudW1iZXIsIG1hcmtlcjogVGFnTWFya2VyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc2tUYWcgPSBzb3J0S2V5VGFnKHRhZyk7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBpdGVtOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gPSB7XG4gICAgICAgIHBrOiB7IFM6IHRoaXMucGsgfSxcbiAgICAgICAgc2s6IHsgUzogYCR7bG9nU2tQcmVmaXgoYXQpfSMke3NrVGFnfWAgfSxcbiAgICAgICAgdHRsOiB7IE46IFN0cmluZyhNYXRoLmNlaWwoKGF0ICsgUkVWQUxJREFUSU9OX0xPR19UVExfTVMpIC8gMTAwMCkpIH0sXG4gICAgICAgIC4uLihza1RhZyAhPT0gdGFnICYmIHsgbG9uZ1RhZzogeyBTOiB0YWcgfSB9KSxcbiAgICAgIH07XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIE1BUktFUl9GSUVMRFMpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBtYXJrZXJbZmllbGRdO1xuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGl0ZW1bZmllbGRdID0geyBOOiBTdHJpbmcodmFsdWUpIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICAgICAgbmV3IFB1dEl0ZW1Db21tYW5kKHtcbiAgICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgICBJdGVtOiBpdGVtLFxuICAgICAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogXCJhdHRyaWJ1dGVfbm90X2V4aXN0cyhzaylcIixcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChlcnJvciBhcyBFcnJvciB8IHVuZGVmaW5lZCk/Lm5hbWUgIT09XG4gICAgICAgICAgICBcIkNvbmRpdGlvbmFsQ2hlY2tGYWlsZWRFeGNlcHRpb25cIiB8fFxuICAgICAgICAgIGF0dGVtcHQgPj0gTE9HX1BVVF9BVFRFTVBUU1xuICAgICAgICApIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBhdCA9IE1hdGguZmxvb3IoYXQpICsgMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIHJvd3Mgd3JpdHRlbiBhdCBvciBhZnRlciBgc2luY2VgIChgRGF0ZS5ub3coKWApLCBvbGRlc3QgZmlyc3QuXG4gICAqIGB0cnVuY2F0ZWRgIHdoZW4gdGhlcmUgd2VyZSBtb3JlIHRoYW4ge0BsaW5rIFJFVkFMSURBVElPTl9MT0dfTUFYX1BBR0VTfVxuICAgKiBwYWdlcyBvZiB0aGVtLCBhbmQgYHJvd3NgIGlzIG9ubHkgdGhlIHN0YXJ0LlxuICAgKlxuICAgKiBFdmVudHVhbGx5IGNvbnNpc3RlbnQ6IGEgcm93IHdyaXR0ZW4gYSBtb21lbnQgYWdvIG1heSBub3Qgc2hvdyB5ZXQsIHdoaWNoXG4gICAqIGlzIHdoYXQgdGhlIHJlYWRlcidzIGxvb2tiYWNrIGlzIGZvci5cbiAgICovXG4gIGFzeW5jIHF1ZXJ5KFxuICAgIHNpbmNlOiBudW1iZXIsXG4gICk6IFByb21pc2U8eyByb3dzOiBSZXZhbGlkYXRpb25Mb2dSb3dbXTsgdHJ1bmNhdGVkOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCByb3dzOiBSZXZhbGlkYXRpb25Mb2dSb3dbXSA9IFtdO1xuICAgIGxldCBzdGFydEtleTogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+IHwgdW5kZWZpbmVkO1xuICAgIGZvciAobGV0IHBhZ2UgPSAwOyBwYWdlIDwgUkVWQUxJREFUSU9OX0xPR19NQVhfUEFHRVM7IHBhZ2UrKykge1xuICAgICAgY29uc3QgcmVzcG9uc2U6IFF1ZXJ5Q29tbWFuZE91dHB1dCA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBRdWVyeUNvbW1hbmQoe1xuICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgS2V5Q29uZGl0aW9uRXhwcmVzc2lvbjogXCJwayA9IDpwayBBTkQgc2sgPj0gOnNpbmNlXCIsXG4gICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczoge1xuICAgICAgICAgICAgXCI6cGtcIjogeyBTOiB0aGlzLnBrIH0sXG4gICAgICAgICAgICBcIjpzaW5jZVwiOiB7IFM6IGxvZ1NrUHJlZml4KE1hdGgubWF4KDAsIHNpbmNlKSkgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFByb2plY3Rpb25FeHByZXNzaW9uOlxuICAgICAgICAgICAgXCJzaywgbG9uZ1RhZywgcmV2YWxpZGF0ZWRBdCwgc3RhbGVBdCwgZXhwaXJlZEF0XCIsXG4gICAgICAgICAgRXhjbHVzaXZlU3RhcnRLZXk6IHN0YXJ0S2V5LFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgcmVzcG9uc2UuSXRlbXMgPz8gW10pIHtcbiAgICAgICAgY29uc3Qgc2sgPSBpdGVtLnNrPy5TO1xuICAgICAgICAvLyBgPGRpZ2l0cz4jPHRhZz5gOiB0aGUgdGFnIGlzIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpeGVkLXdpZHRoXG4gICAgICAgIC8vIHRpbWVzdGFtcCwgYCNgcyBpbmNsdWRlZC5cbiAgICAgICAgaWYgKHNrID09PSB1bmRlZmluZWQgfHwgc2tbTE9HX1NLX0RJR0lUU10gIT09IFwiI1wiKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgICBzayxcbiAgICAgICAgICBhdDogTnVtYmVyKHNrLnNsaWNlKDAsIExPR19TS19ESUdJVFMpKSxcbiAgICAgICAgICB0YWc6IGl0ZW0ubG9uZ1RhZz8uUyA/PyBzay5zbGljZShMT0dfU0tfRElHSVRTICsgMSksXG4gICAgICAgICAgbWFya2VyOiBtYXJrZXJPZihpdGVtKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBzdGFydEtleSA9IHJlc3BvbnNlLkxhc3RFdmFsdWF0ZWRLZXk7XG4gICAgICBpZiAoIXN0YXJ0S2V5KSB7XG4gICAgICAgIHJldHVybiB7IHJvd3MsIHRydW5jYXRlZDogZmFsc2UgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgcm93cywgdHJ1bmNhdGVkOiB0cnVlIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9nU2tQcmVmaXgoYXQ6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBTdHJpbmcoTWF0aC5mbG9vcihhdCkpLnBhZFN0YXJ0KExPR19TS19ESUdJVFMsIFwiMFwiKTtcbn1cblxuLyoqXG4gKiBIb3cgZmFyIGJlaGluZCB0aGUgbGFzdCBxdWVyeSdzIHN0YXJ0IHRoZSBuZXh0IG9uZSBzdGFydHMgcmVhZGluZyB0aGUgbG9nOlxuICogdGhlIHJvb20gZm9yIHRoZSBgUXVlcnlgIGJlaW5nIGV2ZW50dWFsbHkgY29uc2lzdGVudCBhbmQgZm9yIHdyaXRlcnMnIGNsb2Nrc1xuICogcnVubmluZyBiZWhpbmQgdGhlIHJlYWRlcidzLiBSb3dzIGluc2lkZSBpdCBhcmUgcmVhZCBhZ2FpbiwgYW5kIGRyb3BwZWQgYXNcbiAqIGFscmVhZHkgYXBwbGllZC5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVMgPSA1MDAwO1xuXG4vKipcbiAqIFRoZSBsb25nZXN0IHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30gdHJ1c3RzIHRoZSBsb2cgYWxvbmUgZm9yIGEgdGFnIGJlZm9yZVxuICogcmVhZGluZyBpdHMgbWFya2VyIHJvdyBhZ2Fpbi4gVGhlIGxvZyBpcyB0aGUgZmFzdCBwYXRoLCBidXQgdGhlIG1hcmtlciByb3dzXG4gKiBhcmUgdGhlIHNvdXJjZSBvZiB0cnV0aDogYSBsb2cgcm93IHdob3NlIHdyaXRlIGZhaWxlZCB3b3VsZCBvdGhlcndpc2UgYmVcbiAqIG1pc3NlZCBmb3IgYXMgbG9uZyBhcyB0aGUgdGFnIHN0YXlzIHRyYWNrZWQuXG4gKlxuICogUm9sbGluZywgbm90IGFsbCBhdCBvbmNlOiBlYWNoIHJlZnJlc2ggcmUtcmVhZHMgYXQgbW9zdFxuICoge0BsaW5rIEJBVENIX0dFVF9NQVhfS0VZU30gb2YgdGhlIHRhZ3MgZHVlLCBvbGRlc3QgZmlyc3QuIFJlLXJlYWRpbmcgdGhlbSBhbGxcbiAqIHRvZ2V0aGVyIGNvc3QgfjUwMCBSQ1UgYXQgMTAwMCB0YWdzIC0gYSBmbGVldCBzdGFydGVkIGJ5IG9uZSBsb2FkIHRlc3QgZGlkIGl0XG4gKiBpbiB0aGUgc2FtZSBtaW51dGUsIDEyLDgwMCBSQ1UsIGFuZCB0aHJvdHRsZWQgLSBhbmQgd291bGQgYmUgfjUsMDAwIFJDVSBhdFxuICoge0BsaW5rIERFRkFVTFRfTUFYX1RSQUNLRURfVEFHU30sIHBhc3Qgd2hhdCB0aGUgb25lIHBhcnRpdGlvbiBzZXJ2ZXMgaW4gYVxuICogc2Vjb25kLiBTcHJlYWQgb3V0LCAxMCwwMDAgdHJhY2tlZCB0YWdzIGNvc3QgfjggUkNVIGEgc2Vjb25kIHBlciBpbnN0YW5jZS5cbiAqXG4gKiBFYWNoIHRhZyBpcyBkdWUgYXQgYSByYW5kb20gNzUtMTAwJSBvZiB0aGlzIGFmdGVyIGl0IHdhcyBsYXN0IHJlYWQsIHNvIHRhZ3NcbiAqIGZpcnN0IHJlYWQgdG9nZXRoZXIgLSBhbiBpbnN0YW5jZSB3YXJtaW5nIHVwIC0gZG8gbm90IGFsbCBjb21lIGR1ZSB0b2dldGhlclxuICogYWdhaW4gZXZlcnkgaW50ZXJ2YWw6IHRoZSBsb2FkIHRlc3QgdGhhdCBtZWFzdXJlZCB0aGUgcm9sbGluZyByZS1yZWFkIHNhd1xuICogaXRzIHdhcm0tdXAncyByZWFkcyByZXR1cm4gYXMgYSAzMC0zNiBSQ1UvcyBidW1wIHRlbiBtaW51dGVzIGxhdGVyLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9UQUdfUkVTWU5DX01TID0gMTAgKiA2MCAqIDEwMDA7XG5cbi8qKiBUaGUgZnJhY3Rpb24gb2Yge0BsaW5rIERFRkFVTFRfVEFHX1JFU1lOQ19NU30gYSB0YWcgbWF5IGNvbWUgZHVlIGVhcmx5IGJ5LiAqL1xuY29uc3QgVEFHX1JFU1lOQ19KSVRURVIgPSAwLjI1O1xuXG4vKipcbiAqIEhvdyBsb25nIHNpbmNlIHRoZSBsYXN0IHN1Y2Nlc3NmdWwgbG9nIHF1ZXJ5IHRoZSBsb2cgY2FuIHN0aWxsIGJlIHRydXN0ZWQgdG9cbiAqIGhvbGQgZXZlcnkgcm93IG5vdCByZWFkIHlldDogaXRzIFRUTCBsZXNzIGEgbWFyZ2luIGZvciB3cml0ZXJzJyBjbG9ja3MuIFBhc3RcbiAqIGl0IC0gYSBMYW1iZGEgZnJvemVuIGJldHdlZW4gaW52b2NhdGlvbnMsIGEgcnVuIG9mIGZhaWxlZCBxdWVyaWVzIC0gdGhlXG4gKiB0cmFja2VkIG1hcmtlcnMgYXJlIGZvcmdvdHRlbiwgdG8gYmUgcmVhZCBhZ2FpbiBhcyB0aGV5IGFyZSBuZWVkZWQsIGFuZCB0aGVcbiAqIGxvZyBpcyBmb2xsb3dlZCBmcm9tIHRoZXJlLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1JFVkFMSURBVElPTl9MT0dfR0FQX01TID1cbiAgUkVWQUxJREFUSU9OX0xPR19UVExfTVMgLSA1ICogNjAgKiAxMDAwO1xuXG4vKipcbiAqIFRoZSBtb3N0IHRhZ3Mgb25lIGluc3RhbmNlIHRyYWNrcy4gUGFzdCBpdCB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCBpc1xuICogZm9yZ290dGVuLCB3aGljaCBjb3N0cyBhIHJlYWQgdGhlIG5leHQgdGltZSBpdCBpcyBuZWVkZWQ6IGFuIHVudHJhY2tlZCB0YWdcbiAqIGlzIHJlYWQgYmVmb3JlIGl0IGlzIHRydXN0ZWQuXG4gKlxuICogQSB0cmFja2VkIHRhZyBjb3N0cyBtZW1vcnkgKH4yIE1CIGF0IHRoaXMgYm91bmQpIGFuZCBpdHMgc2hhcmUgb2YgdGhlIHJvbGxpbmdcbiAqIHJlLXJlYWQsIG5vdCBhIHJlYWQgZXZlcnkgcmVmcmVzaCwgc28gdGhlIGJvdW5kIGlzIHNldCBieSBob3cgbWFueSB0YWdzIGFuXG4gKiBpbnN0YW5jZSByZWFsbHkgdXNlcy4gRXZlcnkgcGF0aCBpcyBhIHRhZyBvZiBpdHMgb3duIChgX05fVF8vPHBhdGg+YCksIGFuZCBhdFxuICogMTAwMCBhbiBhcHAgb2YgMTAwMCB0YWdnZWQgcGFnZXMga2VwdCBldmljdGluZyB3aGF0IGl0IHdhcyBhYm91dCB0byBuZWVkOlxuICogaGFsZiBpdHMgcmVxdWVzdHMgcmUtcmVhZCBhIG1hcmtlci5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTUFYX1RSQUNLRURfVEFHUyA9IDEwXzAwMDtcblxuLyoqXG4gKiBUaGUgcmV2YWxpZGF0aW9uIHRhYmxlJ3MgbWFya2VyIHJvd3MgYW5kIGl0cyBsb2csIHdoaWNoIGFyZSBvbmx5IGV2ZXIgdXNlZFxuICogdG9nZXRoZXIsIG9yIG5laXRoZXIgZm9yIHRhZ3MgbG9jYWwgdG8gdGhpcyBwcm9jZXNzLlxuICovXG5leHBvcnQgdHlwZSBUYWdUYWJsZSA9XG4gIHwgeyBtYXJrZXJzOiBUYWdNYXJrZXJUYWJsZTsgbG9nOiBSZXZhbGlkYXRpb25Mb2cgfVxuICB8IHsgbWFya2Vycz86IHVuZGVmaW5lZDsgbG9nPzogdW5kZWZpbmVkIH07XG5cbi8qKiBIb3cge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzfSBpcyBidWlsdC4gKi9cbmV4cG9ydCB0eXBlIFRyYWNrZWRUYWdNYXJrZXJzT3B0aW9ucyA9IFRhZ1RhYmxlICYge1xuICAvKipcbiAgICogSG93IG9mdGVuLCBhdCBtb3N0LCB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnMucmVmcmVzaH0gcmVhZHMgYW55dGhpbmcuXG4gICAqIEBkZWZhdWx0IERFRkFVTFRfVEFHX1JFRlJFU0hfTVNcbiAgICovXG4gIHJlZnJlc2hJbnRlcnZhbE1zPzogbnVtYmVyO1xuICBtYXhUcmFja2VkVGFncz86IG51bWJlcjtcbiAgLyoqIEBzZWUgREVGQVVMVF9UQUdfUkVTWU5DX01TICovXG4gIHJlc3luY0ludGVydmFsTXM/OiBudW1iZXI7XG4gIC8qKiBUaGUgd2FsbCBjbG9jayB0aGUgbG9nJ3MgY3Vyc29yIGFuZCB0aGUgaW50ZXJ2YWxzIGFyZSBrZXB0IG9uLiAqL1xuICBjbG9jaz86ICgpID0+IG51bWJlcjtcbiAgLyoqIGBNYXRoLnJhbmRvbWAsIGZvciB3aGVuIGVhY2ggdGFnJ3MgcmUtcmVhZCBjb21lcyBkdWUuICovXG4gIHJhbmRvbT86ICgpID0+IG51bWJlcjtcbiAgZGVidWc/OiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xuICAvKipcbiAgICogV2hldGhlciB0aGUgcHJvY2VzcyBjYW4gYmUgZnJvemVuIHdpdGggYSByZWZyZXNoIGluIGZsaWdodCwgYXMgYSBMYW1iZGFcbiAgICogc2FuZGJveCBpcyBiZXR3ZWVuIGludm9jYXRpb25zOiB0aGVuIGEgdGltZXIgY2hlY2tzIGl0IGtlcHQgcnVubmluZywgYW5kXG4gICAqIG9uZSB0aGF0IHNwYW5uZWQgYSBmcmVlemUgZG9lcyBub3QgY291bnQuIEEgY29udGFpbmVyIGlzIG5ldmVyIGZyb3plbixcbiAgICogc28gaXQgc2tpcHMgdGhlIHRpbWVyIGFuZCB3YWl0cyBmb3IgdGhlIHJlZnJlc2ggaW4gZmxpZ2h0LCBob3dldmVyIHNsb3cuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBjYW5GcmVlemU/OiBib29sZWFuO1xufTtcblxuLyoqXG4gKiBPbmUgaW5zdGFuY2UncyBjb3B5IG9mIHRoZSBtYXJrZXIgcm93cyBvZiB0aGUgdGFncyBpdCBoYXMgbmVlZGVkLCBrZXB0XG4gKiBjdXJyZW50IHRocm91Z2ggdGhlIHtAbGluayBSZXZhbGlkYXRpb25Mb2d9OiB0aGUgcHJvY2VzcydzIG9uZSB0YWcgbWFuaWZlc3RcbiAqIChgc2hhcmVkVGFnTWFuaWZlc3RgKSwgZm9yIHRoZSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXJzIGFuZCB0aGUgaW5jcmVtZW50YWxcbiAqIGNhY2hlIGFsaWtlLlxuICpcbiAqIE5leHQuanMncyBidWlsdC1pbiBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIga2VlcHMgdGFncyBpbiBhIG1vZHVsZS1sZXZlbCBtYXBcbiAqIChgdGFncy1tYW5pZmVzdC5leHRlcm5hbC5qc2ApIHRoYXQgb25seSBpdHMgb3duIGB1cGRhdGVUYWdzYCB3cml0ZXMsIGFuZCBpdHNcbiAqIGByZWZyZXNoVGFnc2AgaXMgYSBuby1vcCwgc28gYSBgcmV2YWxpZGF0ZVRhZ2Agb24gb25lIGluc3RhbmNlIG5ldmVyIHJlYWNoZXNcbiAqIHRoZSBvdGhlcnM6IHRoZXkga2VlcCBzZXJ2aW5nIHRoZSByZXZhbGlkYXRlZCBlbnRyeSwgaW5jbHVkaW5nIGluc2lkZSBwYWdlc1xuICogdGhhdCBhcmUgYmVpbmcgcmUtcmVuZGVyZWQgKmJlY2F1c2UqIG9mIHRoYXQgcmV2YWxpZGF0aW9uLiBUaGVcbiAqIGBjYWNoZUhhbmRsZXJzYCBpbnRlcmZhY2UncyBhbnN3ZXIgaXMgYHJlZnJlc2hUYWdzYCwgXCJjYWxsZWQgYmVmb3JlIHN0YXJ0aW5nXG4gKiBhIG5ldyByZXF1ZXN0IOKApiB0byByZWZyZXNoIHRoZSBsb2NhbCB0YWdzIG1hbmlmZXN0XCIsIGFuZCB0aGlzIGlzIHRoYXRcbiAqIG1hbmlmZXN0LCBiYWNrZWQgYnkgdGhlIHNhbWUgbWFya2VyIHJvd3MgdGhlIGluY3JlbWVudGFsIGNhY2hlJ3NcbiAqIGByZXZhbGlkYXRlVGFnYCB3cml0ZXMgKGBwayA9IGJ1aWxkSWRgLCBgc2sgPSB0YWdgKS5cbiAqXG4gKiBUaGUgY29zdCBpcyBib3VuZGVkIHBlciBpbnN0YW5jZSwgbm90IHBlciByZXF1ZXN0OlxuICogLSB7QGxpbmsgZW5zdXJlfSByZWFkcyBhIHRhZydzIG1hcmtlciB0aGUgZmlyc3QgdGltZSBpdCBpcyBuZWVkZWQgYW5kIG5vdFxuICogICBhZ2FpbiB1bnRpbCBpdCBpcyBldmljdGVkLCBzbyBhIHRhZyBjb3N0cyBvbmUgcmVhZCBwZXIgaW5zdGFuY2UsIG5vdCBvbmVcbiAqICAgcGVyIHJlcXVlc3QuIEFuIGVudHJ5IGNyZWF0ZWQgc2luY2Uge0BsaW5rIGNvbXBsZXRlU2luY2V9IG5lZWRzIG5vIHJlYWRcbiAqICAgYXQgYWxsLlxuICogLSB7QGxpbmsgcmVmcmVzaH0sIGF0IG1vc3Qgb25jZSBwZXIgYHJlZnJlc2hJbnRlcnZhbE1zYCwgc2VuZHMgb25lIGBRdWVyeWBcbiAqICAgZm9yIHRoZSBsb2cgcm93cyB3cml0dGVuIHNpbmNlIHRoZSBsYXN0IG9uZSwgYW5kIGFwcGxpZXMgdGhvc2Ugb2YgdGFnc1xuICogICB0aGlzIGluc3RhbmNlIHRyYWNrcy4gQ29uY3VycmVudCBjYWxsZXJzIHNoYXJlIGl0LiBBbG9uZ3NpZGUsIGl0IHJlLXJlYWRzXG4gKiAgIHRoZSBtYXJrZXJzIG9mIHVwIHRvIHtAbGluayBCQVRDSF9HRVRfTUFYX0tFWVN9IHRhZ3Mgbm90IHJlYWQgZm9yXG4gKiAgIHtAbGluayBERUZBVUxUX1RBR19SRVNZTkNfTVN9LCBpbiBvbmUgYEJhdGNoR2V0SXRlbWAuXG4gKiBBIHJldmFsaWRhdGlvbiBvbiBhbm90aGVyIGluc3RhbmNlIGlzIHRoZXJlZm9yZSBzZWVuIHdpdGhpblxuICogYHJlZnJlc2hJbnRlcnZhbE1zYCAocGx1cyB0aGUgcXVlcnkgaXRzZWxmKSAtIGJ5IGAndXNlIGNhY2hlJ2AsIGZyb20gdGhlXG4gKiBmaXJzdCByZXF1ZXN0IGFmdGVyIHRoZSBxdWVyeSByZXR1cm5zLCBzaW5jZSBpdHMgYHJlZnJlc2hUYWdzYCBkb2VzIG5vdCB3YWl0XG4gKiBmb3IgaXQgKHNlZSBgdGFnTWV0aG9kc2ApIHVubGVzcyB0aGUgaW5zdGFuY2UgaXMge0BsaW5rIGJlaGluZH0sIHdoaWNoIHRoZVxuICogcnVudGltZSBzZXR0bGVzIGJlZm9yZSBhIHBhZ2UgcmVuZGVyIHN0YXJ0cyAoe0BsaW5rIGNhdGNoVXB9KS4gVGhlIGluc3RhbmNlXG4gKiB0aGF0IHJhbiBpdCBhcHBsaWVzIGl0IGl0c2VsZiwgYXQgb25jZSwgd2l0aCB7QGxpbmsgc2V0fS5cbiAqL1xuZXhwb3J0IGNsYXNzIFRyYWNrZWRUYWdNYXJrZXJzIHtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXJrZXJzOiBUYWdNYXJrZXJUYWJsZSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2c6IFJldmFsaWRhdGlvbkxvZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSByZWZyZXNoSW50ZXJ2YWxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heFRyYWNrZWRUYWdzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzeW5jSW50ZXJ2YWxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsb2NrOiAoKSA9PiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmFuZG9tOiAoKSA9PiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVidWc6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIC8qKiBCeSB0YWcsIGxlYXN0IHJlY2VudGx5IHVzZWQgZmlyc3QuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdGFncyA9IG5ldyBNYXA8c3RyaW5nLCBUYWdNYXJrZXI+KCk7XG4gIC8qKlxuICAgKiBXaGVuIGVhY2ggdHJhY2tlZCB0YWcncyBtYXJrZXIgaXMgZHVlIHRvIGJlIHJlYWQgYWdhaW46IGEgcmFuZG9tIDc1LTEwMCVcbiAgICogb2YgYHJlc3luY0ludGVydmFsTXNgIGFmdGVyIGl0IHdhcyBsYXN0IGtub3duIGZyb20gdGhlIHRhYmxlIC0gcmVhZCxcbiAgICogd3JpdHRlbiBoZXJlLCBvciBuZXcuIEluIHRoZSBvcmRlciB0aGV5IGJlY2FtZSBrbm93biwgbGVhc3QgcmVjZW50IGZpcnN0LlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBkdWVBdCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVhZGluZyA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPHZvaWQ+PigpO1xuICAvKipcbiAgICogTG9nIHJvd3MgZm9yIHRhZ3Mgd2hvc2UgZmlyc3QgcmVhZCBpcyBpbiBmbGlnaHQsIG1lcmdlZCBieSB0YWc6IHRoZSByZWFkXG4gICAqIG1heSBoYXZlIGJlZW4gYW5zd2VyZWQgYmVmb3JlIHRoZSByZXZhbGlkYXRpb24sIHNvIHRoZXkgYXJlIGFwcGxpZWQgdG8gaXRzXG4gICAqIHJlc3VsdCByYXRoZXIgdGhhbiBkcm9wcGVkLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUm93cyA9IG5ldyBNYXA8c3RyaW5nLCBUYWdNYXJrZXI+KCk7XG4gIC8qKlxuICAgKiBMb2cgcm93cyBmb3IgdGFncyBub3QgdHJhY2tlZCBhbmQgbm90IGJlaW5nIHJlYWQsIG1lcmdlZCBieSB0YWcsIG9sZGVzdFxuICAgKiBmaXJzdDogd2hhdCB0aGUgbG9nIGhhcyBzYWlkIGFib3V0IHRoZW0gc2luY2Uge0BsaW5rIGNvbXBsZXRlU2luY2V9LiBUYWtlblxuICAgKiBpbnRvIGEgdGFnJ3MgbWFya2VyIHdoZW4gaXQgaXMgcmVhZCBvciB3cml0dGVuLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBsb2dPbmx5ID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcbiAgLyoqIFNlZSB7QGxpbmsgY29tcGxldGVTaW5jZX0uICovXG4gIHByaXZhdGUgZmxvb3I6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBmdXR1cmUgYGV4cGlyZWRBdGBzIG9mIG1hcmtlcnMgZHJvcHBlZCBzaW5jZSwgYXMgYFtmcm9tLCB0b11gLCBpblxuICAgKiBvcmRlcjogb25jZSBgZnJvbWAgaXMgcGFzdCwge0BsaW5rIGNvbXBsZXRlU2luY2V9IG1vdmVzIHRvIGB0b2AsIGFuZCBub3RcbiAgICogYmVmb3JlLCBzaW5jZSBvbmx5IHRoZW4gZG9lcyBpdCBleHBpcmUgYW55dGhpbmcuIGBmcm9tYCBhbmQgYHRvYCBhcmUgdGhlXG4gICAqIHNhbWUgdW50aWwgc3BhbnMgYXJlIG1lcmdlZCBmb3Igc3BhY2UgKHtAbGluayBsYXRlckZsb29yfSkuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGxhdGVyRmxvb3JzOiBbbnVtYmVyLCBudW1iZXJdW10gPSBbXTtcbiAgLyoqIFRoZSBpbi1tZW1vcnkgZW50cnkgc3RvcmVzIGp1ZGdlZCBieSB7QGxpbmsgY29tcGxldGVTaW5jZX0uICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZW50cnlTdG9yZXM6IHtcbiAgICBvbGRlc3RUaW1lc3RhbXA6IChzY2FuOiBib29sZWFuKSA9PiBudW1iZXI7XG4gICAgaG9sZHNBbnk6ICgpID0+IGJvb2xlYW47XG4gIH1bXSA9IFtdO1xuICAvKiogSG93IG1hbnkgdGltZXMge0BsaW5rIGZvcmdldH0gcmFuOiBhIHJlYWQgc3RhcnRlZCBiZWZvcmUgb25lIGlzIG1hZGUgYWdhaW4uICovXG4gIHByaXZhdGUgZm9yZ290dGVuID0gMDtcbiAgLyoqIFRyYWNrZWQgdGFncyB3aG9zZSByZWFkIGZhaWxlZCwgZm9yIHRoZSBuZXh0IHJlZnJlc2ggdG8gcmVhZCBhZ2Fpbi4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB1bnJlYWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgLyoqXG4gICAqIFNldCBpbnNpZGUgYSBwYWdlIHJlbmRlciB7QGxpbmsgY2F0Y2hVcH0gbGV0IGdvLCBmb3IgdGhhdCByZW5kZXIgYWxvbmUuXG4gICAqIFNlZSB7QGxpbmsgYmVoaW5kSW5SZW5kZXJ9LlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjYXVnaHRVcFJlbmRlciA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZTx0cnVlPigpO1xuICAvKiogV2hlbiBgc3luY2AgbGFzdCBzY2FubmVkIHRoZSBlbnRyeSBzdG9yZXMgKHtAbGluayBvbGRlc3RFbnRyeX0pLiAqL1xuICBwcml2YXRlIGxhc3RFbnRyeVNjYW4gPSAtSW5maW5pdHk7XG4gIC8qKlxuICAgKiBObyBgbG9nT25seWAgcm93IGlzIGtub3duIGJ5IGl0IG9yIGVhcmxpZXIsIHNvIGEge0BsaW5rIHBydW5lTG9nZ2VkfVxuICAgKiBhZ2FpbnN0IGl0IG9yIGVhcmxpZXIgZHJvcHMgbm90aGluZzogYSBtYXJrZXIgaXMgb25seSBldmVyIGtub3duIGJ5IGxhdGVyLFxuICAgKiBhcyBpdHMgYGV4cGlyZWRBdGAgcGFzc2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBwcnVuZWRBZ2FpbnN0ID0gLUluZmluaXR5O1xuICAvKiogV2hlbiB0aGUgbGFzdCByZWZyZXNoIHN0YXJ0ZWQsIG9yIHdhcyBza2lwcGVkLiAqL1xuICBwcml2YXRlIGxhc3RSZWZyZXNoID0gLUluZmluaXR5O1xuICAvKipcbiAgICogVGhlIHJlZnJlc2ggaW4gZmxpZ2h0LiBPbmUgbGVmdCBvcGVuIGFjcm9zcyBhIGZyZWV6ZSBjb21lcyBiYWNrIGFmdGVyIHRoZVxuICAgKiB0aGF3IHdpdGggd2hhdCBpdCByZWFkIGJlZm9yZSwgc28ge0BsaW5rIHJlZnJlc2h9IHdhaXRzIGZvciBpdCBhbmQgdGhlblxuICAgKiBmb3IgYSBmcmVzaCBvbmUsIHJhdGhlciB0aGFuIHRoZSBydW50aW1lIHdhaXRpbmcgZm9yIGl0IGJlZm9yZSB0aGUgZnJlZXplOlxuICAgKiB0aGF0IHdvdWxkIGJpbGwgZXZlcnkgTGFtYmRhIGludm9jYXRpb24gZm9yIHRoZSBxdWVyeSdzIHRhaWwuXG4gICAqL1xuICBwcml2YXRlIHJlZnJlc2hpbmc6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBXaGVuIHtAbGluayByZWZyZXNoaW5nfSBsYXN0IHNob3dlZCB0aGUgcHJvY2VzcyBydW5uaW5nOiBhIHRpbWVyIHRpY2tzXG4gICAqIHdoaWxlIGl0IGlzIGluIGZsaWdodCwgYW5kIGEgdGljayB0aGF0IGNvbWVzIGxhdGUsIG9yIG5vbmUgYXQgYWxsLCBtZWFuc1xuICAgKiB0aGUgcHJvY2VzcyB3YXMgcGF1c2VkIC0gZnJvemVuIC0gc2luY2UgaXQgc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgbGFzdFRpY2sgPSAtSW5maW5pdHk7XG4gIC8qKiBXaGV0aGVyIGEgdGljayBjYW1lIGxhdGUgc2luY2Uge0BsaW5rIHJlZnJlc2hpbmd9IHN0YXJ0ZWQuICovXG4gIHByaXZhdGUgcGF1c2VkV2hpbGVSZWZyZXNoaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgdGlja2VyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2FuRnJlZXplOiBib29sZWFuO1xuICAvKipcbiAgICogV2hlbiB0aGUgbGFzdCByZWZyZXNoIHNldHRsZWQsIGVpdGhlciB3YXksIHVubGVzcyBpdCBzcGFubmVkIGEgcGF1c2U6IHdoYXRcbiAgICogaXQga25vd3MgaXMgZnJvbSB0aGVuLiBTZWUge0BsaW5rIGJlaGluZH0uXG4gICAqL1xuICBwcml2YXRlIHNldHRsZWRBdDogbnVtYmVyO1xuICAvKipcbiAgICogV2hlcmUgdGhlIG5leHQgbG9nIHF1ZXJ5IHN0YXJ0cyAoYGNsb2NrKClgKTogdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBvbmUnc1xuICAgKiBzdGFydCwgbGVzcyB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NU30uXG4gICAqL1xuICBwcml2YXRlIGN1cnNvcjogbnVtYmVyO1xuICAvKiogV2hlbiB0aGUgbGFzdCBzdWNjZXNzZnVsIGxvZyBxdWVyeSBzdGFydGVkLCBvciB0aGUgbG9nIHdhcyBmaXJzdCByZWFkLiAqL1xuICBwcml2YXRlIGxhc3RMb2dSZWFkOiBudW1iZXI7XG4gIC8qKiBMb2cgcm93cyBhdCBvciBhZnRlciB0aGUgY3Vyc29yIGFscmVhZHkgYXBwbGllZCwgYnkgc29ydCBrZXkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwbGllZCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiB7QGxpbmsgdXBkYXRlfXMgb2YgdGhlIGN1cnJlbnQgdHVybiwgYnkgdGhlaXIgYXJndW1lbnRzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHVwZGF0aW5nID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8Ym9vbGVhbj4+KCk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogVHJhY2tlZFRhZ01hcmtlcnNPcHRpb25zKSB7XG4gICAgdGhpcy5tYXJrZXJzID0gb3B0aW9ucy5tYXJrZXJzO1xuICAgIHRoaXMubG9nID0gb3B0aW9ucy5sb2c7XG4gICAgdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcyA9XG4gICAgICBvcHRpb25zLnJlZnJlc2hJbnRlcnZhbE1zID8/IERFRkFVTFRfVEFHX1JFRlJFU0hfTVM7XG4gICAgdGhpcy5tYXhUcmFja2VkVGFncyA9IG9wdGlvbnMubWF4VHJhY2tlZFRhZ3MgPz8gREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTO1xuICAgIHRoaXMucmVzeW5jSW50ZXJ2YWxNcyA9IG9wdGlvbnMucmVzeW5jSW50ZXJ2YWxNcyA/PyBERUZBVUxUX1RBR19SRVNZTkNfTVM7XG4gICAgLy8gTG9va2VkIHVwIG9uIGVhY2ggY2FsbCByYXRoZXIgdGhhbiBib3VuZCBoZXJlLCBzbyBhIHRlc3QncyBgRGF0ZS5ub3dgXG4gICAgLy8gc3B5IGFwcGxpZXMuXG4gICAgdGhpcy5jbG9jayA9IG9wdGlvbnMuY2xvY2sgPz8gKCgpID0+IERhdGUubm93KCkpO1xuICAgIHRoaXMucmFuZG9tID0gb3B0aW9ucy5yYW5kb20gPz8gTWF0aC5yYW5kb207XG4gICAgdGhpcy5kZWJ1ZyA9IG9wdGlvbnMuZGVidWcgPz8gKCgpID0+IHt9KTtcbiAgICB0aGlzLmNhbkZyZWV6ZSA9IG9wdGlvbnMuY2FuRnJlZXplID8/IGZhbHNlO1xuICAgIC8vIE5vdGhpbmcgaXMgdHJhY2tlZCB5ZXQsIHNvIG5vdGhpbmcgYmVmb3JlIHRoaXMgY2FuIGJlIG1pc3NlZDogZXZlcnkgdGFnXG4gICAgLy8gaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIgdGhlIGZpcnN0IHRpbWUgaXQgaXMgbmVlZGVkLlxuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIHRoaXMuY3Vyc29yID0gYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TO1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgICB0aGlzLnNldHRsZWRBdCA9IGF0O1xuICAgIHRoaXMuZmxvb3IgPSBtYXJrZXJDbG9jaygpO1xuICB9XG5cbiAgLyoqIGB0YWdgJ3MgbWFya2VyIGFzIHRoaXMgaW5zdGFuY2Uga25vd3MgaXQsIGlmIGl0IHRyYWNrcyBgdGFnYC4gKi9cbiAgZ2V0KHRhZzogc3RyaW5nKTogVGFnTWFya2VyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy50YWdzLmdldCh0YWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNpbmNlIHdoZW4gKGBtYXJrZXJDbG9jaygpYCkgdGhpcyBpbnN0YW5jZSBrbm93cyBvZiBldmVyeSByZXZhbGlkYXRpb24gb2ZcbiAgICogZXZlcnkgdGFnLCB0cmFja2VkIG9yIG5vdDogdHJhY2tlZCBvbmVzIGZyb20gdGhlaXIgbWFya2VycyBhbmQgdGhlIGxvZyxcbiAgICogdGhlIG90aGVycyBmcm9tIHRoZSBsb2cgYWxvbmUgKGBsb2dPbmx5YCkuIFNvIGFuIGVudHJ5IGNyZWF0ZWQgYXQgb3IgYWZ0ZXJcbiAgICogaXQgY2FuIGJlIGp1ZGdlZCBieSB7QGxpbmsgc3RhdGV9IGFuZCB7QGxpbmsgZXhwaXJhdGlvbn0gd2l0aG91dFxuICAgKiB7QGxpbmsgZW5zdXJlfSByZWFkaW5nIGFueXRoaW5nIC0gd2hpY2ggbWF0dGVycyBpbnNpZGUgYSBgJ3VzZSBjYWNoZSdgXG4gICAqIGxvb2t1cCwgd2hlcmUgTmV4dC5qcyB3YWl0cyBmb3IgdGhlIGFuc3dlciBhbmQgYSByZWFkIHB1c2hlcyB0aGUgZW50cnkgb3V0XG4gICAqIG9mIHRoZSBzdGF0aWMgc3RhZ2Ugb2YgYSBzdGFnZWQgcmVuZGVyLlxuICAgKlxuICAgKiBTdGFydHMgYXQgY29uc3RydWN0aW9uOiB0aGUgbG9nIGlzIGZvbGxvd2VkIGZyb20gYmVmb3JlIGl0LiBNb3ZlcyB0byBub3dcbiAgICogd2hlbiB0aGUgdHJhY2tlZCBtYXJrZXJzIGFyZSBmb3Jnb3R0ZW4sIGFuZCBwYXN0IHRoZSByZXZhbGlkYXRpb25zIG9mXG4gICAqIHdoYXRldmVyIGVsc2UgaXQgbGV0cyBnbyBvZiAtIGEgbWFya2VyIGV2aWN0ZWQgZm9yIHNwYWNlLCBhIGxvZyByb3dcbiAgICogcHJ1bmVkIC0gd2hpY2ggYXJlIG5vIGxvbmdlciBrbm93bjogdG8gaXRzIGBleHBpcmVkQXRgIG9ubHkgb25jZSB0aGF0IGlzXG4gICAqIHBhc3QsIHNpbmNlIGEgcHJvZmlsZSdzIGBleHBpcmVgIGNhbiBiZSBhIHllYXIgb3V0LCBhbmQgbW92aW5nIHRoZXJlIGF0XG4gICAqIG9uY2Ugd291bGQgdHVybiB0aGUgcmVhZC1mcmVlIHBhdGggb2ZmIGZvciB0aGUgaW5zdGFuY2UncyBsaWZlLlxuICAgKlxuICAgKiBBIHJvdyBpcyBwcnVuZWQgb25seSBvbmNlIGl0IGlzIG5vIGxhdGVyIHRoYW4gZXZlcnkgZW50cnkgaGVsZCwgc28gdGhhdFxuICAgKiBjb3N0cyB0aG9zZSBlbnRyaWVzIG5vdGhpbmcuIEFuIGVudHJ5IHN0b3JlZCBhZnRlcndhcmRzIHdpdGggYW4gb2xkZXJcbiAgICogYHRpbWVzdGFtcGAgLSBOZXh0LmpzIHN0YW1wcyB0aGUgc3RhcnQgb2YgaXRzIGdlbmVyYXRpb24sIHdoaWNoIGNhblxuICAgKiBvdXRsYXN0IGEgbG9va2JhY2sgLSBpcyBvbGRlciB0aGFuIHRoaXMgdG9vLCBhbmQgaXMgcmVhZCBmaXJzdC5cbiAgICpcbiAgICogSXQgZG9lcyBub3QgY292ZXIgYSByZXZhbGlkYXRpb24gb2xkZXIgdGhhbiB0aGUgbG9nJ3MgZmlyc3QgbG9va2JhY2tcbiAgICogd2hvc2UgYGV4cGlyZWRBdGAgaXMgc3RpbGwgdG8gY29tZSwgd2hpY2ggd291bGQgZXhwaXJlIGFuIGVudHJ5IGNyZWF0ZWRcbiAgICogYWZ0ZXIgaXQuIFNvIHRoZSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIgcmVhZHMgYW4gZW50cnkncyB0YWdzIGluIHRoZVxuICAgKiBiYWNrZ3JvdW5kIGFzIGl0IHN0b3JlcyBpdC5cbiAgICovXG4gIGdldCBjb21wbGV0ZVNpbmNlKCk6IG51bWJlciB7XG4gICAgY29uc3QgYXQgPSBtYXJrZXJDbG9jaygpO1xuICAgIHdoaWxlICh0aGlzLmxhdGVyRmxvb3JzLmxlbmd0aCA+IDAgJiYgdGhpcy5sYXRlckZsb29yc1swXVswXSA8PSBhdCkge1xuICAgICAgdGhpcy5mbG9vciA9IE1hdGgubWF4KHRoaXMuZmxvb3IsIHRoaXMubGF0ZXJGbG9vcnMuc2hpZnQoKSFbMV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5mbG9vcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhbiBpbi1tZW1vcnkgc3RvcmUgd2hvc2UgZW50cmllcyBhcmUganVkZ2VkIGJ5XG4gICAqIHtAbGluayBjb21wbGV0ZVNpbmNlfSwgYnkgdGhlIGB0aW1lc3RhbXBgIG9mIHRoZSBvbGRlc3QgZW50cnkgaXQgaG9sZHM6XG4gICAqIGBsb2dPbmx5YCBrZWVwcyB0aGUgcm93cyB0aGF0IGNvdWxkIHN0aWxsIGFwcGx5IHRvIG9uZSBvZiB0aGVtLCBhbmQgbm9cbiAgICogb3RoZXJzLiBXaXRoIG5vbmUgcmVnaXN0ZXJlZCBpdCBrZWVwcyBub3RoaW5nLiBBc2tlZCB3aXRoIGBzY2FuYCBmYWxzZSxcbiAgICogYG9sZGVzdFRpbWVzdGFtcGAgbWF5IGFuc3dlciBlYXJseSwgYnV0IG5ldmVyIGxhdGUsIHdpdGhvdXQgYSBzY2FuLlxuICAgKi9cbiAganVkZ2VFbnRyaWVzT2YoXG4gICAgb2xkZXN0VGltZXN0YW1wOiAoc2NhbjogYm9vbGVhbikgPT4gbnVtYmVyLFxuICAgIGhvbGRzQW55OiAoKSA9PiBib29sZWFuID0gKCkgPT4gb2xkZXN0VGltZXN0YW1wKGZhbHNlKSA8IEluZmluaXR5LFxuICApOiB2b2lkIHtcbiAgICB0aGlzLmVudHJ5U3RvcmVzLnB1c2goeyBvbGRlc3RUaW1lc3RhbXAsIGhvbGRzQW55IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGB0YWdgIHdpdGggYG1hcmtlcmA6IHdoYXQgdGhpcyBpbnN0YW5jZSBqdXN0IHdyb3RlLCB3aGljaCBpdCBrbm93c1xuICAgKiB3aXRob3V0IHJlYWRpbmcgaXQgYmFjay5cbiAgICovXG4gIHNldCh0YWc6IHN0cmluZywgbWFya2VyOiBUYWdNYXJrZXIpOiB2b2lkIHtcbiAgICBjb25zdCBsb2dnZWQgPSB0aGlzLmxvZ09ubHkuZ2V0KHRhZyk7XG4gICAgdGhpcy5sb2dPbmx5LmRlbGV0ZSh0YWcpO1xuICAgIHRoaXMucmVtZW1iZXIodGFnLCBtZXJnZU1hcmtlcnMobWFya2VyLCBsb2dnZWQpKTtcbiAgICB0aGlzLmtub3duKHRhZywgdGhpcy5jbG9jaygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RlIGEgdXNlIG9mIGB0YWdzYDogdGhvc2Ugb2YgYW4gZW50cnkgdGhpcyBpbnN0YW5jZSBqdXN0IHN0b3JlZC5cbiAgICpcbiAgICogV2l0aCB0aGUgdGFibGUsIGEgdGFnIG5vdCB0cmFja2VkIHlldCBpcyBsZWZ0IHVudHJhY2tlZCwgdG8gYmUgcmVhZCBieVxuICAgKiB7QGxpbmsgZW5zdXJlfSB0aGUgZmlyc3QgdGltZSBhbiBlbnRyeSBuZWVkcyBpdC4gTm90aGluZyByZXZhbGlkYXRlZCBiZWZvcmVcbiAgICogdGhlIG5ldyBlbnRyeSB3YXMgY3JlYXRlZCBhcHBsaWVzIHRvICppdCosIGJ1dCB0cmFja2luZyBpcyBwZXIgdGFnLCBub3QgcGVyXG4gICAqIGVudHJ5OiB0cmFja2luZyB0aGUgdGFnIHdpdGggYW4gZW1wdHkgbWFya2VyIHdvdWxkIGFsc28gdm91Y2ggZm9yIGV2ZXJ5XG4gICAqIG9sZGVyIGVudHJ5IHRoYXQgY2FycmllcyBpdCAtIG9uZSBhbm90aGVyIGluc3RhbmNlIHN0b3JlZCBpbiBTMywgb3Igb25lXG4gICAqIHRoaXMgaW5zdGFuY2Uga2VwdCBpbiBtZW1vcnkgYWNyb3NzIGEge0BsaW5rIGZvcmdldH0gLSBhbmQgYSByZXZhbGlkYXRpb25cbiAgICogZnJvbSBiZWZvcmUgdGhlIGxvZydzIGN1cnNvciB3b3VsZCBnbyB1bnNlZW4gdW50aWwgdGhlIHJvbGxpbmcgcmUtcmVhZC5cbiAgICpcbiAgICogV2l0aG91dCB0aGUgdGFibGUgZXZlcnkgcmV2YWxpZGF0aW9uIGlzIHRoaXMgcHJvY2VzcydzIG93biwgYXBwbGllZCB3aXRoXG4gICAqIHtAbGluayBzZXR9LCBzbyBhIHRhZyBpcyB0cmFja2VkIGF0IG9uY2UuXG4gICAqL1xuICB0cmFjayh0YWdzOiByZWFkb25seSBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tYXJrZXJzKSB7XG4gICAgICB0aGlzLnRyYWNrVW5yZWFkKHRhZ3MpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICB0aGlzLnRvdWNoKHRhZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGB0YWdzYCBhcyB0aGV5IGFyZSBrbm93biBub3csIHdpdGhvdXQgcmVhZGluZyB0aGVtLCB3aXRoIGFuIGVtcHR5XG4gICAqIG1hcmtlciBmb3IgYW55IG5vdCB0cmFja2VkIHlldC5cbiAgICovXG4gIHByaXZhdGUgdHJhY2tVbnJlYWQodGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiB2b2lkIHtcbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBpZiAoIXRoaXMudGFncy5oYXModGFnKSkge1xuICAgICAgICB0aGlzLmtub3duKHRhZywgYXQpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZW1lbWJlcih0YWcsIHRoaXMudGFncy5nZXQodGFnKSA/PyB7fSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgdGhlIG1hcmtlcnMgb2Ygd2hpY2hldmVyIG9mIGB0YWdzYCB0aGlzIGluc3RhbmNlIGRvZXMgbm90IHRyYWNrIHlldC5cbiAgICogTmVlZGVkIGJlZm9yZSBqdWRnaW5nIGFuIGVudHJ5IHRoaXMgaW5zdGFuY2UgZGlkIG5vdCBjcmVhdGUsIHNpbmNlIGl0c1xuICAgKiB0YWdzIG1heSBoYXZlIGJlZW4gcmV2YWxpZGF0ZWQgYXQgYW55IHRpbWUgYmVmb3JlLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLm1hcmtlcnMpIHtcbiAgICAgIHRoaXMudHJhY2tVbnJlYWQodGFncyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHdhaXRzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcbiAgICBjb25zdCB1bnJlYWQ6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgbmV3IFNldCh0YWdzKSkge1xuICAgICAgLy8gVHJhY2tlZCBmaXJzdDogYSB0cmFja2VkIHRhZyBpbiBgcmVhZGluZ2AgaXMgb25seSBiZWluZyByZS1yZWFkIGluXG4gICAgICAvLyB0aGUgYmFja2dyb3VuZCAoYHN5bmNgKSwgd2hpY2ggbm90aGluZyBuZWVkcyB0byB3YWl0IGZvci5cbiAgICAgIGNvbnN0IGluRmxpZ2h0ID0gdGhpcy5yZWFkaW5nLmdldCh0YWcpO1xuICAgICAgaWYgKHRoaXMudGFncy5oYXModGFnKSkge1xuICAgICAgICB0aGlzLnRvdWNoKHRhZyk7XG4gICAgICB9IGVsc2UgaWYgKGluRmxpZ2h0KSB7XG4gICAgICAgIHdhaXRzLnB1c2goaW5GbGlnaHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdW5yZWFkLnB1c2godGFnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHVucmVhZC5sZW5ndGggPiAwKSB7XG4gICAgICB3YWl0cy5wdXNoKHRoaXMuc3RhcnRSZWFkKHVucmVhZCkpO1xuICAgIH1cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh3YWl0cyk7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIHJlYWRJbnRvfSBgdGFnc2AsIGFzIHRoZSByZWFkIG9mIGVhY2ggdGhhdCB3aG9ldmVyIG5lZWRzIG9uZSBvZlxuICAgKiB0aGVtIG5leHQgd2FpdHMgb24gKHtAbGluayByZWFkaW5nfSkuIE5ldmVyIHJlamVjdHM6IGEgZmFpbGVkIHJlYWQgbGVhdmVzXG4gICAqIHRoZSB0YWdzIHRyYWNrZWQuXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0UmVhZCh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlYWQgPSB0aGlzLnJlYWRJbnRvKHRhZ3MpLnRoZW4oKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnJlYWRpbmcuZGVsZXRlKHRhZyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy5yZWFkaW5nLnNldCh0YWcsIHJlYWQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVhZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBsYXN0IHJlZnJlc2ggc2V0dGxlZCBtb3JlIHRoYW4gYHJlZnJlc2hJbnRlcnZhbE1zYCBwbHVzXG4gICAqIHtAbGluayBUQUdfUkVGUkVTSF9HUkFDRV9NU30gYWdvIC0gb25lIHRoYXQgc3Bhbm5lZCBhIGZyZWV6ZSBjb3VudHMgZnJvbVxuICAgKiB3aGVuIGl0IHN0YXJ0ZWQ6IGFmdGVyIHRoZSBpbnN0YW5jZSBzYXQgaWRsZSBvciBmcm96ZW4gLSBvciBhbHdheXMsIHdpdGhcbiAgICogYSBgcmVmcmVzaEludGVydmFsTXNgIG9mIGAwYC4gQW5zd2VyaW5nIGZyb20gd2hhdCBpdCBrbm93cyB0aGVuIGNvdWxkXG4gICAqIHNlcnZlIGFuIGVudHJ5IHJldmFsaWRhdGVkIGVsc2V3aGVyZSBzaW5jZSwgaG93ZXZlciBsb25nIGFnbyB0aGF0IHdhcywgc29cbiAgICogYHJlZnJlc2hUYWdzYCB3YWl0cyBmb3IgdGhlIHJlZnJlc2gsIGFuZCB0aGUgcnVudGltZSB3YWl0cyBmb3IgaXQgYmVmb3JlXG4gICAqIGEgcGFnZSByZW5kZXIgc3RhcnRzICh7QGxpbmsgY2F0Y2hVcH0pLlxuICAgKlxuICAgKiBGcm9tIHdoZW4gaXQgc2V0dGxlZCwgbm90IHdoZW4gaXQgc3RhcnRlZCwgc28gYSBzbG93IHF1ZXJ5IHRoZSBydW50aW1lXG4gICAqIHdhaXRlZCBmb3IgYmVmb3JlIHRoZSByZW5kZXIgZG9lcyBub3QgbGVhdmUgdGhlIGluc3RhbmNlIGJlaGluZCBpbnNpZGVcbiAgICogaXQuIEEgZmFpbGVkIG9uZSBjb3VudHMgdG9vLCBzbyBvbmUgcmVxdWVzdCBkb2VzIG5vdCB3YWl0IGZvciB0d286IHRoZVxuICAgKiBzYW1lIFwiYXNzdW1lIHRoZSBlbnRyeSBpcyB2YWxpZFwiIGEgZmFpbGVkIHJlYWQgYW5zd2VycyB3aXRoLCB1bnRpbCB0aGVcbiAgICogbmV4dCByZWZyZXNoLCBhdCBtb3N0IHRoZSBpbnRlcnZhbCBhbmQgdGhlIGdyYWNlIGxhdGVyLlxuICAgKi9cbiAgZ2V0IGJlaGluZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5sb2cgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgLy8gYDBgIGFza3MgYmVmb3JlIGV2ZXJ5IGNoZWNrLCBzbyBldmVyeSBjaGVjayB3YWl0cyBmb3IgdGhlIGFuc3dlci5cbiAgICAgICh0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID09PSAwIHx8IHRoaXMub3ZlcmR1ZSh0aGlzLnNldHRsZWRBdCkpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgYmVoaW5kfSwgYXMgYHJlZnJlc2hUYWdzYCBhc2tzIGl0OiBuZXZlciBpbnNpZGUgYSBwYWdlJ3MgcmVuZGVyXG4gICAqIHtAbGluayBjYXRjaFVwfSBjYXVnaHQgdXAsIHNpbmNlIHRoZSBydW50aW1lIHNldHRsZWQgaXQgZm9yIHRoYXQgcmVxdWVzdFxuICAgKiBiZWZvcmUgdGhlIHJlbmRlciBzdGFydGVkLCBhbmQgYSB3YWl0IGluc2lkZSBhIGAndXNlIGNhY2hlJ2AgbG9va3VwIGlzXG4gICAqIHdoYXQgaXQgc2V0dGxlZCBpdCB0byBhdm9pZCAtIGEgcmVuZGVyIGNyb3NzaW5nIHRoZSBsaW5lIHBhcnR3YXkgdGhyb3VnaFxuICAgKiB3b3VsZCBvdGhlcndpc2Ugd2FpdCBhZnRlciBhbGwuIFNvIGEgcmV2YWxpZGF0aW9uIGVsc2V3aGVyZSBjYW4gZ28gdW5zZWVuXG4gICAqIGZvciBhIHJlbmRlcidzIGR1cmF0aW9uIG9uIHRvcCBvZiB0aGUgdXN1YWwgd2luZG93LlxuICAgKlxuICAgKiBBIHJvdXRlIGhhbmRsZXIsIHdoaWNoIG5vIGNhdGNoLXVwIHByZWNlZGVzLCB3YWl0cyBhdCB0aGUgcGxhaW4gbGluZS5cbiAgICovXG4gIGdldCBiZWhpbmRJblJlbmRlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcyAhPT0gMCAmJiB0aGlzLmNhdWdodFVwUmVuZGVyLmdldFN0b3JlKClcbiAgICAgID8gZmFsc2VcbiAgICAgIDogdGhpcy5iZWhpbmQ7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciBhIHJlZ2lzdGVyZWQgc3RvcmUgKHtAbGluayBqdWRnZUVudHJpZXNPZn0pIGhvbGRzIGFueSBlbnRyeTogb25lXG4gICAqIGEgcmVmcmVzaCBjb3VsZCBleHBpcmUuIFdpdGggbm9uZSB0aGVyZSBpcyBub3RoaW5nIHRvIHdhaXQgZm9yIGV2ZW4gd2hlblxuICAgKiB0aGUgaW5zdGFuY2UgaXMge0BsaW5rIGJlaGluZH0sIHNpbmNlIHdoYXRldmVyIGlzIHN0b3JlZCBmcm9tIGhlcmUgb24gaXNcbiAgICogbmV3ZXIgdGhhbiB3aGF0IHRoZSBsb2cgd291bGQgc2F5IC0gd2hpY2ggY292ZXJzIHRoZSBmaXJzdCBgJ3VzZSBjYWNoZSdgXG4gICAqIGNhbGwgb2YgYSBwcm9jZXNzLCB3aGljaCBjcmVhdGVzIHRoZSBoYW5kbGVyIGluc2lkZSB0aGUgcmVuZGVyLlxuICAgKi9cbiAgZ2V0IGhvbGRzRW50cmllcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lbnRyeVN0b3Jlcy5zb21lKChzdG9yZSkgPT4gc3RvcmUuaG9sZHNBbnkoKSk7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIHJlZnJlc2h9LCB3YWl0ZWQgZm9yIHdoZW4gdGhlIGluc3RhbmNlIGlzIHtAbGluayBiZWhpbmR9LiBUaGVcbiAgICogcnVudGltZSBjYWxscyBpdCBiZWZvcmUgaGFuZGluZyBhIHBhZ2UgcmVxdWVzdCB0byBOZXh0LmpzLCBvdXRzaWRlIHRoZVxuICAgKiBzdGFnZWQgcmVuZGVyIHdob3NlIHN0YXRpYyBzdGFnZSBhIHdhaXQgaW5zaWRlIGEgYCd1c2UgY2FjaGUnYCBsb29rdXBcbiAgICogd291bGQgY3V0IHNob3J0LiBPbmx5IGZvciB0aGUgYCd1c2UgY2FjaGUnYCBoYW5kbGVyJ3MgZW50cmllc1xuICAgKiAoe0BsaW5rIGp1ZGdlRW50cmllc09mfSk6IHRoZSBvdGhlciBjYWNoZXMgd2FpdCBmb3IgdGhlIHJlZnJlc2ggd2hlcmUgdGhleVxuICAgKiByZWFkIGFueXdheS4gTm90IHdpdGggYSBgcmVmcmVzaEludGVydmFsTXNgIG9mIGAwYCBlaXRoZXIsIHdoZXJlXG4gICAqIGByZWZyZXNoVGFnc2AgYXNrcyBhZ2FpbiByZWdhcmRsZXNzLiBUaGVuIGByZW5kZXJgLCBtYXJrZWQgYXMgY2F1Z2h0IHVwXG4gICAqIGZvciAoe0BsaW5rIGJlaGluZEluUmVuZGVyfSkuIFJlamVjdHMgb25seSBhcyBgcmVuZGVyYCBkb2VzLlxuICAgKi9cbiAgYXN5bmMgY2F0Y2hVcDxUPihyZW5kZXI6ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBsb2cgPSAoZXJyb3I6IHVua25vd24pID0+XG4gICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgcmVmcmVzaGluZyBjYWNoZSB0YWdzOlwiLCBlcnJvcik7XG4gICAgaWYgKHRoaXMucmVmcmVzaEludGVydmFsTXMgPiAwICYmIHRoaXMuYmVoaW5kKSB7XG4gICAgICBpZiAoIXRoaXMuaG9sZHNFbnRyaWVzKSB7XG4gICAgICAgIC8vIE5vdCBjYXVnaHQgdXAsIHNvIG5vIGdyYWNlOiBhbiBlbnRyeSBzdG9yZWQgbWVhbndoaWxlLCBieSBhbm90aGVyXG4gICAgICAgIC8vIHJlcXVlc3QsIG1ha2VzIHRoZSByZW5kZXIncyBsb29rdXBzIHdhaXQgYXQgdGhlIHBsYWluIGxpbmUuXG4gICAgICAgIHJldHVybiByZW5kZXIoKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMucmVmcmVzaCgpLmNhdGNoKGxvZyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID4gMCkge1xuICAgICAgLy8gU3RhcnRlZCwgbm90IHdhaXRlZCBmb3IsIGFzIGByZWZyZXNoVGFnc2Agd291bGQ6IGEgcGFnZSB0aGF0IHJlYWRzXG4gICAgICAvLyBubyBjYWNoZSBrZWVwcyB0aGUgaW5zdGFuY2UgY3VycmVudCB0b28sIHJhdGhlciB0aGFuIGZhbGxpbmcgYmVoaW5kXG4gICAgICAvLyBhbmQgbWFraW5nIGEgbGF0ZXIgcmVxdWVzdCB3YWl0LlxuICAgICAgdm9pZCB0aGlzLnJlZnJlc2goKS5jYXRjaChsb2cpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYXVnaHRVcFJlbmRlci5ydW4odHJ1ZSwgcmVuZGVyKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGBhdGAgaXMgbW9yZSB0aGFuIHRoZSBpbnRlcnZhbCBhbmQgdGhlIGdyYWNlIGFnby4gKi9cbiAgcHJpdmF0ZSBvdmVyZHVlKGF0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jbG9jaygpIC0gYXQgPiB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zICsgVEFHX1JFRlJFU0hfR1JBQ0VfTVM7XG4gIH1cblxuICAvKipcbiAgICogQ2F0Y2ggdXAgb24gcmV2YWxpZGF0aW9ucyBvdGhlciBpbnN0YW5jZXMgcmFuLCBhdCBtb3N0IG9uY2UgcGVyXG4gICAqIGByZWZyZXNoSW50ZXJ2YWxNc2AuIFNlZSB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9IGZvciB0aGUgY29zdC5cbiAgICovXG4gIGFzeW5jIHJlZnJlc2goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2c7XG4gICAgaWYgKCFsb2cpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMucmVmcmVzaGluZykge1xuICAgICAgLy8gT25lIHN0YXJ0ZWQgYmVmb3JlIGEgZnJlZXplIHJlYWQgdGhlIGxvZyBhcyBpdCB3YXMgdGhlbiwgYW5kIHNheXNcbiAgICAgIC8vIG5vdGhpbmcgb2Ygd2hhdCByYW4gbWVhbndoaWxlOiBhbiBpbnN0YW5jZSBiZWhpbmQgd2FpdHMgZm9yIGEgZnJlc2hcbiAgICAgIC8vIG9uZSwgYWZ0ZXIgaXQuIE9uZSB0aGF0IGlzIG1lcmVseSBzbG93IGlzIGFzIGZyZXNoIGFzIGFueS5cbiAgICAgIGlmICh0aGlzLmJlaGluZCAmJiB0aGlzLnBhdXNlZFNpbmNlUmVmcmVzaFN0YXJ0ZWQoKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoaW5nLnRoZW4oKCkgPT4gdGhpcy5yZWZyZXNoKCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZztcbiAgICB9XG4gICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgaWYgKGF0IC0gdGhpcy5sYXN0UmVmcmVzaCA8IHRoaXMucmVmcmVzaEludGVydmFsTXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sYXN0UmVmcmVzaCA9IGF0O1xuICAgIC8vIFdoYXRldmVyIGdldHMgdHJhY2tlZCBiZWZvcmUgdGhlIG5leHQgcmVmcmVzaCBpcyByZWFkIGZyb20gaXRzIG1hcmtlcixcbiAgICAvLyBzbyB0aGVyZSBpcyBub3RoaW5nIHRvIGNhdGNoIHVwIG9uIHlldCAtIHVubGVzcyBhbiBlbnRyeSBpcyBqdWRnZWQgYnlcbiAgICAvLyBgY29tcGxldGVTaW5jZWAsIHdoaWNoIHJlbGllcyBvbiB0aGUgbG9nIGZvciBldmVyeSB0YWcuIEV2ZW4gd2l0aCBub25lXG4gICAgLy8gaGVsZDogYSByb3cgbGV0IGdvIG9mIHRoZW4gbW92ZXMgYGNvbXBsZXRlU2luY2VgIHBhc3QgaXQsIGZvciBhbiBlbnRyeVxuICAgIC8vIHdob3NlIGdlbmVyYXRpb24gc3RhcnRlZCBiZWZvcmUgdGhhdCByZXZhbGlkYXRpb24gYW5kIHRoYXQgaXMgc3RvcmVkXG4gICAgLy8gYWZ0ZXIgaXQuXG4gICAgaWYgKHRoaXMudGFncy5zaXplID09PSAwICYmIHRoaXMuZW50cnlTdG9yZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc3RhcnRUaWNraW5nKCk7XG4gICAgdGhpcy5yZWZyZXNoaW5nID0gdGhpcy5zeW5jKGF0LCBsb2cpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgLy8gT25lIHRoYXQgc3Bhbm5lZCBhIHBhdXNlIGtub3dzIHRoZSBsb2cgYXMgb2YgaXRzIHN0YXJ0IGF0IGJlc3QuIFNvXG4gICAgICAvLyBkb2VzIG9uZSB0aGF0IG9ubHkgbG9va2VkIHBhdXNlZCwgaXRzIGV2ZW50IGxvb3AgaGVsZCB1cDogaXQgY291bnRzXG4gICAgICAvLyBhcyBubyBvbGRlciB0aGFuIGl0cyBzdGFydCwgYXMgaWYgaXQgaGFkIG5vdCBzZXR0bGVkIHNpbmNlLlxuICAgICAgdGhpcy5zZXR0bGVkQXQgPSBNYXRoLm1heChcbiAgICAgICAgdGhpcy5zZXR0bGVkQXQsXG4gICAgICAgIHRoaXMucGF1c2VkU2luY2VSZWZyZXNoU3RhcnRlZCgpID8gdGhpcy5sYXN0UmVmcmVzaCA6IHRoaXMuY2xvY2soKSxcbiAgICAgICk7XG4gICAgICB0aGlzLnN0b3BUaWNraW5nKCk7XG4gICAgICB0aGlzLnJlZnJlc2hpbmcgPSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZztcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRUaWNraW5nKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYW5GcmVlemUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sYXN0VGljayA9IHRoaXMuY2xvY2soKTtcbiAgICB0aGlzLnBhdXNlZFdoaWxlUmVmcmVzaGluZyA9IGZhbHNlO1xuICAgIHRoaXMudGlja2VyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgICBpZiAoYXQgLSB0aGlzLmxhc3RUaWNrID4gUkVGUkVTSF9QQVVTRV9NUykge1xuICAgICAgICB0aGlzLnBhdXNlZFdoaWxlUmVmcmVzaGluZyA9IHRydWU7XG4gICAgICB9XG4gICAgICB0aGlzLmxhc3RUaWNrID0gYXQ7XG4gICAgfSwgUkVGUkVTSF9USUNLX01TKTtcbiAgICAvLyBOZXZlciB3aGF0IGtlZXBzIGEgcHJvY2VzcyBhbGl2ZS5cbiAgICB0aGlzLnRpY2tlci51bnJlZj8uKCk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BUaWNraW5nKCk6IHZvaWQge1xuICAgIGNsZWFySW50ZXJ2YWwodGhpcy50aWNrZXIpO1xuICAgIHRoaXMudGlja2VyID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHByb2Nlc3Mgd2FzIHBhdXNlZCBzaW5jZSB7QGxpbmsgcmVmcmVzaGluZ30gc3RhcnRlZDogYSB0aWNrXG4gICAqIGNhbWUgbGF0ZSwgb3IgdGhlIG5leHQgb25lIGlzIG92ZXJkdWUgKGFmdGVyIGEgdGhhdywgYSByZXF1ZXN0IGNhbiBydW5cbiAgICogYmVmb3JlIHRoZSB0aW1lciBkb2VzKS5cbiAgICovXG4gIHByaXZhdGUgcGF1c2VkU2luY2VSZWZyZXNoU3RhcnRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jYW5GcmVlemUgJiZcbiAgICAgICh0aGlzLnBhdXNlZFdoaWxlUmVmcmVzaGluZyB8fFxuICAgICAgICB0aGlzLmNsb2NrKCkgLSB0aGlzLmxhc3RUaWNrID4gUkVGUkVTSF9QQVVTRV9NUylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCBhIHJldmFsaWRhdGlvbiBvZiBgdGFnc2A6IGhlcmUgYXQgb25jZSwgYW5kIGluIHRoZSByZXZhbGlkYXRpb25cbiAgICogdGFibGUgZm9yIGV2ZXJ5IG90aGVyIGluc3RhbmNlIC0gdGhlIG1hcmtlciByb3cgcGx1cyBhIGxvZyByb3cgcGVyIHRhZy5cbiAgICpcbiAgICogTmV4dC5qcyBjYWxscyBgcmV2YWxpZGF0ZVRhZ2Agb24gdGhlIGluY3JlbWVudGFsIGNhY2hlIGFuZCBgdXBkYXRlVGFnc2Agb25cbiAgICogZXZlcnkgZGlzdGluY3QgYGNhY2hlSGFuZGxlcnNgIGVudHJ5LCBhbGwgaW4gb25lIHN5bmNocm9ub3VzIGxvb3BcbiAgICogKGByZXZhbGlkYXRpb24tdXRpbHNgKSwgYW5kIGFsbCBvZiB0aGVtIHNoYXJlIHRoaXMgbWFuaWZlc3QuIFNvIGFuXG4gICAqIGlkZW50aWNhbCBjYWxsIGluIHRoZSBzYW1lIHR1cm4gam9pbnMgdGhlIGZpcnN0IGluc3RlYWQgb2Ygd3JpdGluZyB0aGVcbiAgICogcm93cyBhZ2Fpbi4gT25lIGluIGEgbGF0ZXIgdHVybiBpcyBhIHJldmFsaWRhdGlvbiBvZiBpdHMgb3duLCBldmVuIHdoaWxlXG4gICAqIHRoZSBmaXJzdCBvbmUncyB3cml0ZXMgYXJlIGluIGZsaWdodCwgYW5kIGdldHMgaXRzIG93biwgbGF0ZXIsIG1hcmtlci5cbiAgICogTmV2ZXIgcmVqZWN0czogcmVzb2x2ZXMgYGZhbHNlYCB3aGVuIGEgcm93IGZhaWxlZCB0byB3cml0ZSAodGhlIGVycm9yIGlzXG4gICAqIGxvZ2dlZCksIHNvIG90aGVyIGluc3RhbmNlcyBtYXkgbm90IHNlZSBpdC5cbiAgICovXG4gIGFzeW5jIHVwZGF0ZShcbiAgICB0YWdzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFt0YWdzLCBkdXJhdGlvbnMgPz8gbnVsbF0pO1xuICAgIGNvbnN0IGluRmxpZ2h0ID0gdGhpcy51cGRhdGluZy5nZXQoa2V5KTtcbiAgICBpZiAoaW5GbGlnaHQpIHtcbiAgICAgIHJldHVybiBpbkZsaWdodDtcbiAgICB9XG4gICAgY29uc3QgdXBkYXRlID0gdGhpcy53cml0ZSh0YWdzLCBkdXJhdGlvbnMpO1xuICAgIHRoaXMudXBkYXRpbmcuc2V0KGtleSwgdXBkYXRlKTtcbiAgICAvLyBGb3Jnb3R0ZW4gYXMgc29vbiBhcyB0aGUgY3VycmVudCB0dXJuJ3MgY2FsbHMgaGF2ZSBiZWVuIG1hZGUuXG4gICAgdm9pZCBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHRoaXMudXBkYXRpbmcuZGVsZXRlKGtleSkpO1xuICAgIHJldHVybiB1cGRhdGU7XG4gIH1cblxuICAvKipcbiAgICogV2hhdCB0aGUgdHJhY2tlZCBtYXJrZXJzIHNheSBhYm91dCBhbiBlbnRyeSBjYXJyeWluZyBgdGFnc2AsIGNyZWF0ZWQgYXRcbiAgICogYGNyZWF0ZWRBdGA6IHRoZSBtb3N0IHNldmVyZSBhbnN3ZXIgb2YgYW55IG9mIHRoZW0uXG4gICAqL1xuICBzdGF0ZSh0YWdzOiByZWFkb25seSBzdHJpbmdbXSwgY3JlYXRlZEF0OiBudW1iZXIpOiBSZXZhbGlkYXRpb25TdGF0ZSB7XG4gICAgLy8gYG1hcmtlckNsb2NrKClgLCBub3QgYERhdGUubm93KClgLCBoZXJlIGFuZCB3aGVyZXZlciBhIG1hcmtlciBpcyBzdGFtcGVkOlxuICAgIC8vIGBjcmVhdGVkQXRgIGlzIG9uIE5leHQuanMncyBjbG9jaywgYW5kIGEgbWFya2VyIG9uIHRoZSB3YWxsIGNsb2NrIHdvdWxkIGJlXG4gICAgLy8gY29tcGFyZWQgYWNyb3NzIHRoZSB0d28sIHNvIGFuIGVudHJ5IHJlZ2VuZXJhdGVkIGp1c3QgYWZ0ZXIgYVxuICAgIC8vIHJldmFsaWRhdGlvbiBjb3VsZCBzdGlsbCByZWFkIGFzIG9sZGVyIHRoYW4gaXQgd2hlcmV2ZXIgdGhleSBkcmlmdC5cbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgbGV0IHN0YXRlOiBSZXZhbGlkYXRpb25TdGF0ZSA9IFwiZnJlc2hcIjtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBjb25zdCBtYXJrZXIgPSB0aGlzLmtub3duTWFya2VyKHRhZyk7XG4gICAgICBpZiAoIW1hcmtlcikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhZ1N0YXRlID0gbWFya2VyU3RhdGUobWFya2VyLCBjcmVhdGVkQXQsIGF0KTtcbiAgICAgIGlmICh0YWdTdGF0ZSA9PT0gXCJleHBpcmVkXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiZXhwaXJlZFwiO1xuICAgICAgfVxuICAgICAgaWYgKHRhZ1N0YXRlID09PSBcInN0YWxlXCIpIHtcbiAgICAgICAgc3RhdGUgPSBcInN0YWxlXCI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBgZ2V0RXhwaXJhdGlvbmAncyBhbnN3ZXI6IHRoZSBsYXRlc3QgdGltZSBhbnkgb2YgYHRhZ3NgIGV4cGlyZWQsIGAwYCBpZlxuICAgKiBub25lIGhhcy4gT25seSBleHBpcmF0aW9ucyBhbHJlYWR5IHBhc3QgY291bnQgLSBhIHByb2ZpbGUncyBmdXR1cmVcbiAgICogYGV4cGlyZWAgaXMgbm90IGFuIGV4cGlyYXRpb24geWV0IC0gYW5kIGEgc3RhbGUgbWFyayBkb2VzIG5vdCwgbWF0Y2hpbmdcbiAgICogTmV4dC5qcydzIGRlZmF1bHQgaGFuZGxlciwgd2hpY2ggcmVhZHMgb25seSBgZXhwaXJlZGAgZm9yIGltcGxpY2l0IHRhZ3MuXG4gICAqL1xuICBleHBpcmF0aW9uKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogbnVtYmVyIHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgbGV0IGxhdGVzdCA9IDA7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy5rbm93bk1hcmtlcih0YWcpO1xuICAgICAgaWYgKCFtYXJrZXIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAobWFya2VyLnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5yZXZhbGlkYXRlZEF0KTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXJrZXIuZXhwaXJlZEF0ICE9PSB1bmRlZmluZWQgJiYgbWFya2VyLmV4cGlyZWRBdCA8PSBhdCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5leHBpcmVkQXQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbGF0ZXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZShcbiAgICB0YWdzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBjb25zdCBtYXJrZXIgPSBtYXJrZXJGb3IoYXQsIGR1cmF0aW9ucyk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy5zZXQodGFnLCBhcHBseU1hcmtlcih0aGlzLmdldCh0YWcpLCBtYXJrZXIpKTtcbiAgICB9XG4gICAgY29uc3QgeyBtYXJrZXJzLCBsb2cgfSA9IHRoaXM7XG4gICAgaWYgKCFtYXJrZXJzIHx8ICFsb2cpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB3cml0ZXM6IFtzdHJpbmcsIFByb21pc2U8dW5rbm93bj5dW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBuZXcgU2V0KHRhZ3MpKSB7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIG1hcmtlcjpcIixcbiAgICAgICAgLy8gVGhlIHJvdyBhcyBpdCBpcyBub3csIHdoaWNoIGNhcnJpZXMgYW55IGVhcmxpZXIgYHJldmFsaWRhdGVkQXRgXG4gICAgICAgIC8vIGFub3RoZXIgaW5zdGFuY2Ugd3JvdGU6IHRyYWNraW5nIG9ubHkgd2hhdCB0aGlzIGNhbGwgc2V0IHdvdWxkXG4gICAgICAgIC8vIGhpZGUgdGhhdCBvbmUgdW50aWwgdGhlIHJvbGxpbmcgcmUtcmVhZCwgYW5kIGFuIGVudHJ5IG9sZGVyIHRoYW4gaXRcbiAgICAgICAgLy8gd291bGQgcmVhZCBhcyBtZXJlbHkgc3RhbGUuXG4gICAgICAgIG1hcmtlcnMud3JpdGUodGFnLCBhdCwgZHVyYXRpb25zKS50aGVuKChyb3cpID0+IHtcbiAgICAgICAgICBpZiAocm93KSB7XG4gICAgICAgICAgICB0aGlzLnNldCh0YWcsIG1lcmdlTWFya2Vycyh0aGlzLmdldCh0YWcpLCByb3cpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIGxvZyByb3c6XCIsXG4gICAgICAgIHRoaXMucHV0TG9nUm93KGxvZywgdGFnLCBtYXJrZXIpLFxuICAgICAgXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQod3JpdGVzLm1hcCgoWywgd3JpdGVdKSA9PiB3cml0ZSkpO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3Iod3JpdGVzW2ldWzBdLCByZXN1bHQucmVhc29uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cy5ldmVyeSgocmVzdWx0KSA9PiByZXN1bHQuc3RhdHVzID09PSBcImZ1bGZpbGxlZFwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXQgYHRhZ2AncyBsb2cgcm93LCBzdGFtcGVkIG9uIHRoZSB3YWxsIGNsb2NrICh0aGUgbWFya2VyIHZhbHVlcyBhcmUgb25cbiAgICogTmV4dC5qcydzOiBzZWUge0BsaW5rIFJldmFsaWRhdGlvbkxvZ30pLlxuICAgKlxuICAgKiBSZWFkZXJzIG9ubHkgbG9vayB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NU30gYmVoaW5kIHRoZWlyIGxhc3RcbiAgICogcXVlcnksIHNvIGEgcm93IHRoYXQgc2hvd3MgdXAgbXVjaCBsYXRlciB0aGFuIGl0cyB0aW1lc3RhbXAgLSBhIHNsb3dcbiAgICogY29ubmVjdGlvbiwgcmV0cmllcyB1bmRlciB0aHJvdHRsaW5nIC0gaXMgYmVoaW5kIGV2ZXJ5IGN1cnNvciBhbmQgbmV2ZXJcbiAgICogcmVhZC4gQSBzbG93IHB1dCBpcyB0aGVyZWZvcmUgbWFkZSBhZ2FpbiB1bmRlciBhIGZyZXNoIHRpbWVzdGFtcCwgd2hpY2hcbiAgICogcmVhZGVycyB3aWxsIHNlZTsgb25lIHNsb3cgdHdpY2UgaXMgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwdXRMb2dSb3coXG4gICAgbG9nOiBSZXZhbGlkYXRpb25Mb2csXG4gICAgdGFnOiBzdHJpbmcsXG4gICAgbWFya2VyOiBUYWdNYXJrZXIsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgMjsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICAgIGF3YWl0IGxvZy5wdXQodGFnLCBhdCwgbWFya2VyKTtcbiAgICAgIGlmICh0aGlzLmNsb2NrKCkgLSBhdCA8PSBNQVhfTE9HX1BVVF9NUykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgcmV2YWxpZGF0aW9uIGxvZyByb3cgZm9yICR7dGFnfSB0b29rIGxvbmdlciB0aGFuIHJlYWRlcnMgbG9vayBiYWNrYCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIE9uZSByZWZyZXNoIHN0YXJ0ZWQgYXQgYGF0YDogdGhlIGxvZyByb3dzIHNpbmNlIHRoZSBjdXJzb3IsIGFuZCB0aGUgbmV4dFxuICAgKiBzbGljZSBvZiB0aGUgcm9sbGluZyByZS1yZWFkLlxuICAgKlxuICAgKiBBIGZhaWxlZCBxdWVyeSBjaGFuZ2VzIG5vdGhpbmcgYnV0IHRoZSBsb2c6IHRoZSB0YWdzIHN0YXkgdHJhY2tlZCBhcyB0aGV5XG4gICAqIHdlcmUsIGFuZCB0aGUgbmV4dCByZWZyZXNoIGFza3MgYWdhaW4gZnJvbSB0aGUgc2FtZSBjdXJzb3IuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN5bmMoYXQ6IG51bWJlciwgbG9nOiBSZXZhbGlkYXRpb25Mb2cpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoYXQgLSB0aGlzLmxhc3RMb2dSZWFkID4gTUFYX1JFVkFMSURBVElPTl9MT0dfR0FQX01TKSB7XG4gICAgICB0aGlzLmZvcmdldChcbiAgICAgICAgYXQsXG4gICAgICAgIFwidGhlIHJldmFsaWRhdGlvbiBsb2cgbWF5IG5vdCBjb3ZlciB0aGUgZ2FwIHNpbmNlIGl0IHdhcyBsYXN0IHJlYWRcIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRoZSByb2xsaW5nIHJlLXJlYWQgcnVucyBhbG9uZ3NpZGUsIG5vdCB3YWl0ZWQgZm9yOiBjYXRjaGluZyB1cCBuZWVkc1xuICAgIC8vIG9ubHkgdGhlIGxvZywgYW5kIGEgdGhyb3R0bGVkIGBCYXRjaEdldEl0ZW1gIHNob3VsZCBub3QgaG9sZCB0aGVcbiAgICAvLyByZXF1ZXN0IGBjYXRjaFVwYCBtYWtlcyB3YWl0LiBBIGZvcmdldCBtZWFud2hpbGUgcmVhZHMgaXQgYWdhaW4uXG4gICAgY29uc3QgZHVlID0gdGhpcy5kdWUoYXQpO1xuICAgIGlmIChkdWUubGVuZ3RoID4gMCkge1xuICAgICAgdm9pZCB0aGlzLnN0YXJ0UmVhZChkdWUpO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBsb2cucXVlcnkodGhpcy5jdXJzb3IpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgdGFnIHJldmFsaWRhdGlvbiBsb2c6XCIsIGVycm9yKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC50cnVuY2F0ZWQpIHtcbiAgICAgIHRoaXMuZm9yZ2V0KFxuICAgICAgICBhdCxcbiAgICAgICAgXCJ0aGUgcmV2YWxpZGF0aW9uIGxvZyBoYXMgbW9yZSByb3dzIHRoYW4gb25lIHF1ZXJ5IHJlYWRzXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBBIHNjYW4gb2YgZXZlcnkgZW50cnkgaGVsZCwgd2hpY2ggYWxzbyBkcm9wcyB0aGUgZXhwaXJlZCBvbmVzLCBvbmNlIGluXG4gICAgLy8gYSB3aGlsZTogc28gZXhwaXJlZCBlbnRyaWVzIG5ldmVyIHJlYWQgYWdhaW4gZG9uJ3QgcGlsZSB1cCBhaGVhZCBvZlxuICAgIC8vIGxpdmUgb25lcy4gSW4gYmV0d2VlbiwgdGhlIHN0b3JlcyBhbnN3ZXIgZWFybHkgd2l0aG91dCBvbmUsIHdoaWNoIG9ubHlcbiAgICAvLyBrZWVwcyByb3dzIGluIGBsb2dPbmx5YCBhIGxpdHRsZSBsb25nZXIuXG4gICAgY29uc3Qgc2NhbiA9IGF0IC0gdGhpcy5sYXN0RW50cnlTY2FuID4gRU5UUllfU0NBTl9JTlRFUlZBTF9NUztcbiAgICBpZiAoc2Nhbikge1xuICAgICAgdGhpcy5sYXN0RW50cnlTY2FuID0gYXQ7XG4gICAgfVxuICAgIGNvbnN0IG9sZGVzdCA9IHRoaXMub2xkZXN0RW50cnkoc2Nhbik7XG4gICAgbGV0IGFwcGxpZWQgPSAwO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJlc3VsdC5yb3dzKSB7XG4gICAgICBpZiAodGhpcy5hcHBsaWVkLmhhcyhyb3cuc2spKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldChyb3cudGFnKTtcbiAgICAgIGlmIChtYXJrZXIpIHtcbiAgICAgICAgLy8gYHNldGAgb24gYSBrZXkgYWxyZWFkeSB0aGVyZSBrZWVwcyBpdHMgcGxhY2UgaW4gdGhlIExSVSBvcmRlcjogYmVpbmdcbiAgICAgICAgLy8gcmV2YWxpZGF0ZWQgZWxzZXdoZXJlIGlzIG5vdCBhIHVzZS5cbiAgICAgICAgdGhpcy50YWdzLnNldChyb3cudGFnLCBtZXJnZU1hcmtlcnMobWFya2VyLCByb3cubWFya2VyKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMucmVhZGluZy5oYXMocm93LnRhZykpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nUm93cy5zZXQoXG4gICAgICAgICAgcm93LnRhZyxcbiAgICAgICAgICBtZXJnZU1hcmtlcnModGhpcy5wZW5kaW5nUm93cy5nZXQocm93LnRhZyksIHJvdy5tYXJrZXIpLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSB0YWcgdGhpcyBpbnN0YW5jZSBkb2VzIG5vdCB0cmFjayBpcyByZWFkIGZyb20gaXRzIG1hcmtlciB3aGVuIGl0XG4gICAgICAgIC8vIGlzIG5leHQgbmVlZGVkIC0gYnV0IG5vdCB5ZXQgbWFya2VkIGFwcGxpZWQsIGJlY2F1c2UgdGhhdCByZWFkIG1heVxuICAgICAgICAvLyBtaXNzIHRoaXMgdmVyeSByZXZhbGlkYXRpb246IHRoZSB3cml0ZXIgcHV0cyB0aGUgbG9nIHJvdyBhbmQgdGhlXG4gICAgICAgIC8vIG1hcmtlciBhdCB0aGUgc2FtZSB0aW1lLCBhbmQgdGhlIHJlYWQgaXMgYW4gZXZlbnR1YWxseSBjb25zaXN0ZW50XG4gICAgICAgIC8vIGBCYXRjaEdldEl0ZW1gIHRoYXQgY2FuIGxhbmQgbWlsbGlzZWNvbmRzIGFmdGVyIHRoZSByb3cgc2hvd2VkIGhlcmUuXG4gICAgICAgIC8vIE1hcmtlZCBhcHBsaWVkLCB0aGUgcm93IHdhcyBza2lwcGVkIGJ5IGV2ZXJ5IHF1ZXJ5IHRoZSBsb29rYmFja1xuICAgICAgICAvLyByZXR1cm5lZCBpdCB0bywgYW5kIHRoZSBwcmUtcmV2YWxpZGF0aW9uIG1hcmtlciBzdG9vZCB1bnRpbCB0aGVcbiAgICAgICAgLy8gcm9sbGluZyByZS1yZWFkLiBMZWZ0IHVubWFya2VkLCB0aGUgbmV4dCByZWZyZXNoIGFwcGxpZXMgaXQgdG9cbiAgICAgICAgLy8gd2hhdGV2ZXIgdGhhdCByZWFkIGZvdW5kOyBpdCBjb3N0cyBubyByZWFkLCBvbmx5IHRoZSByb3cgYmVpbmdcbiAgICAgICAgLy8gbG9va2VkIGF0IGFnYWluIHdoaWxlIGl0IGlzIGluc2lkZSB0aGUgbG9va2JhY2suXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEtlcHQgbWVhbndoaWxlIGluIGBsb2dPbmx5YCwgd2hpY2ggaXMgYWxsIGBjb21wbGV0ZVNpbmNlYCBuZWVkcy5cbiAgICAgICAgdGhpcy5yZW1lbWJlckxvZ2dlZChcbiAgICAgICAgICByb3cudGFnLFxuICAgICAgICAgIG1lcmdlTWFya2Vycyh0aGlzLmxvZ09ubHkuZ2V0KHJvdy50YWcpLCByb3cubWFya2VyKSxcbiAgICAgICAgICBvbGRlc3QsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hcHBsaWVkLnNldChyb3cuc2ssIHJvdy5hdCk7XG4gICAgICBhcHBsaWVkKys7XG4gICAgfVxuICAgIGlmIChvbGRlc3QgPiB0aGlzLnBydW5lZEFnYWluc3QpIHtcbiAgICAgIHRoaXMucHJ1bmVMb2dnZWQob2xkZXN0KTtcbiAgICB9XG4gICAgLy8gVGhlIHJvd3MganVzdCBrZXB0IGFyZSBrbm93biBieSBsYXRlciB0aGFuIGBvbGRlc3RgIHRvby5cbiAgICB0aGlzLnBydW5lZEFnYWluc3QgPSBvbGRlc3Q7XG4gICAgdGhpcy5sYXN0TG9nUmVhZCA9IGF0O1xuICAgIHRoaXMuYWR2YW5jZShhdCAtIFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVMpO1xuICAgIHRoaXMuZGVidWcoXG4gICAgICBgcmVhZCAke3Jlc3VsdC5yb3dzLmxlbmd0aH0gcmV2YWxpZGF0aW9uIGxvZyByb3dzICgke2FwcGxpZWR9IGFwcGxpZWQpYCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0YWdzIHRvIHJlYWQgb24gdGhpcyByZWZyZXNoLCBhdCBtb3N0IG9uZSBgQmF0Y2hHZXRJdGVtYCdzIHdvcnRoOlxuICAgKiB0aG9zZSB3aG9zZSByZWFkIGZhaWxlZCwgdGhlbiB0aG9zZSB3aG9zZSByZS1yZWFkIGhhcyBjb21lIGR1ZSwgaW4gdGhlXG4gICAqIG9yZGVyIHRoZXkgd2VyZSBsYXN0IHJlYWQuXG4gICAqL1xuICBwcml2YXRlIGR1ZShhdDogbnVtYmVyKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGR1ZTogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0aGlzLnVucmVhZCkge1xuICAgICAgaWYgKGR1ZS5sZW5ndGggPj0gQkFUQ0hfR0VUX01BWF9LRVlTKSByZXR1cm4gZHVlO1xuICAgICAgaWYgKCF0aGlzLnJlYWRpbmcuaGFzKHRhZykpIHtcbiAgICAgICAgZHVlLnB1c2godGFnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gS25vd24gaW4gdGltZSBvcmRlciwgYW5kIGVhY2ggZHVlIGF0IG1vc3QgYGppdHRlcmAgZWFybGllciB0aGFuIHRoZVxuICAgIC8vIHRhZ3MgYWZ0ZXIgaXQ6IHBhc3QgYSB0YWcgZHVlIG1vcmUgdGhhbiB0aGF0IGZyb20gbm93LCBub25lIGlzIGR1ZS5cbiAgICBjb25zdCBqaXR0ZXIgPSB0aGlzLnJlc3luY0ludGVydmFsTXMgKiBUQUdfUkVTWU5DX0pJVFRFUjtcbiAgICBmb3IgKGNvbnN0IFt0YWcsIGR1ZUF0XSBvZiB0aGlzLmR1ZUF0KSB7XG4gICAgICBpZiAoZHVlLmxlbmd0aCA+PSBCQVRDSF9HRVRfTUFYX0tFWVMgfHwgZHVlQXQgLSBqaXR0ZXIgPiBhdCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChkdWVBdCA8PSBhdCAmJiAhdGhpcy51bnJlYWQuaGFzKHRhZykgJiYgIXRoaXMucmVhZGluZy5oYXModGFnKSkge1xuICAgICAgICBkdWUucHVzaCh0YWcpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcmdldCBldmVyeSB0cmFja2VkIG1hcmtlciwgYW5kIGZvbGxvdyB0aGUgbG9nIGZyb20gYGF0YDogd2hhdCBpcyBuZWVkZWRcbiAgICogbmV4dCBpcyByZWFkIGZyb20gaXRzIG1hcmtlciBhcyBpdCBpcyBuZWVkZWQsIHNwcmVhZCBvdmVyIHRoZSByZXF1ZXN0c1xuICAgKiB0aGF0IG5lZWQgaXQsIHJhdGhlciB0aGFuIGV2ZXJ5IHRyYWNrZWQgdGFnIHJlLXJlYWQgYXQgb25jZS5cbiAgICovXG4gIHByaXZhdGUgZm9yZ2V0KGF0OiBudW1iZXIsIHdoeTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5kZWJ1ZyhgZm9yZ2V0dGluZyAke3RoaXMudGFncy5zaXplfSB0cmFja2VkIHRhZ3M6ICR7d2h5fWApO1xuICAgIHRoaXMuZm9yZ290dGVuKys7XG4gICAgLy8gV2hhdCB0aGUgbWFya2VycyBleHBpcmUgbGF0ZXIgaXMgc3RpbGwgdG8gYXBwbHkgb25jZSBpdCBpcyBwYXN0LlxuICAgIGZvciAoY29uc3QgbWFya2VyIG9mIHRoaXMudGFncy52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5yYWlzZUZsb29yKG1hcmtlcik7XG4gICAgfVxuICAgIGZvciAoY29uc3QgbWFya2VyIG9mIHRoaXMubG9nT25seS52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5yYWlzZUZsb29yKG1hcmtlcik7XG4gICAgfVxuICAgIHRoaXMudGFncy5jbGVhcigpO1xuICAgIHRoaXMuZHVlQXQuY2xlYXIoKTtcbiAgICB0aGlzLnVucmVhZC5jbGVhcigpO1xuICAgIHRoaXMuYXBwbGllZC5jbGVhcigpO1xuICAgIHRoaXMubG9nT25seS5jbGVhcigpO1xuICAgIC8vIE5ldmVyIGJhY2s6IGEgbWFya2VyIGRyb3BwZWQgZWFybGllciBtYXkgaGF2ZSBleHBpcmVkIGVudHJpZXMgbGF0ZXIuXG4gICAgdGhpcy5mbG9vciA9IE1hdGgubWF4KHRoaXMuZmxvb3IsIG1hcmtlckNsb2NrKCkpO1xuICAgIHRoaXMuY3Vyc29yID0gYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TO1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBjdXJzb3IgZm9yd2FyZCB0byBgY3Vyc29yYCwgZm9yZ2V0dGluZyBhcHBsaWVkIHJvd3MgYmVmb3JlIGl0OlxuICAgKiBubyBxdWVyeSByZXR1cm5zIHRoZW0gYWdhaW4uXG4gICAqL1xuICBwcml2YXRlIGFkdmFuY2UoY3Vyc29yOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoY3Vyc29yIDw9IHRoaXMuY3Vyc29yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3Vyc29yID0gY3Vyc29yO1xuICAgIGZvciAoY29uc3QgW3NrLCBhdF0gb2YgdGhpcy5hcHBsaWVkKSB7XG4gICAgICBpZiAoYXQgPCBjdXJzb3IpIHtcbiAgICAgICAgdGhpcy5hcHBsaWVkLmRlbGV0ZShzayk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgYHRhZ3NgIGZyb20gdGhlIHRhYmxlLCBhbmQgcmVwb3J0IHdoZXRoZXIgdGhhdCB3b3JrZWQuIEEgcmVhZCB0aGF0XG4gICAqIGZhaWxzIGxlYXZlcyB0aGVtIHRyYWNrZWQgYXMgdGhleSB3ZXJlLCBhbmQgdGhlIG5leHQgcmVmcmVzaCByZWFkcyB0aGVtXG4gICAqIGFnYWluOiB0aGUgc2FtZSBcImFzc3VtZSB0aGUgZW50cnkgaXMgdmFsaWRcIiB0aGUgaW5jcmVtZW50YWwgY2FjaGUgaGFzXG4gICAqIGFsd2F5cyBhbnN3ZXJlZCB3aXRoLCByYXRoZXIgdGhhbiBhIHJlYWQgb24gZXZlcnkgcmVxdWVzdCB3aGlsZSBEeW5hbW9EQlxuICAgKiBpcyB1bmF2YWlsYWJsZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVhZEludG8odGFnczogc3RyaW5nW10sIGFnYWluID0gZmFsc2UpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICBjb25zdCBmb3Jnb3R0ZW4gPSB0aGlzLmZvcmdvdHRlbjtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVhZCA9IGF3YWl0IHRoaXMubWFya2VycyEucmVhZCh0YWdzKTtcbiAgICAgIGlmICh0aGlzLmZvcmdvdHRlbiAhPT0gZm9yZ290dGVuICYmICFhZ2Fpbikge1xuICAgICAgICAvLyBSZWFkIGJlZm9yZSBhIGZvcmdldCAtIGFjcm9zcyBhIGZyZWV6ZSwgYXMgbGlrZSBhcyBub3QgLSBzbyBhc1xuICAgICAgICAvLyBzdGFsZSBhcyB3aGF0IGl0IGZvcmdvdC4gUmVhZCBhZ2FpbiByYXRoZXIgdGhhbiBsZWF2ZSB0aGUgdGFnc1xuICAgICAgICAvLyB1bnRyYWNrZWQ6IHdob2V2ZXIgd2FpdHMgb24gdGhpcyByZWFkIChgcmVhZGluZ2ApIGp1ZGdlcyBlbnRyaWVzXG4gICAgICAgIC8vIGJ5IGl0IG5leHQsIGFuZCBhbiB1bnRyYWNrZWQgdGFnIGNvdW50cyBmb3Igbm90aGluZy4gT25jZTogYSBydW5cbiAgICAgICAgLy8gb2YgZm9yZ2V0cyAoYSB0cnVuY2F0ZWQgbG9nLCBxdWVyeSBhZnRlciBxdWVyeSkgd291bGQgb3RoZXJ3aXNlXG4gICAgICAgIC8vIGtlZXAgdGhlbSB3YWl0aW5nLCBhbmQgdGhlIHNlY29uZCByZWFkIGJlZ2FuIGFmdGVyIHRoZSBmaXJzdC5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVhZEludG8odGFncywgdHJ1ZSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICAgIHRoaXMudW5yZWFkLmRlbGV0ZSh0YWcpO1xuICAgICAgICB0aGlzLnJlbWVtYmVyKFxuICAgICAgICAgIHRhZyxcbiAgICAgICAgICBtZXJnZU1hcmtlcnMoXG4gICAgICAgICAgICBtZXJnZU1hcmtlcnModGhpcy50YWdzLmdldCh0YWcpLCByZWFkLmdldCh0YWcpKSxcbiAgICAgICAgICAgIHRoaXMudGFrZVBlbmRpbmdSb3dzKHRhZyksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5rbm93bih0YWcsIGF0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZGVidWcoYHJlYWQgJHt0YWdzLmxlbmd0aH0gdGFnIG1hcmtlcnMgKCR7cmVhZC5zaXplfSBzZXQpYCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgdGFnIG1hcmtlcnM6XCIsIGVycm9yKTtcbiAgICAgIGlmICh0aGlzLmZvcmdvdHRlbiAhPT0gZm9yZ290dGVuICYmICFhZ2Fpbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkSW50byh0YWdzLCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudHJhY2tVbnJlYWQodGFncyk7XG4gICAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICAgIHRoaXMudW5yZWFkLmFkZCh0YWcpO1xuICAgICAgICBjb25zdCBwZW5kaW5nID0gdGhpcy50YWtlUGVuZGluZ1Jvd3ModGFnKTtcbiAgICAgICAgaWYgKHBlbmRpbmcpIHtcbiAgICAgICAgICB0aGlzLnJlbWVtYmVyKHRhZywgbWVyZ2VNYXJrZXJzKHRoaXMudGFncy5nZXQodGFnKSwgcGVuZGluZykpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0YWtlUGVuZGluZ1Jvd3ModGFnOiBzdHJpbmcpOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBlbmRpbmdSb3dzLmdldCh0YWcpO1xuICAgIGNvbnN0IGxvZ2dlZCA9IHRoaXMubG9nT25seS5nZXQodGFnKTtcbiAgICB0aGlzLnBlbmRpbmdSb3dzLmRlbGV0ZSh0YWcpO1xuICAgIHRoaXMubG9nT25seS5kZWxldGUodGFnKTtcbiAgICByZXR1cm4gbG9nZ2VkID8gbWVyZ2VNYXJrZXJzKGxvZ2dlZCwgcGVuZGluZykgOiBwZW5kaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoYXQgdGhpcyBpbnN0YW5jZSBrbm93cyBvZiBgdGFnYDogdHJhY2tlZCwgb3IgZnJvbSB0aGUgbG9nIGFsb25lIC1cbiAgICogaW5jbHVkaW5nIHJvd3MgdGhhdCBhcnJpdmVkIHdoaWxlIGl0cyBmaXJzdCByZWFkIGlzIGluIGZsaWdodC5cbiAgICovXG4gIHByaXZhdGUga25vd25NYXJrZXIodGFnOiBzdHJpbmcpOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHRyYWNrZWQgPSB0aGlzLnRhZ3MuZ2V0KHRhZyk7XG4gICAgaWYgKHRyYWNrZWQpIHtcbiAgICAgIHJldHVybiB0cmFja2VkO1xuICAgIH1cbiAgICBjb25zdCBsb2dnZWQgPSB0aGlzLmxvZ09ubHkuZ2V0KHRhZyk7XG4gICAgY29uc3QgcGVuZGluZyA9IHRoaXMucGVuZGluZ1Jvd3MuZ2V0KHRhZyk7XG4gICAgcmV0dXJuIGxvZ2dlZCB8fCBwZW5kaW5nID8gbWVyZ2VNYXJrZXJzKGxvZ2dlZCwgcGVuZGluZykgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogS2VlcCBgdGFnYCdzIGxvZyByb3dzIGluIGBsb2dPbmx5YCwgdW5sZXNzIHRoZXkgY2Fubm90IGFwcGx5IHRvIGFuIGVudHJ5XG4gICAqIGhlbGQsIGBvbGRlc3RgIG9yIG5ld2VyIChzZWUge0BsaW5rIHBydW5lTG9nZ2VkfSksIGFzIGJvdW5kZWQgYXMgdGhlXG4gICAqIHRyYWNrZWQgdGFncy4gRWl0aGVyIHdheSBhIHJvdyBsZXQgZ28gb2YgdGFrZXMgd2hhdCBpdCBrbmV3IHdpdGggaXQsIHNvXG4gICAqIGBjb21wbGV0ZVNpbmNlYCBtb3ZlcyBwYXN0IGl0LlxuICAgKi9cbiAgcHJpdmF0ZSByZW1lbWJlckxvZ2dlZCh0YWc6IHN0cmluZywgbWFya2VyOiBUYWdNYXJrZXIsIG9sZGVzdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5sb2dPbmx5LmRlbGV0ZSh0YWcpO1xuICAgIGlmIChrbm93bkJ5KG1hcmtlciwgbWFya2VyQ2xvY2soKSkgPD0gb2xkZXN0KSB7XG4gICAgICB0aGlzLnJhaXNlRmxvb3IobWFya2VyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sb2dPbmx5LnNldCh0YWcsIG1hcmtlcik7XG4gICAgZm9yIChjb25zdCBbZmlyc3QsIGRyb3BwZWRdIG9mIHRoaXMubG9nT25seSkge1xuICAgICAgaWYgKHRoaXMubG9nT25seS5zaXplIDw9IHRoaXMubWF4VHJhY2tlZFRhZ3MpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB0aGlzLmxvZ09ubHkuZGVsZXRlKGZpcnN0KTtcbiAgICAgIHRoaXMucmFpc2VGbG9vcihkcm9wcGVkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRHJvcCB0aGUgYGxvZ09ubHlgIHJvd3MgdGhhdCBjYW5ub3QgYXBwbHkgdG8gYW4gZW50cnkgaGVsZCwgYG9sZGVzdGAgb3JcbiAgICogbmV3ZXI6IGV2ZXJ5IHJldmFsaWRhdGlvbiB0aGV5IG5hbWUgc28gZmFyIGlzIG5vIGxhdGVyIHRoYW4gaXQuIFRoYXRcbiAgICogbW92ZXMgYGNvbXBsZXRlU2luY2VgIG5vIGZ1cnRoZXIgdGhhbiBgb2xkZXN0YCwgd2hpY2ggY29zdHMgdGhlIGVudHJpZXNcbiAgICogaGVsZCBub3RoaW5nLCBhbmQgYSBwcm9maWxlJ3MgYGV4cGlyZWRBdGAgc3RpbGwgdG8gY29tZSB3YWl0cyBpblxuICAgKiBgbGF0ZXJGbG9vcnNgLiBXaXRob3V0IHRoaXMsIGEgZGVwbG95bWVudCByZXZhbGlkYXRpbmcgbWFueSBkaXN0aW5jdCB0YWdzXG4gICAqIGZpbGxlZCBgbG9nT25seWAgd2l0aCB0YWdzIG5vIGVudHJ5IGhlcmUgY2FycmllcywgYW5kIHRoZSBldmljdGlvbnMgcGFzdFxuICAgKiBpdHMgYm91bmQga2VwdCBtb3ZpbmcgYGNvbXBsZXRlU2luY2VgIHVwIHRvIHRoZSBwcmVzZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBwcnVuZUxvZ2dlZChvbGRlc3Q6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBmb3IgKGNvbnN0IFt0YWcsIG1hcmtlcl0gb2YgdGhpcy5sb2dPbmx5KSB7XG4gICAgICBpZiAoa25vd25CeShtYXJrZXIsIGF0KSA8PSBvbGRlc3QpIHtcbiAgICAgICAgdGhpcy5sb2dPbmx5LmRlbGV0ZSh0YWcpO1xuICAgICAgICB0aGlzLnJhaXNlRmxvb3IobWFya2VyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIG9sZGVzdCBlbnRyeSB0aW1lc3RhbXAgb2YgYW55IHJlZ2lzdGVyZWQgc3RvcmUsIGBJbmZpbml0eWAgd2l0aCBub25lOlxuICAgKiBlYXJseSwgbmV2ZXIgbGF0ZSwgdW5sZXNzIGBzY2FuYC5cbiAgICovXG4gIHByaXZhdGUgb2xkZXN0RW50cnkoc2NhbjogYm9vbGVhbik6IG51bWJlciB7XG4gICAgbGV0IG9sZGVzdCA9IEluZmluaXR5O1xuICAgIGZvciAoY29uc3QgeyBvbGRlc3RUaW1lc3RhbXAgfSBvZiB0aGlzLmVudHJ5U3RvcmVzKSB7XG4gICAgICBvbGRlc3QgPSBNYXRoLm1pbihvbGRlc3QsIG9sZGVzdFRpbWVzdGFtcChzY2FuKSk7XG4gICAgfVxuICAgIHJldHVybiBvbGRlc3Q7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSBgY29tcGxldGVTaW5jZWAgcGFzdCBgbWFya2VyYCdzIHJldmFsaWRhdGlvbnM6IHdoYXQgaXMgbm8gbG9uZ2VyXG4gICAqIGtub3duIGFib3V0IGEgdGFnIG9uY2UgaXRzIG1hcmtlciBpcyBkcm9wcGVkLiBBIGZ1dHVyZSBgZXhwaXJlZEF0YCB3YWl0c1xuICAgKiBpbiBgbGF0ZXJGbG9vcnNgIHVudGlsIGl0IGlzIHBhc3QuXG4gICAqL1xuICBwcml2YXRlIHJhaXNlRmxvb3IobWFya2VyOiBUYWdNYXJrZXIpOiB2b2lkIHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgdGhpcy5mbG9vciA9IE1hdGgubWF4KHRoaXMuZmxvb3IsIGtub3duQnkobWFya2VyLCBhdCkpO1xuICAgIGNvbnN0IHsgZXhwaXJlZEF0IH0gPSBtYXJrZXI7XG4gICAgaWYgKGV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIGV4cGlyZWRBdCA+IE1hdGgubWF4KGF0LCB0aGlzLmZsb29yKSkge1xuICAgICAgdGhpcy5sYXRlckZsb29yKGV4cGlyZWRBdCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBgdGltZWAgdG8gYGxhdGVyRmxvb3JzYCwgaW4gb3JkZXIuIFBhc3QgdGhlIHRyYWNrZWQtdGFnIGJvdW5kIHRoZSB0d29cbiAgICogc3BhbnMgY2xvc2VzdCB0b2dldGhlciBhcmUgbWVyZ2VkOiBmcm9tIHRoZSBmaXJzdCdzIHN0YXJ0LFxuICAgKiBgY29tcGxldGVTaW5jZWAgaXMgdGhlIHNlY29uZCdzIGVuZCwgZWFybHkgLSB3aGljaCBvbmx5IGNvc3RzIHJlYWRzLCBhbmRcbiAgICogZm9yIGFzIHNob3J0IGEgdGltZSBhcyBhbnkgbWVyZ2UgYWxsb3dzLiBOZXZlciBsYXRlciB0aGFuIGl0cyB0aW1lLCB3aGljaFxuICAgKiB3b3VsZCBsZXQgYW4gZW50cnkgZXhwaXJlIHVuc2Vlbi5cbiAgICovXG4gIHByaXZhdGUgbGF0ZXJGbG9vcih0aW1lOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmbG9vcnMgPSB0aGlzLmxhdGVyRmxvb3JzO1xuICAgIGxldCBsb3cgPSAwO1xuICAgIGxldCBoaWdoID0gZmxvb3JzLmxlbmd0aDtcbiAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKTtcbiAgICAgIGlmIChmbG9vcnNbbWlkXVswXSA8IHRpbWUpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEluc2lkZSBhIG1lcmdlZCBzcGFuIGFscmVhZHk6IGJ5IGl0cyBzdGFydCwgYGNvbXBsZXRlU2luY2VgIGlzIHBhc3QgaXQuXG4gICAgLy8gT3IgYWxyZWFkeSB0aGVyZTogYSBsb2cgcm93IGZvciBhbiB1bnRyYWNrZWQgdGFnIGlzIGFwcGxpZWQgYWdhaW4gYnlcbiAgICAvLyBldmVyeSBxdWVyeSBpdHMgbG9va2JhY2sgcmV0dXJucyBpdCB0by5cbiAgICBpZiAoKGxvdyA+IDAgJiYgZmxvb3JzW2xvdyAtIDFdWzFdID49IHRpbWUpIHx8IGZsb29yc1tsb3ddPy5bMF0gPT09IHRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZmxvb3JzLnNwbGljZShsb3csIDAsIFt0aW1lLCB0aW1lXSk7XG4gICAgLy8gQSBzY2FuLCBidXQgb25seSBvbmNlIHBhc3QgdGhlIGJvdW5kLiBNZXJnaW5nIHRoZSBuZXcgdGltZSBpbnRvIGFcbiAgICAvLyBuZWlnaGJvdXIgaW5zdGVhZCBjb3VsZCBqb2luIGFuIGhvdXItb3V0IHNwYW4gd2l0aCBhIHllYXItb3V0IG9uZSwgYW5kXG4gICAgLy8gaG9sZCBgY29tcGxldGVTaW5jZWAgYSB5ZWFyIGVhcmx5LlxuICAgIGlmIChmbG9vcnMubGVuZ3RoID4gdGhpcy5tYXhUcmFja2VkVGFncykge1xuICAgICAgbGV0IG1lcmdlID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmxvb3JzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZmxvb3JzW2kgKyAxXVsxXSAtIGZsb29yc1tpXVswXSA8XG4gICAgICAgICAgZmxvb3JzW21lcmdlICsgMV1bMV0gLSBmbG9vcnNbbWVyZ2VdWzBdXG4gICAgICAgICkge1xuICAgICAgICAgIG1lcmdlID0gaTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZmxvb3JzLnNwbGljZShtZXJnZSwgMiwgW2Zsb29yc1ttZXJnZV1bMF0sIGZsb29yc1ttZXJnZSArIDFdWzFdXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJlY29yZCB0aGF0IGB0YWdgJ3MgbWFya2VyIHdhcyBrbm93biBmcm9tIHRoZSB0YWJsZSBhdCBgYXRgLiAqL1xuICBwcml2YXRlIGtub3duKHRhZzogc3RyaW5nLCBhdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5kdWVBdC5kZWxldGUodGFnKTtcbiAgICB0aGlzLmR1ZUF0LnNldChcbiAgICAgIHRhZyxcbiAgICAgIGF0ICsgdGhpcy5yZXN5bmNJbnRlcnZhbE1zICogKDEgLSBUQUdfUkVTWU5DX0pJVFRFUiAqIHRoaXMucmFuZG9tKCkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlbWVtYmVyKHRhZzogc3RyaW5nLCBtYXJrZXI6IFRhZ01hcmtlcik6IHZvaWQge1xuICAgIHRoaXMudGFncy5kZWxldGUodGFnKTtcbiAgICB0aGlzLnRhZ3Muc2V0KHRhZywgbWFya2VyKTtcbiAgICBmb3IgKGNvbnN0IG9sZGVzdCBvZiB0aGlzLnRhZ3Mua2V5cygpKSB7XG4gICAgICBpZiAodGhpcy50YWdzLnNpemUgPD0gdGhpcy5tYXhUcmFja2VkVGFncykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHRoaXMucmFpc2VGbG9vcih0aGlzLnRhZ3MuZ2V0KG9sZGVzdCkhKTtcbiAgICAgIHRoaXMudGFncy5kZWxldGUob2xkZXN0KTtcbiAgICAgIHRoaXMuZHVlQXQuZGVsZXRlKG9sZGVzdCk7XG4gICAgICB0aGlzLnVucmVhZC5kZWxldGUob2xkZXN0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRvdWNoKHRhZzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldCh0YWcpO1xuICAgIGlmIChtYXJrZXIpIHtcbiAgICAgIHRoaXMucmVtZW1iZXIodGFnLCBtYXJrZXIpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBsYXRlc3QgcmV2YWxpZGF0aW9uIGBtYXJrZXJgIGhhcyBtYWRlIGtub3duIGJ5IGBhdGAsIGAtSW5maW5pdHlgIHdpdGhcbiAqIG5vbmU6IGEgZnV0dXJlIGBleHBpcmVkQXRgIGlzIHN0aWxsIHRvIGNvbWUuXG4gKi9cbmZ1bmN0aW9uIGtub3duQnkobWFya2VyOiBUYWdNYXJrZXIsIGF0OiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCB7IHJldmFsaWRhdGVkQXQsIHN0YWxlQXQsIGV4cGlyZWRBdCB9ID0gbWFya2VyO1xuICByZXR1cm4gTWF0aC5tYXgoXG4gICAgcmV2YWxpZGF0ZWRBdCA/PyAtSW5maW5pdHksXG4gICAgc3RhbGVBdCA/PyAtSW5maW5pdHksXG4gICAgZXhwaXJlZEF0ICE9PSB1bmRlZmluZWQgJiYgZXhwaXJlZEF0IDw9IGF0ID8gZXhwaXJlZEF0IDogLUluZmluaXR5LFxuICApO1xufVxuXG4vKipcbiAqIFRoZSBsb25nZXN0IGEgbG9nIHJvdydzIHB1dCBtYXkgdGFrZSBhbmQgc3RpbGwgYmUgc2VlbiBieSBldmVyeSByZWFkZXI6IGhhbGZcbiAqIHRoZSBsb29rYmFjaywgbGVhdmluZyB0aGUgcmVzdCBmb3Igd3JpdGVycycgY2xvY2tzIGFuZCBldmVudHVhbGx5IGNvbnNpc3RlbnRcbiAqIHF1ZXJpZXMuXG4gKi9cbmNvbnN0IE1BWF9MT0dfUFVUX01TID0gUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyAvIDI7XG5cbi8qKlxuICogSG93IG9mdGVuIGEgcmVmcmVzaCBzY2FucyB0aGUgZW50cnkgc3RvcmVzIGZvciB0aGVpciBvbGRlc3QgZW50cnksIGRyb3BwaW5nXG4gKiB0aGUgZXhwaXJlZCBvbmVzIG5vIHJlcXVlc3QgcmVhZHMgYWdhaW4uXG4gKi9cbmNvbnN0IEVOVFJZX1NDQU5fSU5URVJWQUxfTVMgPSA2MF8wMDA7XG5cbi8qKiBIb3cgb2Z0ZW4gYSByZWZyZXNoIGluIGZsaWdodCBjaGVja3MgdGhlIHByb2Nlc3MgaXMgcnVubmluZy4gKi9cbmNvbnN0IFJFRlJFU0hfVElDS19NUyA9IDI1MDtcblxuLyoqXG4gKiBIb3cgbGF0ZSBhIHRpY2sgbWF5IGNvbWUgYmVmb3JlIHRoZSBwcm9jZXNzIGNvdW50cyBhcyBwYXVzZWQgKGZyb3plbilcbiAqIHNpbmNlIHRoZSByZWZyZXNoIGluIGZsaWdodCBzdGFydGVkLiBBIGJ1c3kgZXZlbnQgbG9vcCBjYW4gZGVsYXkgb25lIHRvbzpcbiAqIHRoZSByZWZyZXNoIHRoZW4gY291bnRzIGFzIG5vIGZyZXNoZXIgdGhhbiBpdHMgc3RhcnQsIGFzIGJlZm9yZSB0aGUgcGF1c2VcbiAqIGNoZWNrLCBzbyBhIHJlcXVlc3Qgd2FpdHMgZm9yIHRoZSBuZXh0IG9uZSBvbmNlIHRoYXQgaXMgcGFzdCB0aGUgZ3JhY2UuXG4gKi9cbmNvbnN0IFJFRlJFU0hfUEFVU0VfTVMgPSAxMDAwO1xuXG4vKipcbiAqIEEgbWFya2VyIGFzIHJlYWQgZnJvbSB0aGUgdGFibGUgb3IgdGhlIGxvZywga2VlcGluZyB3aGF0ZXZlciB0aGlzIGluc3RhbmNlXG4gKiBhbHJlYWR5IGtub3dzIHRoYXQgdGhlIHJlYWQgZG9lcyBub3Qgc2hvdyB5ZXQ6IHJlYWRzIGFyZSBldmVudHVhbGx5XG4gKiBjb25zaXN0ZW50LCBhbmQgYSByZWFkIHN0cmFpZ2h0IGFmdGVyIHRoaXMgaW5zdGFuY2UncyBvd24gcmV2YWxpZGF0aW9uIGNvdWxkXG4gKiBvdGhlcndpc2UgdGFrZSBpdCBiYWNrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VNYXJrZXJzKFxuICBsb2NhbDogVGFnTWFya2VyIHwgdW5kZWZpbmVkLFxuICByZW1vdGU6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCxcbik6IFRhZ01hcmtlciB7XG4gIGlmICghbG9jYWwpIHtcbiAgICByZXR1cm4gcmVtb3RlID8/IHt9O1xuICB9XG4gIGlmICghcmVtb3RlKSB7XG4gICAgcmV0dXJuIGxvY2FsO1xuICB9XG4gIC8vIGBleHBpcmVkQXRgIGlzIHdyaXR0ZW4gd2l0aCBgc3RhbGVBdGAsIHNvIGl0IGJlbG9uZ3MgdG8gd2hpY2hldmVyIGlzXG4gIC8vIG5ld2VyIC0gdW5sZXNzIHRoYXQgcmV2YWxpZGF0aW9uJ3MgcHJvZmlsZSBoYWQgbm8gYGV4cGlyZWAgYW5kIGxlZnQgaXQuXG4gIGNvbnN0IFtvbGRlciwgbmV3ZXJdID1cbiAgICAobG9jYWwuc3RhbGVBdCA/PyAtMSkgPiAocmVtb3RlLnN0YWxlQXQgPz8gLTEpXG4gICAgICA/IFtyZW1vdGUsIGxvY2FsXVxuICAgICAgOiBbbG9jYWwsIHJlbW90ZV07XG4gIHJldHVybiB7XG4gICAgLi4uYXBwbHlNYXJrZXIob2xkZXIsIG5ld2VyKSxcbiAgICByZXZhbGlkYXRlZEF0OiBtYXhEZWZpbmVkKGxvY2FsLnJldmFsaWRhdGVkQXQsIHJlbW90ZS5yZXZhbGlkYXRlZEF0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWF4RGVmaW5lZChhOiBudW1iZXIgfCB1bmRlZmluZWQsIGI6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICBpZiAoYSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gYjtcbiAgaWYgKGIgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGE7XG4gIHJldHVybiBNYXRoLm1heChhLCBiKTtcbn1cblxuLyoqXG4gKiBUaGUgY2FjaGUgYnVja2V0LCBhcyB0aGUgaGFuZGxlcnMgdXNlIGl0OiB3aG9sZSBvYmplY3RzIHJlYWQgYW5kIHdyaXR0ZW4gYXNcbiAqIFVURi04IHRleHQgdW5kZXIgdGhlIGtleXMgYWJvdmUuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYWNoZUJ1Y2tldCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBTM0NsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJ1Y2tldE5hbWU6IHN0cmluZyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBUaGUgYm9keSBvZiB0aGUgb2JqZWN0IGF0IGBrZXlgLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZXJlIGlzIG5vbmUgKGBOb1N1Y2hLZXlgLCBvciBhblxuICAgKiBlbXB0eSByZXNwb25zZSBib2R5KS4gQW55IG90aGVyIGVycm9yIGlzIHRocm93bjogdGhlIGhhbmRsZXJzIGRpc2FncmVlIG9uXG4gICAqIHdoZXRoZXIgb25lIGlzIHdvcnRoIGxvZ2dpbmcuXG4gICAqL1xuICBhc3luYyBnZXQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBHZXRPYmplY3RDb21tYW5kKHsgQnVja2V0OiB0aGlzLmJ1Y2tldE5hbWUsIEtleToga2V5IH0pLFxuICAgICAgKTtcbiAgICAgIGlmICghcmVzcG9uc2UuQm9keSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF3YWl0IHJlc3BvbnNlLkJvZHkudHJhbnNmb3JtVG9TdHJpbmcoXCJ1dGYtOFwiKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm9TdWNoS2V5KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKiogV3JpdGUgYGJvZHlgIGFzIGEgSlNPTiBvYmplY3QgYXQgYGtleWAuICovXG4gIGFzeW5jIHB1dEpzb24oa2V5OiBzdHJpbmcsIGJvZHk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICBuZXcgUHV0T2JqZWN0Q29tbWFuZCh7XG4gICAgICAgIEJ1Y2tldDogdGhpcy5idWNrZXROYW1lLFxuICAgICAgICBLZXk6IGtleSxcbiAgICAgICAgQm9keTogYm9keSxcbiAgICAgICAgQ29udGVudFR5cGU6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOFwiLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxufVxuIl19
|