480 lines
74 KiB
Plaintext
480 lines
74 KiB
Plaintext
import { __assign, __extends } from "/_nuxt/node_modules/tslib/tslib.es6.js?v=e4f18c29";
|
|
import { invariant } from "/_nuxt/node_modules/@apollo/client/utilities/globals/index.js?v=e4f18c29";
|
|
// Make builtins like Map and Set safe to use with non-extensible objects.
|
|
import "/_nuxt/node_modules/@apollo/client/cache/inmemory/fixPolyfills.js?v=e4f18c29";
|
|
import { wrap } from "/_nuxt/node_modules/optimism/lib/index.js?v=e4f18c29";
|
|
import { equal } from "/_nuxt/node_modules/@wry/equality/lib/index.js?v=e4f18c29";
|
|
import { ApolloCache } from "/_nuxt/node_modules/@apollo/client/cache/core/cache.js?v=e4f18c29";
|
|
import { MissingFieldError } from "/_nuxt/node_modules/@apollo/client/cache/core/types/common.js?v=e4f18c29";
|
|
import { addTypenameToDocument, isReference, DocumentTransform, canonicalStringify, print, cacheSizes, } from "/_nuxt/node_modules/@apollo/client/utilities/index.js?v=e4f18c29";
|
|
import { StoreReader } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/readFromStore.js?v=e4f18c29";
|
|
import { StoreWriter } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/writeToStore.js?v=e4f18c29";
|
|
import { EntityStore, supportsResultCaching } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/entityStore.js?v=e4f18c29";
|
|
import { makeVar, forgetCache, recallCache } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/reactiveVars.js?v=e4f18c29";
|
|
import { Policies } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/policies.js?v=e4f18c29";
|
|
import { hasOwn, normalizeConfig, shouldCanonizeResults } from "/_nuxt/node_modules/@apollo/client/cache/inmemory/helpers.js?v=e4f18c29";
|
|
import { getInMemoryCacheMemoryInternals } from "/_nuxt/node_modules/@apollo/client/utilities/caching/getMemoryInternals.js?v=e4f18c29";
|
|
var InMemoryCache = /** @class */ (function (_super) {
|
|
__extends(InMemoryCache, _super);
|
|
function InMemoryCache(config) {
|
|
if (config === void 0) { config = {}; }
|
|
var _this = _super.call(this) || this;
|
|
_this.watches = new Set();
|
|
_this.addTypenameTransform = new DocumentTransform(addTypenameToDocument);
|
|
// Override the default value, since InMemoryCache result objects are frozen
|
|
// in development and expected to remain logically immutable in production.
|
|
_this.assumeImmutableResults = true;
|
|
_this.makeVar = makeVar;
|
|
_this.txCount = 0;
|
|
_this.config = normalizeConfig(config);
|
|
_this.addTypename = !!_this.config.addTypename;
|
|
_this.policies = new Policies({
|
|
cache: _this,
|
|
dataIdFromObject: _this.config.dataIdFromObject,
|
|
possibleTypes: _this.config.possibleTypes,
|
|
typePolicies: _this.config.typePolicies,
|
|
});
|
|
_this.init();
|
|
return _this;
|
|
}
|
|
InMemoryCache.prototype.init = function () {
|
|
// Passing { resultCaching: false } in the InMemoryCache constructor options
|
|
// will completely disable dependency tracking, which will improve memory
|
|
// usage but worsen the performance of repeated reads.
|
|
var rootStore = (this.data = new EntityStore.Root({
|
|
policies: this.policies,
|
|
resultCaching: this.config.resultCaching,
|
|
}));
|
|
// When no optimistic writes are currently active, cache.optimisticData ===
|
|
// cache.data, so there are no additional layers on top of the actual data.
|
|
// When an optimistic update happens, this.optimisticData will become a
|
|
// linked list of EntityStore Layer objects that terminates with the
|
|
// original this.data cache object.
|
|
this.optimisticData = rootStore.stump;
|
|
this.resetResultCache();
|
|
};
|
|
InMemoryCache.prototype.resetResultCache = function (resetResultIdentities) {
|
|
var _this = this;
|
|
var previousReader = this.storeReader;
|
|
var fragments = this.config.fragments;
|
|
// The StoreWriter is mostly stateless and so doesn't really need to be
|
|
// reset, but it does need to have its writer.storeReader reference updated,
|
|
// so it's simpler to update this.storeWriter as well.
|
|
this.storeWriter = new StoreWriter(this, (this.storeReader = new StoreReader({
|
|
cache: this,
|
|
addTypename: this.addTypename,
|
|
resultCacheMaxSize: this.config.resultCacheMaxSize,
|
|
canonizeResults: shouldCanonizeResults(this.config),
|
|
canon: resetResultIdentities ? void 0 : (previousReader && previousReader.canon),
|
|
fragments: fragments,
|
|
})), fragments);
|
|
this.maybeBroadcastWatch = wrap(function (c, options) {
|
|
return _this.broadcastWatch(c, options);
|
|
}, {
|
|
max: this.config.resultCacheMaxSize ||
|
|
cacheSizes["inMemoryCache.maybeBroadcastWatch"] ||
|
|
5000 /* defaultCacheSizes["inMemoryCache.maybeBroadcastWatch"] */,
|
|
makeCacheKey: function (c) {
|
|
// Return a cache key (thus enabling result caching) only if we're
|
|
// currently using a data store that can track cache dependencies.
|
|
var store = c.optimistic ? _this.optimisticData : _this.data;
|
|
if (supportsResultCaching(store)) {
|
|
var optimistic = c.optimistic, id = c.id, variables = c.variables;
|
|
return store.makeCacheKey(c.query,
|
|
// Different watches can have the same query, optimistic
|
|
// status, rootId, and variables, but if their callbacks are
|
|
// different, the (identical) result needs to be delivered to
|
|
// each distinct callback. The easiest way to achieve that
|
|
// separation is to include c.callback in the cache key for
|
|
// maybeBroadcastWatch calls. See issue #5733.
|
|
c.callback, canonicalStringify({ optimistic: optimistic, id: id, variables: variables }));
|
|
}
|
|
},
|
|
});
|
|
// Since we have thrown away all the cached functions that depend on the
|
|
// CacheGroup dependencies maintained by EntityStore, we should also reset
|
|
// all CacheGroup dependency information.
|
|
new Set([this.data.group, this.optimisticData.group]).forEach(function (group) {
|
|
return group.resetCaching();
|
|
});
|
|
};
|
|
InMemoryCache.prototype.restore = function (data) {
|
|
this.init();
|
|
// Since calling this.init() discards/replaces the entire StoreReader, along
|
|
// with the result caches it maintains, this.data.replace(data) won't have
|
|
// to bother deleting the old data.
|
|
if (data)
|
|
this.data.replace(data);
|
|
return this;
|
|
};
|
|
InMemoryCache.prototype.extract = function (optimistic) {
|
|
if (optimistic === void 0) { optimistic = false; }
|
|
return (optimistic ? this.optimisticData : this.data).extract();
|
|
};
|
|
InMemoryCache.prototype.read = function (options) {
|
|
var
|
|
// Since read returns data or null, without any additional metadata
|
|
// about whether/where there might have been missing fields, the
|
|
// default behavior cannot be returnPartialData = true (like it is
|
|
// for the diff method), since defaulting to true would violate the
|
|
// integrity of the T in the return type. However, partial data may
|
|
// be useful in some cases, so returnPartialData:true may be
|
|
// specified explicitly.
|
|
_a = options.returnPartialData,
|
|
// Since read returns data or null, without any additional metadata
|
|
// about whether/where there might have been missing fields, the
|
|
// default behavior cannot be returnPartialData = true (like it is
|
|
// for the diff method), since defaulting to true would violate the
|
|
// integrity of the T in the return type. However, partial data may
|
|
// be useful in some cases, so returnPartialData:true may be
|
|
// specified explicitly.
|
|
returnPartialData = _a === void 0 ? false : _a;
|
|
try {
|
|
return (this.storeReader.diffQueryAgainstStore(__assign(__assign({}, options), { store: options.optimistic ? this.optimisticData : this.data, config: this.config, returnPartialData: returnPartialData })).result || null);
|
|
}
|
|
catch (e) {
|
|
if (e instanceof MissingFieldError) {
|
|
// Swallow MissingFieldError and return null, so callers do not need to
|
|
// worry about catching "normal" exceptions resulting from incomplete
|
|
// cache data. Unexpected errors will be re-thrown. If you need more
|
|
// information about which fields were missing, use cache.diff instead,
|
|
// and examine diffResult.missing.
|
|
return null;
|
|
}
|
|
throw e;
|
|
}
|
|
};
|
|
InMemoryCache.prototype.write = function (options) {
|
|
try {
|
|
++this.txCount;
|
|
return this.storeWriter.writeToStore(this.data, options);
|
|
}
|
|
finally {
|
|
if (!--this.txCount && options.broadcast !== false) {
|
|
this.broadcastWatches();
|
|
}
|
|
}
|
|
};
|
|
InMemoryCache.prototype.modify = function (options) {
|
|
if (hasOwn.call(options, "id") && !options.id) {
|
|
// To my knowledge, TypeScript does not currently provide a way to
|
|
// enforce that an optional property?:type must *not* be undefined
|
|
// when present. That ability would be useful here, because we want
|
|
// options.id to default to ROOT_QUERY only when no options.id was
|
|
// provided. If the caller attempts to pass options.id with a
|
|
// falsy/undefined value (perhaps because cache.identify failed), we
|
|
// should not assume the goal was to modify the ROOT_QUERY object.
|
|
// We could throw, but it seems natural to return false to indicate
|
|
// that nothing was modified.
|
|
return false;
|
|
}
|
|
var store = ((options.optimistic) // Defaults to false.
|
|
) ?
|
|
this.optimisticData
|
|
: this.data;
|
|
try {
|
|
++this.txCount;
|
|
return store.modify(options.id || "ROOT_QUERY", options.fields);
|
|
}
|
|
finally {
|
|
if (!--this.txCount && options.broadcast !== false) {
|
|
this.broadcastWatches();
|
|
}
|
|
}
|
|
};
|
|
InMemoryCache.prototype.diff = function (options) {
|
|
return this.storeReader.diffQueryAgainstStore(__assign(__assign({}, options), { store: options.optimistic ? this.optimisticData : this.data, rootId: options.id || "ROOT_QUERY", config: this.config }));
|
|
};
|
|
InMemoryCache.prototype.watch = function (watch) {
|
|
var _this = this;
|
|
if (!this.watches.size) {
|
|
// In case we previously called forgetCache(this) because
|
|
// this.watches became empty (see below), reattach this cache to any
|
|
// reactive variables on which it previously depended. It might seem
|
|
// paradoxical that we're able to recall something we supposedly
|
|
// forgot, but the point of calling forgetCache(this) is to silence
|
|
// useless broadcasts while this.watches is empty, and to allow the
|
|
// cache to be garbage collected. If, however, we manage to call
|
|
// recallCache(this) here, this cache object must not have been
|
|
// garbage collected yet, and should resume receiving updates from
|
|
// reactive variables, now that it has a watcher to notify.
|
|
recallCache(this);
|
|
}
|
|
this.watches.add(watch);
|
|
if (watch.immediate) {
|
|
this.maybeBroadcastWatch(watch);
|
|
}
|
|
return function () {
|
|
// Once we remove the last watch from this.watches, cache.broadcastWatches
|
|
// no longer does anything, so we preemptively tell the reactive variable
|
|
// system to exclude this cache from future broadcasts.
|
|
if (_this.watches.delete(watch) && !_this.watches.size) {
|
|
forgetCache(_this);
|
|
}
|
|
// Remove this watch from the LRU cache managed by the
|
|
// maybeBroadcastWatch OptimisticWrapperFunction, to prevent memory
|
|
// leaks involving the closure of watch.callback.
|
|
_this.maybeBroadcastWatch.forget(watch);
|
|
};
|
|
};
|
|
InMemoryCache.prototype.gc = function (options) {
|
|
var _a;
|
|
canonicalStringify.reset();
|
|
print.reset();
|
|
this.addTypenameTransform.resetCache();
|
|
(_a = this.config.fragments) === null || _a === void 0 ? void 0 : _a.resetCaches();
|
|
var ids = this.optimisticData.gc();
|
|
if (options && !this.txCount) {
|
|
if (options.resetResultCache) {
|
|
this.resetResultCache(options.resetResultIdentities);
|
|
}
|
|
else if (options.resetResultIdentities) {
|
|
this.storeReader.resetCanon();
|
|
}
|
|
}
|
|
return ids;
|
|
};
|
|
// Call this method to ensure the given root ID remains in the cache after
|
|
// garbage collection, along with its transitive child entities. Note that
|
|
// the cache automatically retains all directly written entities. By default,
|
|
// the retainment persists after optimistic updates are removed. Pass true
|
|
// for the optimistic argument if you would prefer for the retainment to be
|
|
// discarded when the top-most optimistic layer is removed. Returns the
|
|
// resulting (non-negative) retainment count.
|
|
InMemoryCache.prototype.retain = function (rootId, optimistic) {
|
|
return (optimistic ? this.optimisticData : this.data).retain(rootId);
|
|
};
|
|
// Call this method to undo the effect of the retain method, above. Once the
|
|
// retainment count falls to zero, the given ID will no longer be preserved
|
|
// during garbage collection, though it may still be preserved by other safe
|
|
// entities that refer to it. Returns the resulting (non-negative) retainment
|
|
// count, in case that's useful.
|
|
InMemoryCache.prototype.release = function (rootId, optimistic) {
|
|
return (optimistic ? this.optimisticData : this.data).release(rootId);
|
|
};
|
|
// Returns the canonical ID for a given StoreObject, obeying typePolicies
|
|
// and keyFields (and dataIdFromObject, if you still use that). At minimum,
|
|
// the object must contain a __typename and any primary key fields required
|
|
// to identify entities of that type. If you pass a query result object, be
|
|
// sure that none of the primary key fields have been renamed by aliasing.
|
|
// If you pass a Reference object, its __ref ID string will be returned.
|
|
InMemoryCache.prototype.identify = function (object) {
|
|
if (isReference(object))
|
|
return object.__ref;
|
|
try {
|
|
return this.policies.identify(object)[0];
|
|
}
|
|
catch (e) {
|
|
globalThis.__DEV__ !== false && invariant.warn(e);
|
|
}
|
|
};
|
|
InMemoryCache.prototype.evict = function (options) {
|
|
if (!options.id) {
|
|
if (hasOwn.call(options, "id")) {
|
|
// See comment in modify method about why we return false when
|
|
// options.id exists but is falsy/undefined.
|
|
return false;
|
|
}
|
|
options = __assign(__assign({}, options), { id: "ROOT_QUERY" });
|
|
}
|
|
try {
|
|
// It's unlikely that the eviction will end up invoking any other
|
|
// cache update operations while it's running, but {in,de}crementing
|
|
// this.txCount still seems like a good idea, for uniformity with
|
|
// the other update methods.
|
|
++this.txCount;
|
|
// Pass this.data as a limit on the depth of the eviction, so evictions
|
|
// during optimistic updates (when this.data is temporarily set equal to
|
|
// this.optimisticData) do not escape their optimistic Layer.
|
|
return this.optimisticData.evict(options, this.data);
|
|
}
|
|
finally {
|
|
if (!--this.txCount && options.broadcast !== false) {
|
|
this.broadcastWatches();
|
|
}
|
|
}
|
|
};
|
|
InMemoryCache.prototype.reset = function (options) {
|
|
var _this = this;
|
|
this.init();
|
|
canonicalStringify.reset();
|
|
if (options && options.discardWatches) {
|
|
// Similar to what happens in the unsubscribe function returned by
|
|
// cache.watch, applied to all current watches.
|
|
this.watches.forEach(function (watch) { return _this.maybeBroadcastWatch.forget(watch); });
|
|
this.watches.clear();
|
|
forgetCache(this);
|
|
}
|
|
else {
|
|
// Calling this.init() above unblocks all maybeBroadcastWatch caching, so
|
|
// this.broadcastWatches() triggers a broadcast to every current watcher
|
|
// (letting them know their data is now missing). This default behavior is
|
|
// convenient because it means the watches do not have to be manually
|
|
// reestablished after resetting the cache. To prevent this broadcast and
|
|
// cancel all watches, pass true for options.discardWatches.
|
|
this.broadcastWatches();
|
|
}
|
|
return Promise.resolve();
|
|
};
|
|
InMemoryCache.prototype.removeOptimistic = function (idToRemove) {
|
|
var newOptimisticData = this.optimisticData.removeLayer(idToRemove);
|
|
if (newOptimisticData !== this.optimisticData) {
|
|
this.optimisticData = newOptimisticData;
|
|
this.broadcastWatches();
|
|
}
|
|
};
|
|
InMemoryCache.prototype.batch = function (options) {
|
|
var _this = this;
|
|
var update = options.update, _a = options.optimistic, optimistic = _a === void 0 ? true : _a, removeOptimistic = options.removeOptimistic, onWatchUpdated = options.onWatchUpdated;
|
|
var updateResult;
|
|
var perform = function (layer) {
|
|
var _a = _this, data = _a.data, optimisticData = _a.optimisticData;
|
|
++_this.txCount;
|
|
if (layer) {
|
|
_this.data = _this.optimisticData = layer;
|
|
}
|
|
try {
|
|
return (updateResult = update(_this));
|
|
}
|
|
finally {
|
|
--_this.txCount;
|
|
_this.data = data;
|
|
_this.optimisticData = optimisticData;
|
|
}
|
|
};
|
|
var alreadyDirty = new Set();
|
|
if (onWatchUpdated && !this.txCount) {
|
|
// If an options.onWatchUpdated callback is provided, we want to call it
|
|
// with only the Cache.WatchOptions objects affected by options.update,
|
|
// but there might be dirty watchers already waiting to be broadcast that
|
|
// have nothing to do with the update. To prevent including those watchers
|
|
// in the post-update broadcast, we perform this initial broadcast to
|
|
// collect the dirty watchers, so we can re-dirty them later, after the
|
|
// post-update broadcast, allowing them to receive their pending
|
|
// broadcasts the next time broadcastWatches is called, just as they would
|
|
// if we never called cache.batch.
|
|
this.broadcastWatches(__assign(__assign({}, options), { onWatchUpdated: function (watch) {
|
|
alreadyDirty.add(watch);
|
|
return false;
|
|
} }));
|
|
}
|
|
if (typeof optimistic === "string") {
|
|
// Note that there can be multiple layers with the same optimistic ID.
|
|
// When removeOptimistic(id) is called for that id, all matching layers
|
|
// will be removed, and the remaining layers will be reapplied.
|
|
this.optimisticData = this.optimisticData.addLayer(optimistic, perform);
|
|
}
|
|
else if (optimistic === false) {
|
|
// Ensure both this.data and this.optimisticData refer to the root
|
|
// (non-optimistic) layer of the cache during the update. Note that
|
|
// this.data could be a Layer if we are currently executing an optimistic
|
|
// update function, but otherwise will always be an EntityStore.Root
|
|
// instance.
|
|
perform(this.data);
|
|
}
|
|
else {
|
|
// Otherwise, leave this.data and this.optimisticData unchanged and run
|
|
// the update with broadcast batching.
|
|
perform();
|
|
}
|
|
if (typeof removeOptimistic === "string") {
|
|
this.optimisticData = this.optimisticData.removeLayer(removeOptimistic);
|
|
}
|
|
// Note: if this.txCount > 0, then alreadyDirty.size === 0, so this code
|
|
// takes the else branch and calls this.broadcastWatches(options), which
|
|
// does nothing when this.txCount > 0.
|
|
if (onWatchUpdated && alreadyDirty.size) {
|
|
this.broadcastWatches(__assign(__assign({}, options), { onWatchUpdated: function (watch, diff) {
|
|
var result = onWatchUpdated.call(this, watch, diff);
|
|
if (result !== false) {
|
|
// Since onWatchUpdated did not return false, this diff is
|
|
// about to be broadcast to watch.callback, so we don't need
|
|
// to re-dirty it with the other alreadyDirty watches below.
|
|
alreadyDirty.delete(watch);
|
|
}
|
|
return result;
|
|
} }));
|
|
// Silently re-dirty any watches that were already dirty before the update
|
|
// was performed, and were not broadcast just now.
|
|
if (alreadyDirty.size) {
|
|
alreadyDirty.forEach(function (watch) { return _this.maybeBroadcastWatch.dirty(watch); });
|
|
}
|
|
}
|
|
else {
|
|
// If alreadyDirty is empty or we don't have an onWatchUpdated
|
|
// function, we don't need to go to the trouble of wrapping
|
|
// options.onWatchUpdated.
|
|
this.broadcastWatches(options);
|
|
}
|
|
return updateResult;
|
|
};
|
|
InMemoryCache.prototype.performTransaction = function (update, optimisticId) {
|
|
return this.batch({
|
|
update: update,
|
|
optimistic: optimisticId || optimisticId !== null,
|
|
});
|
|
};
|
|
InMemoryCache.prototype.transformDocument = function (document) {
|
|
return this.addTypenameToDocument(this.addFragmentsToDocument(document));
|
|
};
|
|
InMemoryCache.prototype.fragmentMatches = function (fragment, typename) {
|
|
return this.policies.fragmentMatches(fragment, typename);
|
|
};
|
|
InMemoryCache.prototype.lookupFragment = function (fragmentName) {
|
|
var _a;
|
|
return ((_a = this.config.fragments) === null || _a === void 0 ? void 0 : _a.lookup(fragmentName)) || null;
|
|
};
|
|
InMemoryCache.prototype.broadcastWatches = function (options) {
|
|
var _this = this;
|
|
if (!this.txCount) {
|
|
this.watches.forEach(function (c) { return _this.maybeBroadcastWatch(c, options); });
|
|
}
|
|
};
|
|
InMemoryCache.prototype.addFragmentsToDocument = function (document) {
|
|
var fragments = this.config.fragments;
|
|
return fragments ? fragments.transform(document) : document;
|
|
};
|
|
InMemoryCache.prototype.addTypenameToDocument = function (document) {
|
|
if (this.addTypename) {
|
|
return this.addTypenameTransform.transformDocument(document);
|
|
}
|
|
return document;
|
|
};
|
|
// This method is wrapped by maybeBroadcastWatch, which is called by
|
|
// broadcastWatches, so that we compute and broadcast results only when
|
|
// the data that would be broadcast might have changed. It would be
|
|
// simpler to check for changes after recomputing a result but before
|
|
// broadcasting it, but this wrapping approach allows us to skip both
|
|
// the recomputation and the broadcast, in most cases.
|
|
InMemoryCache.prototype.broadcastWatch = function (c, options) {
|
|
var lastDiff = c.lastDiff;
|
|
// Both WatchOptions and DiffOptions extend ReadOptions, and DiffOptions
|
|
// currently requires no additional properties, so we can use c (a
|
|
// WatchOptions object) as DiffOptions, without having to allocate a new
|
|
// object, and without having to enumerate the relevant properties (query,
|
|
// variables, etc.) explicitly. There will be some additional properties
|
|
// (lastDiff, callback, etc.), but cache.diff ignores them.
|
|
var diff = this.diff(c);
|
|
if (options) {
|
|
if (c.optimistic && typeof options.optimistic === "string") {
|
|
diff.fromOptimisticTransaction = true;
|
|
}
|
|
if (options.onWatchUpdated &&
|
|
options.onWatchUpdated.call(this, c, diff, lastDiff) === false) {
|
|
// Returning false from the onWatchUpdated callback will prevent
|
|
// calling c.callback(diff) for this watcher.
|
|
return;
|
|
}
|
|
}
|
|
if (!lastDiff || !equal(lastDiff.result, diff.result)) {
|
|
c.callback((c.lastDiff = diff), lastDiff);
|
|
}
|
|
};
|
|
return InMemoryCache;
|
|
}(ApolloCache));
|
|
export { InMemoryCache };
|
|
if (globalThis.__DEV__ !== false) {
|
|
InMemoryCache.prototype.getMemoryInternals = getInMemoryCacheMemoryInternals;
|
|
}
|
|
|
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5NZW1vcnlDYWNoZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jYWNoZS9pbm1lbW9yeS9pbk1lbW9yeUNhY2hlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFN0QsMEVBQTBFO0FBQzFFLE9BQU8sbUJBQW1CLENBQUM7QUFRM0IsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUNoQyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXRDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUUvQyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUU1RCxPQUFPLEVBQ0wscUJBQXFCLEVBQ3JCLFdBQVcsRUFDWCxpQkFBaUIsRUFDakIsa0JBQWtCLEVBQ2xCLEtBQUssRUFDTCxVQUFVLEdBRVgsTUFBTSwwQkFBMEIsQ0FBQztBQUVsQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDakQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxXQUFXLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLHFCQUFxQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRTlFLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBT2hHO0lBQW1DLGlDQUFrQztJQTZCbkUsdUJBQVksTUFBZ0M7UUFBaEMsdUJBQUEsRUFBQSxXQUFn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Y2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbnZhcmlhbnQgfSBmcm9tIFwiLi4vLi4vdXRpbGl0aWVzL2dsb2JhbHMvaW5kZXguanNcIjtcblxuLy8gTWFrZSBidWlsdGlucyBsaWtlIE1hcCBhbmQgU2V0IHNhZmUgdG8gdXNlIHdpdGggbm9uLWV4dGVuc2libGUgb2JqZWN0cy5cbmltcG9ydCBcIi4vZml4UG9seWZpbGxzLmpzXCI7XG5cbmltcG9ydCB0eXBlIHtcbiAgRG9jdW1lbnROb2RlLFxuICBGcmFnbWVudERlZmluaXRpb25Ob2RlLFxuICBJbmxpbmVGcmFnbWVudE5vZGUsXG59IGZyb20gXCJncmFwaHFsXCI7XG5pbXBvcnQgdHlwZSB7IE9wdGltaXN0aWNXcmFwcGVyRnVuY3Rpb24gfSBmcm9tIFwib3B0aW1pc21cIjtcbmltcG9ydCB7IHdyYXAgfSBmcm9tIFwib3B0aW1pc21cIjtcbmltcG9ydCB7IGVxdWFsIH0gZnJvbSBcIkB3cnkvZXF1YWxpdHlcIjtcblxuaW1wb3J0IHsgQXBvbGxvQ2FjaGUgfSBmcm9tIFwiLi4vY29yZS9jYWNoZS5qc1wiO1xuaW1wb3J0IHR5cGUgeyBDYWNoZSB9IGZyb20gXCIuLi9jb3JlL3R5cGVzL0NhY2hlLmpzXCI7XG5pbXBvcnQgeyBNaXNzaW5nRmllbGRFcnJvciB9IGZyb20gXCIuLi9jb3JlL3R5cGVzL2NvbW1vbi5qc1wiO1xuaW1wb3J0IHR5cGUgeyBTdG9yZU9iamVjdCwgUmVmZXJlbmNlIH0gZnJvbSBcIi4uLy4uL3V0aWxpdGllcy9pbmRleC5qc1wiO1xuaW1wb3J0IHtcbiAgYWRkVHlwZW5hbWVUb0RvY3VtZW50LFxuICBpc1JlZmVyZW5jZSxcbiAgRG9jdW1lbnRUcmFuc2Zvcm0sXG4gIGNhbm9uaWNhbFN0cmluZ2lmeSxcbiAgcHJpbnQsXG4gIGNhY2hlU2l6ZXMsXG4gIGRlZmF1bHRDYWNoZVNpemVzLFxufSBmcm9tIFwiLi4vLi4vdXRpbGl0aWVzL2luZGV4LmpzXCI7XG5pbXBvcnQgdHlwZSB7IEluTWVtb3J5Q2FjaGVDb25maWcsIE5vcm1hbGl6ZWRDYWNoZU9iamVjdCB9IGZyb20gXCIuL3R5cGVzLmpzXCI7XG5pbXBvcnQgeyBTdG9yZVJlYWRlciB9IGZyb20gXCIuL3JlYWRGcm9tU3RvcmUuanNcIjtcbmltcG9ydCB7IFN0b3JlV3JpdGVyIH0gZnJvbSBcIi4vd3JpdGVUb1N0b3JlLmpzXCI7XG5pbXBvcnQgeyBFbnRpdHlTdG9yZSwgc3VwcG9ydHNSZXN1bHRDYWNoaW5nIH0gZnJvbSBcIi4vZW50aXR5U3RvcmUuanNcIjtcbmltcG9ydCB7IG1ha2VWYXIsIGZvcmdldENhY2hlLCByZWNhbGxDYWNoZSB9IGZyb20gXCIuL3JlYWN0aXZlVmFycy5qc1wiO1xuaW1wb3J0IHsgUG9saWNpZXMgfSBmcm9tIFwiLi9wb2xpY2llcy5qc1wiO1xuaW1wb3J0IHsgaGFzT3duLCBub3JtYWxpemVDb25maWcsIHNob3VsZENhbm9uaXplUmVzdWx0cyB9IGZyb20gXCIuL2hlbHBlcnMuanNcIjtcbmltcG9ydCB0eXBlIHsgT3BlcmF0aW9uVmFyaWFibGVzIH0gZnJvbSBcIi4uLy4uL2NvcmUvaW5kZXguanNcIjtcbmltcG9ydCB7IGdldEluTWVtb3J5Q2FjaGVNZW1vcnlJbnRlcm5hbHMgfSBmcm9tIFwiLi4vLi4vdXRpbGl0aWVzL2NhY2hpbmcvZ2V0TWVtb3J5SW50ZXJuYWxzLmpzXCI7XG5cbnR5cGUgQnJvYWRjYXN0T3B0aW9ucyA9IFBpY2s8XG4gIENhY2hlLkJhdGNoT3B0aW9uczxJbk1lbW9yeUNhY2hlPixcbiAgXCJvcHRpbWlzdGljXCIgfCBcIm9uV2F0Y2hVcGRhdGVkXCJcbj47XG5cbmV4cG9ydCBjbGFzcyBJbk1lbW9yeUNhY2hlIGV4dGVuZHMgQXBvbGxvQ2FjaGU8Tm9ybWFsaXplZENhY2hlT2JqZWN0PiB7XG4gIHByaXZhdGUgZGF0YSE6IEVudGl0eVN0b3JlO1xuICBwcml2YXRlIG9wdGltaXN0aWNEYXRhITogRW50aXR5U3RvcmU7XG5cbiAgcHJvdGVjdGVkIGNvbmZpZzogSW5NZW1vcnlDYWNoZUNvbmZpZztcbiAgcHJpdmF0ZSB3YXRjaGVzID0gbmV3IFNldDxDYWNoZS5XYXRjaE9wdGlvbnM+KCk7XG4gIHByaXZhdGUgYWRkVHlwZW5hbWU6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBzdG9yZVJlYWRlciE6IFN0b3JlUmVhZGVyO1xuICBwcml2YXRlIHN0b3JlV3JpdGVyITogU3RvcmVXcml0ZXI7XG4gIHByaXZhdGUgYWRkVHlwZW5hbWVUcmFuc2Zvcm0gPSBuZXcgRG9jdW1lbnRUcmFuc2Zvcm0oYWRkVHlwZW5hbWVUb0RvY3VtZW50KTtcblxuICBwcml2YXRlIG1heWJlQnJvYWRjYXN0V2F0Y2ghOiBPcHRpbWlzdGljV3JhcHBlckZ1bmN0aW9uPFxuICAgIFtDYWNoZS5XYXRjaE9wdGlvbnMsIEJyb2FkY2FzdE9wdGlvbnM/XSxcbiAgICBhbnksXG4gICAgW0NhY2hlLldhdGNoT3B0aW9uc11cbiAgPjtcblxuICAvLyBPdmVycmlkZSB0aGUgZGVmYXVsdCB2YWx1ZSwgc2luY2UgSW5NZW1vcnlDYWNoZSByZXN1bHQgb2JqZWN0cyBhcmUgZnJvemVuXG4gIC8vIGluIGRldmVsb3BtZW50IGFuZCBleHBlY3RlZCB0byByZW1haW4gbG9naWNhbGx5IGltbXV0YWJsZSBpbiBwcm9kdWN0aW9uLlxuICBwdWJsaWMgcmVhZG9ubHkgYXNzdW1lSW1tdXRhYmxlUmVzdWx0cyA9IHRydWU7XG5cbiAgLy8gRHluYW1pY2FsbHkgaW1wb3J0ZWQgY29kZSBjYW4gYXVnbWVudCBleGlzdGluZyB0eXBlUG9saWNpZXMgb3JcbiAgLy8gcG9zc2libGVUeXBlcyBieSBjYWxsaW5nIGNhY2hlLnBvbGljaWVzLmFkZFR5cGVQb2xpY2llcyBvclxuICAvLyBjYWNoZS5wb2xpY2llcy5hZGRQb3NzaWJsZXR5cGVzLlxuICBwdWJsaWMgcmVhZG9ubHkgcG9saWNpZXM6IFBvbGljaWVzO1xuXG4gIHB1YmxpYyByZWFkb25seSBtYWtlVmFyID0gbWFrZVZhcjtcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IEluTWVtb3J5Q2FjaGVDb25maWcgPSB7fSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5jb25maWcgPSBub3JtYWxpemVDb25maWcoY29uZmlnKTtcbiAgICB0aGlzLmFkZFR5cGVuYW1lID0gISF0aGlzLmNvbmZpZy5hZGRUeXBlbmFtZTtcblxuICAgIHRoaXMucG9saWNpZXMgPSBuZXcgUG9saWNpZXMoe1xuICAgICAgY2FjaGU6IHRoaXMsXG4gICAgICBkYXRhSWRGcm9tT2JqZWN0OiB0aGlzLmNvbmZpZy5kYXRhSWRGcm9tT2JqZWN0LFxuICAgICAgcG9zc2libGVUeXBlczogdGhpcy5jb25maWcucG9zc2libGVUeXBlcyxcbiAgICAgIHR5cGVQb2xpY2llczogdGhpcy5jb25maWcudHlwZVBvbGljaWVzLFxuICAgIH0pO1xuXG4gICAgdGhpcy5pbml0KCk7XG4gIH1cblxuICBwcml2YXRlIGluaXQoKSB7XG4gICAgLy8gUGFzc2luZyB7IHJlc3VsdENhY2hpbmc6IGZhbHNlIH0gaW4gdGhlIEluTWVtb3J5Q2FjaGUgY29uc3RydWN0b3Igb3B0aW9uc1xuICAgIC8vIHdpbGwgY29tcGxldGVseSBkaXNhYmxlIGRlcGVuZGVuY3kgdHJhY2tpbmcsIHdoaWNoIHdpbGwgaW1wcm92ZSBtZW1vcnlcbiAgICAvLyB1c2FnZSBidXQgd29yc2VuIHRoZSBwZXJmb3JtYW5jZSBvZiByZXBlYXRlZCByZWFkcy5cbiAgICBjb25zdCByb290U3RvcmUgPSAodGhpcy5kYXRhID0gbmV3IEVudGl0eVN0b3JlLlJvb3Qoe1xuICAgICAgcG9saWNpZXM6IHRoaXMucG9saWNpZXMsXG4gICAgICByZXN1bHRDYWNoaW5nOiB0aGlzLmNvbmZpZy5yZXN1bHRDYWNoaW5nLFxuICAgIH0pKTtcblxuICAgIC8vIFdoZW4gbm8gb3B0aW1pc3RpYyB3cml0ZXMgYXJlIGN1cnJlbnRseSBhY3RpdmUsIGNhY2hlLm9wdGltaXN0aWNEYXRhID09PVxuICAgIC8vIGNhY2hlLmRhdGEsIHNvIHRoZXJlIGFyZSBubyBhZGRpdGlvbmFsIGxheWVycyBvbiB0b3Agb2YgdGhlIGFjdHVhbCBkYXRhLlxuICAgIC8vIFdoZW4gYW4gb3B0aW1pc3RpYyB1cGRhdGUgaGFwcGVucywgdGhpcy5vcHRpbWlzdGljRGF0YSB3aWxsIGJlY29tZSBhXG4gICAgLy8gbGlua2VkIGxpc3Qgb2YgRW50aXR5U3RvcmUgTGF5ZXIgb2JqZWN0cyB0aGF0IHRlcm1pbmF0ZXMgd2l0aCB0aGVcbiAgICAvLyBvcmlnaW5hbCB0aGlzLmRhdGEgY2FjaGUgb2JqZWN0LlxuICAgIHRoaXMub3B0aW1pc3RpY0RhdGEgPSByb290U3RvcmUuc3R1bXA7XG5cbiAgICB0aGlzLnJlc2V0UmVzdWx0Q2FjaGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRSZXN1bHRDYWNoZShyZXNldFJlc3VsdElkZW50aXRpZXM/OiBib29sZWFuKSB7XG4gICAgY29uc3QgcHJldmlvdXNSZWFkZXIgPSB0aGlzLnN0b3JlUmVhZGVyO1xuICAgIGNvbnN0IHsgZnJhZ21lbnRzIH0gPSB0aGlzLmNvbmZpZztcblxuICAgIC8vIFRoZSBTdG9yZVdyaXRlciBpcyBtb3N0bHkgc3RhdGVsZXNzIGFuZCBzbyBkb2Vzbid0IHJlYWxseSBuZWVkIHRvIGJlXG4gICAgLy8gcmVzZXQsIGJ1dCBpdCBkb2VzIG5lZWQgdG8gaGF2ZSBpdHMgd3JpdGVyLnN0b3JlUmVhZGVyIHJlZmVyZW5jZSB1cGRhdGVkLFxuICAgIC8vIHNvIGl0J3Mgc2ltcGxlciB0byB1cGRhdGUgdGhpcy5zdG9yZVdyaXRlciBhcyB3ZWxsLlxuICAgIHRoaXMuc3RvcmVXcml0ZXIgPSBuZXcgU3RvcmVXcml0ZXIoXG4gICAgICB0aGlzLFxuICAgICAgKHRoaXMuc3RvcmVSZWFkZXIgPSBuZXcgU3RvcmVSZWFkZXIoe1xuICAgICAgICBjYWNoZTogdGhpcyxcbiAgICAgICAgYWRkVHlwZW5hbWU6IHRoaXMuYWRkVHlwZW5hbWUsXG4gICAgICAgIHJlc3VsdENhY2hlTWF4U2l6ZTogdGhpcy5jb25maWcucmVzdWx0Q2FjaGVNYXhTaXplLFxuICAgICAgICBjYW5vbml6ZVJlc3VsdHM6IHNob3VsZENhbm9uaXplUmVzdWx0cyh0aGlzLmNvbmZpZyksXG4gICAgICAgIGNhbm9uOlxuICAgICAgICAgIHJlc2V0UmVzdWx0SWRlbnRpdGllcyA/IHZvaWQgMCA6IChcbiAgICAgICAgICAgIHByZXZpb3VzUmVhZGVyICYmIHByZXZpb3VzUmVhZGVyLmNhbm9uXG4gICAgICAgICAgKSxcbiAgICAgICAgZnJhZ21lbnRzLFxuICAgICAgfSkpLFxuICAgICAgZnJhZ21lbnRzXG4gICAgKTtcblxuICAgIHRoaXMubWF5YmVCcm9hZGNhc3RXYXRjaCA9IHdyYXAoXG4gICAgICAoYzogQ2FjaGUuV2F0Y2hPcHRpb25zLCBvcHRpb25zPzogQnJvYWRjYXN0T3B0aW9ucykgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5icm9hZGNhc3RXYXRjaChjLCBvcHRpb25zKTtcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG1heDpcbiAgICAgICAgICB0aGlzLmNvbmZpZy5yZXN1bHRDYWNoZU1heFNpemUgfHxcbiAgICAgICAgICBjYWNoZVNpemVzW1wiaW5NZW1vcnlDYWNoZS5tYXliZUJyb2FkY2FzdFdhdGNoXCJdIHx8XG4gICAgICAgICAgZGVmYXVsdENhY2hlU2l6ZXNbXCJpbk1lbW9yeUNhY2hlLm1heWJlQnJvYWRjYXN0V2F0Y2hcIl0sXG4gICAgICAgIG1ha2VDYWNoZUtleTogKGM6IENhY2hlLldhdGNoT3B0aW9ucykgPT4ge1xuICAgICAgICAgIC8vIFJldHVybiBhIGNhY2hlIGtleSAodGh1cyBlbmFibGluZyByZXN1bHQgY2FjaGluZykgb25seSBpZiB3ZSdyZVxuICAgICAgICAgIC8vIGN1cnJlbnRseSB1c2luZyBhIGRhdGEgc3RvcmUgdGhhdCBjYW4gdHJhY2sgY2FjaGUgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgIGNvbnN0IHN0b3JlID0gYy5vcHRpbWlzdGljID8gdGhpcy5vcHRpbWlzdGljRGF0YSA6IHRoaXMuZGF0YTtcbiAgICAgICAgICBpZiAoc3VwcG9ydHNSZXN1bHRDYWNoaW5nKHN0b3JlKSkge1xuICAgICAgICAgICAgY29uc3QgeyBvcHRpbWlzdGljLCBpZCwgdmFyaWFibGVzIH0gPSBjO1xuICAgICAgICAgICAgcmV0dXJuIHN0b3JlLm1ha2VDYWNoZUtleShcbiAgICAgICAgICAgICAgYy5xdWVyeSxcbiAgICAgICAgICAgICAgLy8gRGlmZmVyZW50IHdhdGNoZXMgY2FuIGhhdmUgdGhlIHNhbWUgcXVlcnksIG9wdGltaXN0aWNcbiAgICAgICAgICAgICAgLy8gc3RhdHVzLCByb290SWQsIGFuZCB2YXJpYWJsZXMsIGJ1dCBpZiB0aGVpciBjYWxsYmFja3MgYXJlXG4gICAgICAgICAgICAgIC8vIGRpZmZlcmVudCwgdGhlIChpZGVudGljYWwpIHJlc3VsdCBuZWVkcyB0byBiZSBkZWxpdmVyZWQgdG9cbiAgICAgICAgICAgICAgLy8gZWFjaCBkaXN0aW5jdCBjYWxsYmFjay4gVGhlIGVhc2llc3Qgd2F5IHRvIGFjaGlldmUgdGhhdFxuICAgICAgICAgICAgICAvLyBzZXBhcmF0aW9uIGlzIHRvIGluY2x1ZGUgYy5jYWxsYmFjayBpbiB0aGUgY2FjaGUga2V5IGZvclxuICAgICAgICAgICAgICAvLyBtYXliZUJyb2FkY2FzdFdhdGNoIGNhbGxzLiBTZWUgaXNzdWUgIzU3MzMuXG4gICAgICAgICAgICAgIGMuY2FsbGJhY2ssXG4gICAgICAgICAgICAgIGNhbm9uaWNhbFN0cmluZ2lmeSh7IG9wdGltaXN0aWMsIGlkLCB2YXJpYWJsZXMgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgfVxuICAgICk7XG5cbiAgICAvLyBTaW5jZSB3ZSBoYXZlIHRocm93biBhd2F5IGFsbCB0aGUgY2FjaGVkIGZ1bmN0aW9ucyB0aGF0IGRlcGVuZCBvbiB0aGVcbiAgICAvLyBDYWNoZUdyb3VwIGRlcGVuZGVuY2llcyBtYWludGFpbmVkIGJ5IEVudGl0eVN0b3JlLCB3ZSBzaG91bGQgYWxzbyByZXNldFxuICAgIC8vIGFsbCBDYWNoZUdyb3VwIGRlcGVuZGVuY3kgaW5mb3JtYXRpb24uXG4gICAgbmV3IFNldChbdGhpcy5kYXRhLmdyb3VwLCB0aGlzLm9wdGltaXN0aWNEYXRhLmdyb3VwXSkuZm9yRWFjaCgoZ3JvdXApID0+XG4gICAgICBncm91cC5yZXNldENhY2hpbmcoKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgcmVzdG9yZShkYXRhOiBOb3JtYWxpemVkQ2FjaGVPYmplY3QpOiB0aGlzIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgICAvLyBTaW5jZSBjYWxsaW5nIHRoaXMuaW5pdCgpIGRpc2NhcmRzL3JlcGxhY2VzIHRoZSBlbnRpcmUgU3RvcmVSZWFkZXIsIGFsb25nXG4gICAgLy8gd2l0aCB0aGUgcmVzdWx0IGNhY2hlcyBpdCBtYWludGFpbnMsIHRoaXMuZGF0YS5yZXBsYWNlKGRhdGEpIHdvbid0IGhhdmVcbiAgICAvLyB0byBib3RoZXIgZGVsZXRpbmcgdGhlIG9sZCBkYXRhLlxuICAgIGlmIChkYXRhKSB0aGlzLmRhdGEucmVwbGFjZShkYXRhKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHB1YmxpYyBleHRyYWN0KG9wdGltaXN0aWM6IGJvb2xlYW4gPSBmYWxzZSk6IE5vcm1hbGl6ZWRDYWNoZU9iamVjdCB7XG4gICAgcmV0dXJuIChvcHRpbWlzdGljID8gdGhpcy5vcHRpbWlzdGljRGF0YSA6IHRoaXMuZGF0YSkuZXh0cmFjdCgpO1xuICB9XG5cbiAgcHVibGljIHJlYWQ8VD4ob3B0aW9uczogQ2FjaGUuUmVhZE9wdGlvbnMpOiBUIHwgbnVsbCB7XG4gICAgY29uc3Qge1xuICAgICAgLy8gU2luY2UgcmVhZCByZXR1cm5zIGRhdGEgb3IgbnVsbCwgd2l0aG91dCBhbnkgYWRkaXRpb25hbCBtZXRhZGF0YVxuICAgICAgLy8gYWJvdXQgd2hldGhlci93aGVyZSB0aGVyZSBtaWdodCBoYXZlIGJlZW4gbWlzc2luZyBmaWVsZHMsIHRoZVxuICAgICAgLy8gZGVmYXVsdCBiZWhhdmlvciBjYW5ub3QgYmUgcmV0dXJuUGFydGlhbERhdGEgPSB0cnVlIChsaWtlIGl0IGlzXG4gICAgICAvLyBmb3IgdGhlIGRpZmYgbWV0aG9kKSwgc2luY2UgZGVmYXVsdGluZyB0byB0cnVlIHdvdWxkIHZpb2xhdGUgdGhlXG4gICAgICAvLyBpbnRlZ3JpdHkgb2YgdGhlIFQgaW4gdGhlIHJldHVybiB0eXBlLiBIb3dldmVyLCBwYXJ0aWFsIGRhdGEgbWF5XG4gICAgICAvLyBiZSB1c2VmdWwgaW4gc29tZSBjYXNlcywgc28gcmV0dXJuUGFydGlhbERhdGE6dHJ1ZSBtYXkgYmVcbiAgICAgIC8vIHNwZWNpZmllZCBleHBsaWNpdGx5LlxuICAgICAgcmV0dXJuUGFydGlhbERhdGEgPSBmYWxzZSxcbiAgICB9ID0gb3B0aW9ucztcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgdGhpcy5zdG9yZVJlYWRlci5kaWZmUXVlcnlBZ2FpbnN0U3RvcmU8VD4oe1xuICAgICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgICAgc3RvcmU6IG9wdGlvbnMub3B0aW1pc3RpYyA/IHRoaXMub3B0aW1pc3RpY0RhdGEgOiB0aGlzLmRhdGEsXG4gICAgICAgICAgY29uZmlnOiB0aGlzLmNvbmZpZyxcbiAgICAgICAgICByZXR1cm5QYXJ0aWFsRGF0YSxcbiAgICAgICAgfSkucmVzdWx0IHx8IG51bGxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBNaXNzaW5nRmllbGRFcnJvcikge1xuICAgICAgICAvLyBTd2FsbG93IE1pc3NpbmdGaWVsZEVycm9yIGFuZCByZXR1cm4gbnVsbCwgc28gY2FsbGVycyBkbyBub3QgbmVlZCB0b1xuICAgICAgICAvLyB3b3JyeSBhYm91dCBjYXRjaGluZyBcIm5vcm1hbFwiIGV4Y2VwdGlvbnMgcmVzdWx0aW5nIGZyb20gaW5jb21wbGV0ZVxuICAgICAgICAvLyBjYWNoZSBkYXRhLiBVbmV4cGVjdGVkIGVycm9ycyB3aWxsIGJlIHJlLXRocm93bi4gSWYgeW91IG5lZWQgbW9yZVxuICAgICAgICAvLyBpbmZvcm1hdGlvbiBhYm91dCB3aGljaCBmaWVsZHMgd2VyZSBtaXNzaW5nLCB1c2UgY2FjaGUuZGlmZiBpbnN0ZWFkLFxuICAgICAgICAvLyBhbmQgZXhhbWluZSBkaWZmUmVzdWx0Lm1pc3NpbmcuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgd3JpdGUob3B0aW9uczogQ2FjaGUuV3JpdGVPcHRpb25zKTogUmVmZXJlbmNlIHwgdW5kZWZpbmVkIHtcbiAgICB0cnkge1xuICAgICAgKyt0aGlzLnR4Q291bnQ7XG4gICAgICByZXR1cm4gdGhpcy5zdG9yZVdyaXRlci53cml0ZVRvU3RvcmUodGhpcy5kYXRhLCBvcHRpb25zKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKCEtLXRoaXMudHhDb3VudCAmJiBvcHRpb25zLmJyb2FkY2FzdCAhPT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5icm9hZGNhc3RXYXRjaGVzKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG1vZGlmeTxFbnRpdHkgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gUmVjb3JkPHN0cmluZywgYW55Pj4oXG4gICAgb3B0aW9uczogQ2FjaGUuTW9kaWZ5T3B0aW9uczxFbnRpdHk+XG4gICk6IGJvb2xlYW4ge1xuICAgIGlmIChoYXNPd24uY2FsbChvcHRpb25zLCBcImlkXCIpICYmICFvcHRpb25zLmlkKSB7XG4gICAgICAvLyBUbyBteSBrbm93bGVkZ2UsIFR5cGVTY3JpcHQgZG9lcyBub3QgY3VycmVudGx5IHByb3ZpZGUgYSB3YXkgdG9cbiAgICAgIC8vIGVuZm9yY2UgdGhhdCBhbiBvcHRpb25hbCBwcm9wZXJ0eT86dHlwZSBtdXN0ICpub3QqIGJlIHVuZGVmaW5lZFxuICAgICAgLy8gd2hlbiBwcmVzZW50LiBUaGF0IGFiaWxpdHkgd291bGQgYmUgdXNlZnVsIGhlcmUsIGJlY2F1c2Ugd2Ugd2FudFxuICAgICAgLy8gb3B0aW9ucy5pZCB0byBkZWZhdWx0IHRvIFJPT1RfUVVFUlkgb25seSB3aGVuIG5vIG9wdGlvbnMuaWQgd2FzXG4gICAgICAvLyBwcm92aWRlZC4gSWYgdGhlIGNhbGxlciBhdHRlbXB0cyB0byBwYXNzIG9wdGlvbnMuaWQgd2l0aCBhXG4gICAgICAvLyBmYWxzeS91bmRlZmluZWQgdmFsdWUgKHBlcmhhcHMgYmVjYXVzZSBjYWNoZS5pZGVudGlmeSBmYWlsZWQpLCB3ZVxuICAgICAgLy8gc2hvdWxkIG5vdCBhc3N1bWUgdGhlIGdvYWwgd2FzIHRvIG1vZGlmeSB0aGUgUk9PVF9RVUVSWSBvYmplY3QuXG4gICAgICAvLyBXZSBjb3VsZCB0aHJvdywgYnV0IGl0IHNlZW1zIG5hdHVyYWwgdG8gcmV0dXJuIGZhbHNlIHRvIGluZGljYXRlXG4gICAgICAvLyB0aGF0IG5vdGhpbmcgd2FzIG1vZGlmaWVkLlxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBzdG9yZSA9XG4gICAgICAoXG4gICAgICAgIG9wdGlvbnMub3B0aW1pc3RpYyAvLyBEZWZhdWx0cyB0byBmYWxzZS5cbiAgICAgICkgP1xuICAgICAgICB0aGlzLm9wdGltaXN0aWNEYXRhXG4gICAgICA6IHRoaXMuZGF0YTtcbiAgICB0cnkge1xuICAgICAgKyt0aGlzLnR4Q291bnQ7XG4gICAgICByZXR1cm4gc3RvcmUubW9kaWZ5KG9wdGlvbnMuaWQgfHwgXCJST09UX1FVRVJZXCIsIG9wdGlvbnMuZmllbGRzKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKCEtLXRoaXMudHhDb3VudCAmJiBvcHRpb25zLmJyb2FkY2FzdCAhPT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5icm9hZGNhc3RXYXRjaGVzKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGRpZmY8VERhdGEsIFRWYXJpYWJsZXMgZXh0ZW5kcyBPcGVyYXRpb25WYXJpYWJsZXMgPSBhbnk+KFxuICAgIG9wdGlvbnM6IENhY2hlLkRpZmZPcHRpb25zPFREYXRhLCBUVmFyaWFibGVzPlxuICApOiBDYWNoZS5EaWZmUmVzdWx0PFREYXRhPiB7XG4gICAgcmV0dXJuIHRoaXMuc3RvcmVSZWFkZXIuZGlmZlF1ZXJ5QWdhaW5zdFN0b3JlKHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBzdG9yZTogb3B0aW9ucy5vcHRpbWlzdGljID8gdGhpcy5vcHRpbWlzdGljRGF0YSA6IHRoaXMuZGF0YSxcbiAgICAgIHJvb3RJZDogb3B0aW9ucy5pZCB8fCBcIlJPT1RfUVVFUllcIixcbiAgICAgIGNvbmZpZzogdGhpcy5jb25maWcsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgd2F0Y2g8VERhdGEgPSBhbnksIFRWYXJpYWJsZXMgPSBhbnk+KFxuICAgIHdhdGNoOiBDYWNoZS5XYXRjaE9wdGlvbnM8VERhdGEsIFRWYXJpYWJsZXM+XG4gICk6ICgpID0+IHZvaWQge1xuICAgIGlmICghdGhpcy53YXRjaGVzLnNpemUpIHtcbiAgICAgIC8vIEluIGNhc2Ugd2UgcHJldmlvdXNseSBjYWxsZWQgZm9yZ2V0Q2FjaGUodGhpcykgYmVjYXVzZVxuICAgICAgLy8gdGhpcy53YXRjaGVzIGJlY2FtZSBlbXB0eSAoc2VlIGJlbG93KSwgcmVhdHRhY2ggdGhpcyBjYWNoZSB0byBhbnlcbiAgICAgIC8vIHJlYWN0aXZlIHZhcmlhYmxlcyBvbiB3aGljaCBpdCBwcmV2aW91c2x5IGRlcGVuZGVkLiBJdCBtaWdodCBzZWVtXG4gICAgICAvLyBwYXJhZG94aWNhbCB0aGF0IHdlJ3JlIGFibGUgdG8gcmVjYWxsIHNvbWV0aGluZyB3ZSBzdXBwb3NlZGx5XG4gICAgICAvLyBmb3Jnb3QsIGJ1dCB0aGUgcG9pbnQgb2YgY2FsbGluZyBmb3JnZXRDYWNoZSh0aGlzKSBpcyB0byBzaWxlbmNlXG4gICAgICAvLyB1c2VsZXNzIGJyb2FkY2FzdHMgd2hpbGUgdGhpcy53YXRjaGVzIGlzIGVtcHR5LCBhbmQgdG8gYWxsb3cgdGhlXG4gICAgICAvLyBjYWNoZSB0byBiZSBnYXJiYWdlIGNvbGxlY3RlZC4gSWYsIGhvd2V2ZXIsIHdlIG1hbmFnZSB0byBjYWxsXG4gICAgICAvLyByZWNhbGxDYWNoZSh0aGlzKSBoZXJlLCB0aGlzIGNhY2hlIG9iamVjdCBtdXN0IG5vdCBoYXZlIGJlZW5cbiAgICAgIC8vIGdhcmJhZ2UgY29sbGVjdGVkIHlldCwgYW5kIHNob3VsZCByZXN1bWUgcmVjZWl2aW5nIHVwZGF0ZXMgZnJvbVxuICAgICAgLy8gcmVhY3RpdmUgdmFyaWFibGVzLCBub3cgdGhhdCBpdCBoYXMgYSB3YXRjaGVyIHRvIG5vdGlmeS5cbiAgICAgIHJlY2FsbENhY2hlKHRoaXMpO1xuICAgIH1cbiAgICB0aGlzLndhdGNoZXMuYWRkKHdhdGNoKTtcbiAgICBpZiAod2F0Y2guaW1tZWRpYXRlKSB7XG4gICAgICB0aGlzLm1heWJlQnJvYWRjYXN0V2F0Y2god2F0Y2gpO1xuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgLy8gT25jZSB3ZSByZW1vdmUgdGhlIGxhc3Qgd2F0Y2ggZnJvbSB0aGlzLndhdGNoZXMsIGNhY2hlLmJyb2FkY2FzdFdhdGNoZXNcbiAgICAgIC8vIG5vIGxvbmdlciBkb2VzIGFueXRoaW5nLCBzbyB3ZSBwcmVlbXB0aXZlbHkgdGVsbCB0aGUgcmVhY3RpdmUgdmFyaWFibGVcbiAgICAgIC8vIHN5c3RlbSB0byBleGNsdWRlIHRoaXMgY2FjaGUgZnJvbSBmdXR1cmUgYnJvYWRjYXN0cy5cbiAgICAgIGlmICh0aGlzLndhdGNoZXMuZGVsZXRlKHdhdGNoKSAmJiAhdGhpcy53YXRjaGVzLnNpemUpIHtcbiAgICAgICAgZm9yZ2V0Q2FjaGUodGhpcyk7XG4gICAgICB9XG4gICAgICAvLyBSZW1vdmUgdGhpcyB3YXRjaCBmcm9tIHRoZSBMUlUgY2FjaGUgbWFuYWdlZCBieSB0aGVcbiAgICAgIC8vIG1heWJlQnJvYWRjYXN0V2F0Y2ggT3B0aW1pc3RpY1dyYXBwZXJGdW5jdGlvbiwgdG8gcHJldmVudCBtZW1vcnlcbiAgICAgIC8vIGxlYWtzIGludm9sdmluZyB0aGUgY2xvc3VyZSBvZiB3YXRjaC5jYWxsYmFjay5cbiAgICAgIHRoaXMubWF5YmVCcm9hZGNhc3RXYXRjaC5mb3JnZXQod2F0Y2gpO1xuICAgIH07XG4gIH1cblxuICBwdWJsaWMgZ2Mob3B0aW9ucz86IHtcbiAgICAvLyBJZiB0cnVlLCBhbHNvIGZyZWUgbm9uLWVzc2VudGlhbCByZXN1bHQgY2FjaGUgbWVtb3J5IGJ5IGJ1bGstcmVsZWFzaW5nXG4gICAgLy8gdGhpcy57c3RvcmV7UmVhZGVyLFdyaXRlcn0sbWF5YmVCcm9hZGNhc3RXYXRjaH0uIERlZmF1bHRzIHRvIGZhbHNlLlxuICAgIHJlc2V0UmVzdWx0Q2FjaGU/OiBib29sZWFuO1xuICAgIC8vIElmIHJlc2V0UmVzdWx0Q2FjaGUgaXMgdHJ1ZSwgdGhpcy5zdG9yZVJlYWRlci5jYW5vbiB3aWxsIGJlIHByZXNlcnZlZCBieVxuICAgIC8vIGRlZmF1bHQsIGJ1dCBjYW4gYWxzbyBiZSBkaXNjYXJkZWQgYnkgcGFzc2luZyByZXNldFJlc3VsdElkZW50aXRpZXM6dHJ1ZS5cbiAgICAvLyBEZWZhdWx0cyB0byBmYWxzZS5cbiAgICByZXNldFJlc3VsdElkZW50aXRpZXM/OiBib29sZWFuO1xuICB9KSB7XG4gICAgY2Fub25pY2FsU3RyaW5naWZ5LnJlc2V0KCk7XG4gICAgcHJpbnQucmVzZXQoKTtcbiAgICB0aGlzLmFkZFR5cGVuYW1lVHJhbnNmb3JtLnJlc2V0Q2FjaGUoKTtcbiAgICB0aGlzLmNvbmZpZy5mcmFnbWVudHM/LnJlc2V0Q2FjaGVzKCk7XG4gICAgY29uc3QgaWRzID0gdGhpcy5vcHRpbWlzdGljRGF0YS5nYygpO1xuICAgIGlmIChvcHRpb25zICYmICF0aGlzLnR4Q291bnQpIHtcbiAgICAgIGlmIChvcHRpb25zLnJlc2V0UmVzdWx0Q2FjaGUpIHtcbiAgICAgICAgdGhpcy5yZXNldFJlc3VsdENhY2hlKG9wdGlvbnMucmVzZXRSZXN1bHRJZGVudGl0aWVzKTtcbiAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5yZXNldFJlc3VsdElkZW50aXRpZXMpIHtcbiAgICAgICAgdGhpcy5zdG9yZVJlYWRlci5yZXNldENhbm9uKCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBpZHM7XG4gIH1cblxuICAvLyBDYWxsIHRoaXMgbWV0aG9kIHRvIGVuc3VyZSB0aGUgZ2l2ZW4gcm9vdCBJRCByZW1haW5zIGluIHRoZSBjYWNoZSBhZnRlclxuICAvLyBnYXJiYWdlIGNvbGxlY3Rpb24sIGFsb25nIHdpdGggaXRzIHRyYW5zaXRpdmUgY2hpbGQgZW50aXRpZXMuIE5vdGUgdGhhdFxuICAvLyB0aGUgY2FjaGUgYXV0b21hdGljYWxseSByZXRhaW5zIGFsbCBkaXJlY3RseSB3cml0dGVuIGVudGl0aWVzLiBCeSBkZWZhdWx0LFxuICAvLyB0aGUgcmV0YWlubWVudCBwZXJzaXN0cyBhZnRlciBvcHRpbWlzdGljIHVwZGF0ZXMgYXJlIHJlbW92ZWQuIFBhc3MgdHJ1ZVxuICAvLyBmb3IgdGhlIG9wdGltaXN0aWMgYXJndW1lbnQgaWYgeW91IHdvdWxkIHByZWZlciBmb3IgdGhlIHJldGFpbm1lbnQgdG8gYmVcbiAgLy8gZGlzY2FyZGVkIHdoZW4gdGhlIHRvcC1tb3N0IG9wdGltaXN0aWMgbGF5ZXIgaXMgcmVtb3ZlZC4gUmV0dXJucyB0aGVcbiAgLy8gcmVzdWx0aW5nIChub24tbmVnYXRpdmUpIHJldGFpbm1lbnQgY291bnQuXG4gIHB1YmxpYyByZXRhaW4ocm9vdElkOiBzdHJpbmcsIG9wdGltaXN0aWM/OiBib29sZWFuKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKG9wdGltaXN0aWMgPyB0aGlzLm9wdGltaXN0aWNEYXRhIDogdGhpcy5kYXRhKS5yZXRhaW4ocm9vdElkKTtcbiAgfVxuXG4gIC8vIENhbGwgdGhpcyBtZXRob2QgdG8gdW5kbyB0aGUgZWZmZWN0IG9mIHRoZSByZXRhaW4gbWV0aG9kLCBhYm92ZS4gT25jZSB0aGVcbiAgLy8gcmV0YWlubWVudCBjb3VudCBmYWxscyB0byB6ZXJvLCB0aGUgZ2l2ZW4gSUQgd2lsbCBubyBsb25nZXIgYmUgcHJlc2VydmVkXG4gIC8vIGR1cmluZyBnYXJiYWdlIGNvbGxlY3Rpb24sIHRob3VnaCBpdCBtYXkgc3RpbGwgYmUgcHJlc2VydmVkIGJ5IG90aGVyIHNhZmVcbiAgLy8gZW50aXRpZXMgdGhhdCByZWZlciB0byBpdC4gUmV0dXJucyB0aGUgcmVzdWx0aW5nIChub24tbmVnYXRpdmUpIHJldGFpbm1lbnRcbiAgLy8gY291bnQsIGluIGNhc2UgdGhhdCdzIHVzZWZ1bC5cbiAgcHVibGljIHJlbGVhc2Uocm9vdElkOiBzdHJpbmcsIG9wdGltaXN0aWM/OiBib29sZWFuKTogbnVtYmVyIHtcbiAgICByZXR1cm4gKG9wdGltaXN0aWMgPyB0aGlzLm9wdGltaXN0aWNEYXRhIDogdGhpcy5kYXRhKS5yZWxlYXNlKHJvb3RJZCk7XG4gIH1cblxuICAvLyBSZXR1cm5zIHRoZSBjYW5vbmljYWwgSUQgZm9yIGEgZ2l2ZW4gU3RvcmVPYmplY3QsIG9iZXlpbmcgdHlwZVBvbGljaWVzXG4gIC8vIGFuZCBrZXlGaWVsZHMgKGFuZCBkYXRhSWRGcm9tT2JqZWN0LCBpZiB5b3Ugc3RpbGwgdXNlIHRoYXQpLiBBdCBtaW5pbXVtLFxuICAvLyB0aGUgb2JqZWN0IG11c3QgY29udGFpbiBhIF9fdHlwZW5hbWUgYW5kIGFueSBwcmltYXJ5IGtleSBmaWVsZHMgcmVxdWlyZWRcbiAgLy8gdG8gaWRlbnRpZnkgZW50aXRpZXMgb2YgdGhhdCB0eXBlLiBJZiB5b3UgcGFzcyBhIHF1ZXJ5IHJlc3VsdCBvYmplY3QsIGJlXG4gIC8vIHN1cmUgdGhhdCBub25lIG9mIHRoZSBwcmltYXJ5IGtleSBmaWVsZHMgaGF2ZSBiZWVuIHJlbmFtZWQgYnkgYWxpYXNpbmcuXG4gIC8vIElmIHlvdSBwYXNzIGEgUmVmZXJlbmNlIG9iamVjdCwgaXRzIF9fcmVmIElEIHN0cmluZyB3aWxsIGJlIHJldHVybmVkLlxuICBwdWJsaWMgaWRlbnRpZnkob2JqZWN0OiBTdG9yZU9iamVjdCB8IFJlZmVyZW5jZSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKGlzUmVmZXJlbmNlKG9iamVjdCkpIHJldHVybiBvYmplY3QuX19yZWY7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLnBvbGljaWVzLmlkZW50aWZ5KG9iamVjdClbMF07XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaW52YXJpYW50Lndhcm4oZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGV2aWN0KG9wdGlvbnM6IENhY2hlLkV2aWN0T3B0aW9ucyk6IGJvb2xlYW4ge1xuICAgIGlmICghb3B0aW9ucy5pZCkge1xuICAgICAgaWYgKGhhc093bi5jYWxsKG9wdGlvbnMsIFwiaWRcIikpIHtcbiAgICAgICAgLy8gU2VlIGNvbW1lbnQgaW4gbW9kaWZ5IG1ldGhvZCBhYm91dCB3aHkgd2UgcmV0dXJuIGZhbHNlIHdoZW5cbiAgICAgICAgLy8gb3B0aW9ucy5pZCBleGlzdHMgYnV0IGlzIGZhbHN5L3VuZGVmaW5lZC5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgb3B0aW9ucyA9IHsgLi4ub3B0aW9ucywgaWQ6IFwiUk9PVF9RVUVSWVwiIH07XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAvLyBJdCdzIHVubGlrZWx5IHRoYXQgdGhlIGV2aWN0aW9uIHdpbGwgZW5kIHVwIGludm9raW5nIGFueSBvdGhlclxuICAgICAgLy8gY2FjaGUgdXBkYXRlIG9wZXJhdGlvbnMgd2hpbGUgaXQncyBydW5uaW5nLCBidXQge2luLGRlfWNyZW1lbnRpbmdcbiAgICAgIC8vIHRoaXMudHhDb3VudCBzdGlsbCBzZWVtcyBsaWtlIGEgZ29vZCBpZGVhLCBmb3IgdW5pZm9ybWl0eSB3aXRoXG4gICAgICAvLyB0aGUgb3RoZXIgdXBkYXRlIG1ldGhvZHMuXG4gICAgICArK3RoaXMudHhDb3VudDtcbiAgICAgIC8vIFBhc3MgdGhpcy5kYXRhIGFzIGEgbGltaXQgb24gdGhlIGRlcHRoIG9mIHRoZSBldmljdGlvbiwgc28gZXZpY3Rpb25zXG4gICAgICAvLyBkdXJpbmcgb3B0aW1pc3RpYyB1cGRhdGVzICh3aGVuIHRoaXMuZGF0YSBpcyB0ZW1wb3JhcmlseSBzZXQgZXF1YWwgdG9cbiAgICAgIC8vIHRoaXMub3B0aW1pc3RpY0RhdGEpIGRvIG5vdCBlc2NhcGUgdGhlaXIgb3B0aW1pc3RpYyBMYXllci5cbiAgICAgIHJldHVybiB0aGlzLm9wdGltaXN0aWNEYXRhLmV2aWN0KG9wdGlvbnMsIHRoaXMuZGF0YSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmICghLS10aGlzLnR4Q291bnQgJiYgb3B0aW9ucy5icm9hZGNhc3QgIT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuYnJvYWRjYXN0V2F0Y2hlcygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZXNldChvcHRpb25zPzogQ2FjaGUuUmVzZXRPcHRpb25zKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5pbml0KCk7XG5cbiAgICBjYW5vbmljYWxTdHJpbmdpZnkucmVzZXQoKTtcblxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuZGlzY2FyZFdhdGNoZXMpIHtcbiAgICAgIC8vIFNpbWlsYXIgdG8gd2hhdCBoYXBwZW5zIGluIHRoZSB1bnN1YnNjcmliZSBmdW5jdGlvbiByZXR1cm5lZCBieVxuICAgICAgLy8gY2FjaGUud2F0Y2gsIGFwcGxpZWQgdG8gYWxsIGN1cnJlbnQgd2F0Y2hlcy5cbiAgICAgIHRoaXMud2F0Y2hlcy5mb3JFYWNoKCh3YXRjaCkgPT4gdGhpcy5tYXliZUJyb2FkY2FzdFdhdGNoLmZvcmdldCh3YXRjaCkpO1xuICAgICAgdGhpcy53YXRjaGVzLmNsZWFyKCk7XG4gICAgICBmb3JnZXRDYWNoZSh0aGlzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ2FsbGluZyB0aGlzLmluaXQoKSBhYm92ZSB1bmJsb2NrcyBhbGwgbWF5YmVCcm9hZGNhc3RXYXRjaCBjYWNoaW5nLCBzb1xuICAgICAgLy8gdGhpcy5icm9hZGNhc3RXYXRjaGVzKCkgdHJpZ2dlcnMgYSBicm9hZGNhc3QgdG8gZXZlcnkgY3VycmVudCB3YXRjaGVyXG4gICAgICAvLyAobGV0dGluZyB0aGVtIGtub3cgdGhlaXIgZGF0YSBpcyBub3cgbWlzc2luZykuIFRoaXMgZGVmYXVsdCBiZWhhdmlvciBpc1xuICAgICAgLy8gY29udmVuaWVudCBiZWNhdXNlIGl0IG1lYW5zIHRoZSB3YXRjaGVzIGRvIG5vdCBoYXZlIHRvIGJlIG1hbnVhbGx5XG4gICAgICAvLyByZWVzdGFibGlzaGVkIGFmdGVyIHJlc2V0dGluZyB0aGUgY2FjaGUuIFRvIHByZXZlbnQgdGhpcyBicm9hZGNhc3QgYW5kXG4gICAgICAvLyBjYW5jZWwgYWxsIHdhdGNoZXMsIHBhc3MgdHJ1ZSBmb3Igb3B0aW9ucy5kaXNjYXJkV2F0Y2hlcy5cbiAgICAgIHRoaXMuYnJvYWRjYXN0V2F0Y2hlcygpO1xuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIHB1YmxpYyByZW1vdmVPcHRpbWlzdGljKGlkVG9SZW1vdmU6IHN0cmluZykge1xuICAgIGNvbnN0IG5ld09wdGltaXN0aWNEYXRhID0gdGhpcy5vcHRpbWlzdGljRGF0YS5yZW1vdmVMYXllcihpZFRvUmVtb3ZlKTtcbiAgICBpZiAobmV3T3B0aW1pc3RpY0RhdGEgIT09IHRoaXMub3B0aW1pc3RpY0RhdGEpIHtcbiAgICAgIHRoaXMub3B0aW1pc3RpY0RhdGEgPSBuZXdPcHRpbWlzdGljRGF0YTtcbiAgICAgIHRoaXMuYnJvYWRjYXN0V2F0Y2hlcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdHhDb3VudCA9IDA7XG5cbiAgcHVibGljIGJhdGNoPFRVcGRhdGVSZXN1bHQ+KFxuICAgIG9wdGlvbnM6IENhY2hlLkJhdGNoT3B0aW9uczxJbk1lbW9yeUNhY2hlLCBUVXBkYXRlUmVzdWx0PlxuICApOiBUVXBkYXRlUmVzdWx0IHtcbiAgICBjb25zdCB7XG4gICAgICB1cGRhdGUsXG4gICAgICBvcHRpbWlzdGljID0gdHJ1ZSxcbiAgICAgIHJlbW92ZU9wdGltaXN0aWMsXG4gICAgICBvbldhdGNoVXBkYXRlZCxcbiAgICB9ID0gb3B0aW9ucztcblxuICAgIGxldCB1cGRhdGVSZXN1bHQ6IFRVcGRhdGVSZXN1bHQ7XG4gICAgY29uc3QgcGVyZm9ybSA9IChsYXllcj86IEVudGl0eVN0b3JlKTogVFVwZGF0ZVJlc3VsdCA9PiB7XG4gICAgICBjb25zdCB7IGRhdGEsIG9wdGltaXN0aWNEYXRhIH0gPSB0aGlzO1xuICAgICAgKyt0aGlzLnR4Q291bnQ7XG4gICAgICBpZiAobGF5ZXIpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gdGhpcy5vcHRpbWlzdGljRGF0YSA9IGxheWVyO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuICh1cGRhdGVSZXN1bHQgPSB1cGRhdGUodGhpcykpO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgLS10aGlzLnR4Q291bnQ7XG4gICAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMub3B0aW1pc3RpY0RhdGEgPSBvcHRpbWlzdGljRGF0YTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgYWxyZWFkeURpcnR5ID0gbmV3IFNldDxDYWNoZS5XYXRjaE9wdGlvbnM+KCk7XG5cbiAgICBpZiAob25XYXRjaFVwZGF0ZWQgJiYgIXRoaXMudHhDb3VudCkge1xuICAgICAgLy8gSWYgYW4gb3B0aW9ucy5vbldhdGNoVXBkYXRlZCBjYWxsYmFjayBpcyBwcm92aWRlZCwgd2Ugd2FudCB0byBjYWxsIGl0XG4gICAgICAvLyB3aXRoIG9ubHkgdGhlIENhY2hlLldhdGNoT3B0aW9ucyBvYmplY3RzIGFmZmVjdGVkIGJ5IG9wdGlvbnMudXBkYXRlLFxuICAgICAgLy8gYnV0IHRoZXJlIG1pZ2h0IGJlIGRpcnR5IHdhdGNoZXJzIGFscmVhZHkgd2FpdGluZyB0byBiZSBicm9hZGNhc3QgdGhhdFxuICAgICAgLy8gaGF2ZSBub3RoaW5nIHRvIGRvIHdpdGggdGhlIHVwZGF0ZS4gVG8gcHJldmVudCBpbmNsdWRpbmcgdGhvc2Ugd2F0Y2hlcnNcbiAgICAgIC8vIGluIHRoZSBwb3N0LXVwZGF0ZSBicm9hZGNhc3QsIHdlIHBlcmZvcm0gdGhpcyBpbml0aWFsIGJyb2FkY2FzdCB0b1xuICAgICAgLy8gY29sbGVjdCB0aGUgZGlydHkgd2F0Y2hlcnMsIHNvIHdlIGNhbiByZS1kaXJ0eSB0aGVtIGxhdGVyLCBhZnRlciB0aGVcbiAgICAgIC8vIHBvc3QtdXBkYXRlIGJyb2FkY2FzdCwgYWxsb3dpbmcgdGhlbSB0byByZWNlaXZlIHRoZWlyIHBlbmRpbmdcbiAgICAgIC8vIGJyb2FkY2FzdHMgdGhlIG5leHQgdGltZSBicm9hZGNhc3RXYXRjaGVzIGlzIGNhbGxlZCwganVzdCBhcyB0aGV5IHdvdWxkXG4gICAgICAvLyBpZiB3ZSBuZXZlciBjYWxsZWQgY2FjaGUuYmF0Y2guXG4gICAgICB0aGlzLmJyb2FkY2FzdFdhdGNoZXMoe1xuICAgICAgICAuLi5vcHRpb25zLFxuICAgICAgICBvbldhdGNoVXBkYXRlZCh3YXRjaCkge1xuICAgICAgICAgIGFscmVhZHlEaXJ0eS5hZGQod2F0Y2gpO1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb3B0aW1pc3RpYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgLy8gTm90ZSB0aGF0IHRoZXJlIGNhbiBiZSBtdWx0aXBsZSBsYXllcnMgd2l0aCB0aGUgc2FtZSBvcHRpbWlzdGljIElELlxuICAgICAgLy8gV2hlbiByZW1vdmVPcHRpbWlzdGljKGlkKSBpcyBjYWxsZWQgZm9yIHRoYXQgaWQsIGFsbCBtYXRjaGluZyBsYXllcnNcbiAgICAgIC8vIHdpbGwgYmUgcmVtb3ZlZCwgYW5kIHRoZSByZW1haW5pbmcgbGF5ZXJzIHdpbGwgYmUgcmVhcHBsaWVkLlxuICAgICAgdGhpcy5vcHRpbWlzdGljRGF0YSA9IHRoaXMub3B0aW1pc3RpY0RhdGEuYWRkTGF5ZXIob3B0aW1pc3RpYywgcGVyZm9ybSk7XG4gICAgfSBlbHNlIGlmIChvcHRpbWlzdGljID09PSBmYWxzZSkge1xuICAgICAgLy8gRW5zdXJlIGJvdGggdGhpcy5kYXRhIGFuZCB0aGlzLm9wdGltaXN0aWNEYXRhIHJlZmVyIHRvIHRoZSByb290XG4gICAgICAvLyAobm9uLW9wdGltaXN0aWMpIGxheWVyIG9mIHRoZSBjYWNoZSBkdXJpbmcgdGhlIHVwZGF0ZS4gTm90ZSB0aGF0XG4gICAgICAvLyB0aGlzLmRhdGEgY291bGQgYmUgYSBMYXllciBpZiB3ZSBhcmUgY3VycmVudGx5IGV4ZWN1dGluZyBhbiBvcHRpbWlzdGljXG4gICAgICAvLyB1cGRhdGUgZnVuY3Rpb24sIGJ1dCBvdGhlcndpc2Ugd2lsbCBhbHdheXMgYmUgYW4gRW50aXR5U3RvcmUuUm9vdFxuICAgICAgLy8gaW5zdGFuY2UuXG4gICAgICBwZXJmb3JtKHRoaXMuZGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIE90aGVyd2lzZSwgbGVhdmUgdGhpcy5kYXRhIGFuZCB0aGlzLm9wdGltaXN0aWNEYXRhIHVuY2hhbmdlZCBhbmQgcnVuXG4gICAgICAvLyB0aGUgdXBkYXRlIHdpdGggYnJvYWRjYXN0IGJhdGNoaW5nLlxuICAgICAgcGVyZm9ybSgpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgcmVtb3ZlT3B0aW1pc3RpYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhpcy5vcHRpbWlzdGljRGF0YSA9IHRoaXMub3B0aW1pc3RpY0RhdGEucmVtb3ZlTGF5ZXIocmVtb3ZlT3B0aW1pc3RpYyk7XG4gICAgfVxuXG4gICAgLy8gTm90ZTogaWYgdGhpcy50eENvdW50ID4gMCwgdGhlbiBhbHJlYWR5RGlydHkuc2l6ZSA9PT0gMCwgc28gdGhpcyBjb2RlXG4gICAgLy8gdGFrZXMgdGhlIGVsc2UgYnJhbmNoIGFuZCBjYWxscyB0aGlzLmJyb2FkY2FzdFdhdGNoZXMob3B0aW9ucyksIHdoaWNoXG4gICAgLy8gZG9lcyBub3RoaW5nIHdoZW4gdGhpcy50eENvdW50ID4gMC5cbiAgICBpZiAob25XYXRjaFVwZGF0ZWQgJiYgYWxyZWFkeURpcnR5LnNpemUpIHtcbiAgICAgIHRoaXMuYnJvYWRjYXN0V2F0Y2hlcyh7XG4gICAgICAgIC4uLm9wdGlvbnMsXG4gICAgICAgIG9uV2F0Y2hVcGRhdGVkKHdhdGNoLCBkaWZmKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gb25XYXRjaFVwZGF0ZWQuY2FsbCh0aGlzLCB3YXRjaCwgZGlmZik7XG4gICAgICAgICAgaWYgKHJlc3VsdCAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIC8vIFNpbmNlIG9uV2F0Y2hVcGRhdGVkIGRpZCBub3QgcmV0dXJuIGZhbHNlLCB0aGlzIGRpZmYgaXNcbiAgICAgICAgICAgIC8vIGFib3V0IHRvIGJlIGJyb2FkY2FzdCB0byB3YXRjaC5jYWxsYmFjaywgc28gd2UgZG9uJ3QgbmVlZFxuICAgICAgICAgICAgLy8gdG8gcmUtZGlydHkgaXQgd2l0aCB0aGUgb3RoZXIgYWxyZWFkeURpcnR5IHdhdGNoZXMgYmVsb3cuXG4gICAgICAgICAgICBhbHJlYWR5RGlydHkuZGVsZXRlKHdhdGNoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgLy8gU2lsZW50bHkgcmUtZGlydHkgYW55IHdhdGNoZXMgdGhhdCB3ZXJlIGFscmVhZHkgZGlydHkgYmVmb3JlIHRoZSB1cGRhdGVcbiAgICAgIC8vIHdhcyBwZXJmb3JtZWQsIGFuZCB3ZXJlIG5vdCBicm9hZGNhc3QganVzdCBub3cuXG4gICAgICBpZiAoYWxyZWFkeURpcnR5LnNpemUpIHtcbiAgICAgICAgYWxyZWFkeURpcnR5LmZvckVhY2goKHdhdGNoKSA9PiB0aGlzLm1heWJlQnJvYWRjYXN0V2F0Y2guZGlydHkod2F0Y2gpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgYWxyZWFkeURpcnR5IGlzIGVtcHR5IG9yIHdlIGRvbid0IGhhdmUgYW4gb25XYXRjaFVwZGF0ZWRcbiAgICAgIC8vIGZ1bmN0aW9uLCB3ZSBkb24ndCBuZWVkIHRvIGdvIHRvIHRoZSB0cm91YmxlIG9mIHdyYXBwaW5nXG4gICAgICAvLyBvcHRpb25zLm9uV2F0Y2hVcGRhdGVkLlxuICAgICAgdGhpcy5icm9hZGNhc3RXYXRjaGVzKG9wdGlvbnMpO1xuICAgIH1cblxuICAgIHJldHVybiB1cGRhdGVSZXN1bHQhO1xuICB9XG5cbiAgcHVibGljIHBlcmZvcm1UcmFuc2FjdGlvbihcbiAgICB1cGRhdGU6IChjYWNoZTogSW5NZW1vcnlDYWNoZSkgPT4gYW55LFxuICAgIG9wdGltaXN0aWNJZD86IHN0cmluZyB8IG51bGxcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuYmF0Y2goe1xuICAgICAgdXBkYXRlLFxuICAgICAgb3B0aW1pc3RpYzogb3B0aW1pc3RpY0lkIHx8IG9wdGltaXN0aWNJZCAhPT0gbnVsbCxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyB0cmFuc2Zvcm1Eb2N1bWVudChkb2N1bWVudDogRG9jdW1lbnROb2RlKTogRG9jdW1lbnROb2RlIHtcbiAgICByZXR1cm4gdGhpcy5hZGRUeXBlbmFtZVRvRG9jdW1lbnQodGhpcy5hZGRGcmFnbWVudHNUb0RvY3VtZW50KGRvY3VtZW50KSk7XG4gIH1cblxuICBwdWJsaWMgZnJhZ21lbnRNYXRjaGVzKFxuICAgIGZyYWdtZW50OiBJbmxpbmVGcmFnbWVudE5vZGUsXG4gICAgdHlwZW5hbWU6IHN0cmluZ1xuICApOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5wb2xpY2llcy5mcmFnbWVudE1hdGNoZXMoZnJhZ21lbnQsIHR5cGVuYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBsb29rdXBGcmFnbWVudChmcmFnbWVudE5hbWU6IHN0cmluZyk6IEZyYWdtZW50RGVmaW5pdGlvbk5vZGUgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jb25maWcuZnJhZ21lbnRzPy5sb29rdXAoZnJhZ21lbnROYW1lKSB8fCBudWxsO1xuICB9XG5cbiAgcHJvdGVjdGVkIGJyb2FkY2FzdFdhdGNoZXMob3B0aW9ucz86IEJyb2FkY2FzdE9wdGlvbnMpIHtcbiAgICBpZiAoIXRoaXMudHhDb3VudCkge1xuICAgICAgdGhpcy53YXRjaGVzLmZvckVhY2goKGMpID0+IHRoaXMubWF5YmVCcm9hZGNhc3RXYXRjaChjLCBvcHRpb25zKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRGcmFnbWVudHNUb0RvY3VtZW50KGRvY3VtZW50OiBEb2N1bWVudE5vZGUpIHtcbiAgICBjb25zdCB7IGZyYWdtZW50cyB9ID0gdGhpcy5jb25maWc7XG4gICAgcmV0dXJuIGZyYWdtZW50cyA/IGZyYWdtZW50cy50cmFuc2Zvcm0oZG9jdW1lbnQpIDogZG9jdW1lbnQ7XG4gIH1cblxuICBwcml2YXRlIGFkZFR5cGVuYW1lVG9Eb2N1bWVudChkb2N1bWVudDogRG9jdW1lbnROb2RlKSB7XG4gICAgaWYgKHRoaXMuYWRkVHlwZW5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmFkZFR5cGVuYW1lVHJhbnNmb3JtLnRyYW5zZm9ybURvY3VtZW50KGRvY3VtZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIGRvY3VtZW50O1xuICB9XG5cbiAgLy8gVGhpcyBtZXRob2QgaXMgd3JhcHBlZCBieSBtYXliZUJyb2FkY2FzdFdhdGNoLCB3aGljaCBpcyBjYWxsZWQgYnlcbiAgLy8gYnJvYWRjYXN0V2F0Y2hlcywgc28gdGhhdCB3ZSBjb21wdXRlIGFuZCBicm9hZGNhc3QgcmVzdWx0cyBvbmx5IHdoZW5cbiAgLy8gdGhlIGRhdGEgdGhhdCB3b3VsZCBiZSBicm9hZGNhc3QgbWlnaHQgaGF2ZSBjaGFuZ2VkLiBJdCB3b3VsZCBiZVxuICAvLyBzaW1wbGVyIHRvIGNoZWNrIGZvciBjaGFuZ2VzIGFmdGVyIHJlY29tcHV0aW5nIGEgcmVzdWx0IGJ1dCBiZWZvcmVcbiAgLy8gYnJvYWRjYXN0aW5nIGl0LCBidXQgdGhpcyB3cmFwcGluZyBhcHByb2FjaCBhbGxvd3MgdXMgdG8gc2tpcCBib3RoXG4gIC8vIHRoZSByZWNvbXB1dGF0aW9uIGFuZCB0aGUgYnJvYWRjYXN0LCBpbiBtb3N0IGNhc2VzLlxuICBwcml2YXRlIGJyb2FkY2FzdFdhdGNoKGM6IENhY2hlLldhdGNoT3B0aW9ucywgb3B0aW9ucz86IEJyb2FkY2FzdE9wdGlvbnMpIHtcbiAgICBjb25zdCB7IGxhc3REaWZmIH0gPSBjO1xuXG4gICAgLy8gQm90aCBXYXRjaE9wdGlvbnMgYW5kIERpZmZPcHRpb25zIGV4dGVuZCBSZWFkT3B0aW9ucywgYW5kIERpZmZPcHRpb25zXG4gICAgLy8gY3VycmVudGx5IHJlcXVpcmVzIG5vIGFkZGl0aW9uYWwgcHJvcGVydGllcywgc28gd2UgY2FuIHVzZSBjIChhXG4gICAgLy8gV2F0Y2hPcHRpb25zIG9iamVjdCkgYXMgRGlmZk9wdGlvbnMsIHdpdGhvdXQgaGF2aW5nIHRvIGFsbG9jYXRlIGEgbmV3XG4gICAgLy8gb2JqZWN0LCBhbmQgd2l0aG91dCBoYXZpbmcgdG8gZW51bWVyYXRlIHRoZSByZWxldmFudCBwcm9wZXJ0aWVzIChxdWVyeSxcbiAgICAvLyB2YXJpYWJsZXMsIGV0Yy4pIGV4cGxpY2l0bHkuIFRoZXJlIHdpbGwgYmUgc29tZSBhZGRpdGlvbmFsIHByb3BlcnRpZXNcbiAgICAvLyAobGFzdERpZmYsIGNhbGxiYWNrLCBldGMuKSwgYnV0IGNhY2hlLmRpZmYgaWdub3JlcyB0aGVtLlxuICAgIGNvbnN0IGRpZmYgPSB0aGlzLmRpZmY8YW55PihjKTtcblxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICBpZiAoYy5vcHRpbWlzdGljICYmIHR5cGVvZiBvcHRpb25zLm9wdGltaXN0aWMgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgZGlmZi5mcm9tT3B0aW1pc3RpY1RyYW5zYWN0aW9uID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICBvcHRpb25zLm9uV2F0Y2hVcGRhdGVkICYmXG4gICAgICAgIG9wdGlvbnMub25XYXRjaFVwZGF0ZWQuY2FsbCh0aGlzLCBjLCBkaWZmLCBsYXN0RGlmZikgPT09IGZhbHNlXG4gICAgICApIHtcbiAgICAgICAgLy8gUmV0dXJuaW5nIGZhbHNlIGZyb20gdGhlIG9uV2F0Y2hVcGRhdGVkIGNhbGxiYWNrIHdpbGwgcHJldmVudFxuICAgICAgICAvLyBjYWxsaW5nIGMuY2FsbGJhY2soZGlmZikgZm9yIHRoaXMgd2F0Y2hlci5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghbGFzdERpZmYgfHwgIWVxdWFsKGxhc3REaWZmLnJlc3VsdCwgZGlmZi5yZXN1bHQpKSB7XG4gICAgICBjLmNhbGxiYWNrKChjLmxhc3REaWZmID0gZGlmZiksIGxhc3REaWZmKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKiBAaW50ZXJuYWxcbiAgICogVGhpcyBpcyBub3QgYSBzdGFibGUgQVBJIC0gaXQgaXMgdXNlZCBpbiBkZXZlbG9wbWVudCBidWlsZHMgdG8gZXhwb3NlXG4gICAqIGluZm9ybWF0aW9uIHRvIHRoZSBEZXZUb29scy5cbiAgICogVXNlIGF0IHlvdXIgb3duIHJpc2shXG4gICAqL1xuICBwdWJsaWMgZ2V0TWVtb3J5SW50ZXJuYWxzPzogdHlwZW9mIGdldEluTWVtb3J5Q2FjaGVNZW1vcnlJbnRlcm5hbHM7XG59XG5cbmlmIChfX0RFVl9fKSB7XG4gIEluTWVtb3J5Q2FjaGUucHJvdG90eXBlLmdldE1lbW9yeUludGVybmFscyA9IGdldEluTWVtb3J5Q2FjaGVNZW1vcnlJbnRlcm5hbHM7XG59XG4iXSwieF9nb29nbGVfaWdub3JlTGlzdCI6WzBdfQ== |