package.dist.src.internal.cache-data-client.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sdk Show documentation
Show all versions of sdk Show documentation
Client SDK for Momento services
The newest version!
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CacheDataClient = exports.CONNECTION_ID_KEY = void 0;
const generated_types_1 = require("@gomomento/generated-types");
// older versions of node don't have the global util variables https://github.com/nodejs/node/issues/20365
const util_1 = require("util");
const headers_interceptor_1 = require("./grpc/headers-interceptor");
const retry_interceptor_1 = require("./grpc/retry-interceptor");
const cache_service_error_mapper_1 = require("../errors/cache-service-error-mapper");
const grpc_js_1 = require("@grpc/grpc-js");
const __1 = require("..");
const package_json_1 = require("../../package.json");
const idle_grpc_client_wrapper_1 = require("./grpc/idle-grpc-client-wrapper");
const middlewares_interceptor_1 = require("./grpc/middlewares-interceptor");
const cacheclient_1 = require("@gomomento/generated-types/dist/cacheclient");
const utils_1 = require("@gomomento/sdk-core/dist/src/internal/utils");
const grpc_response_types_1 = require("@gomomento/sdk-core/dist/src/messages/responses/grpc-response-types");
const connectivity_state_1 = require("@grpc/grpc-js/build/src/connectivity-state");
const grpc_channel_options_1 = require("./grpc/grpc-channel-options");
const errors_1 = require("@gomomento/sdk-core/dist/src/errors");
const common_1 = require("@gomomento/generated-types/dist/common");
const compression_error_1 = require("../errors/compression-error");
var grpcCache = generated_types_1.cache.cache_client;
var ECacheResult = cacheclient_1.cache_client.ECacheResult;
var _ItemGetTypeResponse = cacheclient_1.cache_client._ItemGetTypeResponse;
var _Unbounded = common_1.common._Unbounded;
var Absent = common_1.common.Absent;
var Present = common_1.common.Present;
var Equal = common_1.common.Equal;
var NotEqual = common_1.common.NotEqual;
var PresentAndNotEqual = common_1.common.PresentAndNotEqual;
var AbsentOrEqual = common_1.common.AbsentOrEqual;
const sdk_core_1 = require("@gomomento/sdk-core");
exports.CONNECTION_ID_KEY = Symbol('connectionID');
class CacheDataClient {
/**
* @param {CacheClientProps} props
* @param dataClientID
* @param semaphore
*/
constructor(props, dataClientID, semaphore) {
var _a, _b;
this.configuration = props.configuration;
this.credentialProvider = props.credentialProvider;
this.logger = this.configuration.getLoggerFactory().getLogger(this);
this.cacheServiceErrorMapper = new cache_service_error_mapper_1.CacheServiceErrorMapper(props.configuration.getThrowOnErrors());
const compression = this.configuration.getCompressionStrategy();
if (compression !== undefined) {
this.compressionDetails = {
valueCompressor: compression.compressorFactory,
compressionLevel: (_a = compression.compressionLevel) !== null && _a !== void 0 ? _a : __1.CompressionLevel.Balanced,
autoDecompressEnabled: ((_b = compression.automaticDecompression) !== null && _b !== void 0 ? _b : __1.AutomaticDecompression.Enabled) === __1.AutomaticDecompression.Enabled,
};
}
else {
this.compressionDetails = undefined;
}
this.requestConcurrencySemaphore = semaphore;
const grpcConfig = this.configuration
.getTransportStrategy()
.getGrpcConfig();
this.requestTimeoutMs =
grpcConfig.getDeadlineMillis() ||
CacheDataClient.DEFAULT_REQUEST_TIMEOUT_MS;
this.validateRequestTimeout(this.requestTimeoutMs);
this.logger.debug(`Creating cache client using endpoint: '${this.credentialProvider.getCacheEndpoint()}'`);
const channelOptions = (0, grpc_channel_options_1.grpcChannelOptionsFromGrpcConfig)(grpcConfig);
this.clientWrapper = new idle_grpc_client_wrapper_1.IdleGrpcClientWrapper({
clientFactoryFn: () => {
this.logger.debug(`Constructing channel for clientID ${dataClientID}`);
return new grpcCache.ScsClient(this.credentialProvider.getCacheEndpoint(), this.credentialProvider.isCacheEndpointSecure()
? grpc_js_1.ChannelCredentials.createSsl()
: grpc_js_1.ChannelCredentials.createInsecure(), channelOptions);
},
loggerFactory: this.configuration.getLoggerFactory(),
maxIdleMillis: this.configuration
.getTransportStrategy()
.getMaxIdleMillis(),
maxClientAgeMillis: this.configuration
.getTransportStrategy()
.getMaxClientAgeMillis(),
});
this.textEncoder = new util_1.TextEncoder();
this.defaultTtlSeconds = props.defaultTtlSeconds;
// this context object is currently internal only but can be extended in the Configuration object is we wants clients
// to be able to set it.
const context = {};
context[exports.CONNECTION_ID_KEY] = dataClientID;
const headers = [
new headers_interceptor_1.Header('Authorization', this.credentialProvider.getAuthToken()),
new headers_interceptor_1.Header('agent', `nodejs:cache:${package_json_1.version}`),
new headers_interceptor_1.Header('read-concern', this.configuration.getReadConcern()),
new headers_interceptor_1.Header('runtime-version', `nodejs:${process.versions.node}`),
];
this.interceptors = this.initializeInterceptors(headers, this.configuration.getLoggerFactory(), this.configuration.getMiddlewares(), context);
this.streamingInterceptors = this.initializeStreamingInterceptors(headers);
}
close() {
this.logger.debug('Closing cache data client');
this.clientWrapper.getClient().close();
}
connect(timeoutSeconds = 10) {
this.logger.debug('Attempting to eagerly connect to channel');
const deadline = new Date();
deadline.setSeconds(deadline.getSeconds() + timeoutSeconds);
return this.connectWithinDeadline(deadline);
}
connectionStateToString(state) {
switch (state) {
case connectivity_state_1.ConnectivityState.IDLE:
return 'IDLE';
case connectivity_state_1.ConnectivityState.CONNECTING:
return 'CONNECTING';
case connectivity_state_1.ConnectivityState.READY:
return 'READY';
case connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE:
return 'TRANSIENT_FAILURE';
case connectivity_state_1.ConnectivityState.SHUTDOWN:
return 'SHUTDOWN';
}
}
connectWithinDeadline(deadline) {
return new Promise((resolve, reject) => {
// Get the current state and initiate a connection
const currentState = this.clientWrapper
.getClient()
.getChannel()
.getConnectivityState(true);
this.logger.debug(`Client connectivity state: ${currentState}`);
if (currentState === connectivity_state_1.ConnectivityState.READY) {
resolve();
return;
}
const now = new Date();
if (now >= deadline) {
const errorMessage = 'Unable to connect to Momento: deadline exceeded.';
this.logger.error(errorMessage);
reject(new errors_1.ConnectionError(errorMessage));
return;
}
this.clientWrapper
.getClient()
.getChannel()
.watchConnectivityState(currentState, deadline, (error) => {
if (error) {
const errorMessage = `Unable to eagerly connect to Momento. Please contact Momento if this persists. currentState: ${this.connectionStateToString(currentState)}, errorName: ${error.name} : errorMessage: ${error.message}, errorStack: ${error.stack ? error.stack : 'Stack trace undefined'}`;
this.logger.error(errorMessage);
reject(new errors_1.ConnectionError(errorMessage));
return;
}
const newState = this.clientWrapper
.getClient()
.getChannel()
.getConnectivityState(false);
if (newState === connectivity_state_1.ConnectivityState.READY) {
this.logger.debug(`Connected! Current state: ${this.connectionStateToString(newState)}`);
resolve();
}
else if (newState === connectivity_state_1.ConnectivityState.CONNECTING) {
// The connection goes through the CONNECTING state before becoming READY,
// so we must watch it twice.
this.logger.debug(`Connecting! Current state: ${this.connectionStateToString(newState)}`);
this.connectWithinDeadline(deadline).then(resolve).catch(reject);
}
else {
const errorMessage = `Unable to connect to Momento: Unexpected connection state: ${this.connectionStateToString(newState)}., oldState: ${this.connectionStateToString(currentState)}
Please contact Momento if this persists.`;
this.logger.error(errorMessage);
reject(new errors_1.ConnectionError(errorMessage));
return;
}
});
});
}
getEndpoint() {
const endpoint = this.credentialProvider.getCacheEndpoint();
this.logger.debug(`Using cache endpoint: ${endpoint}`);
return endpoint;
}
validateRequestTimeout(timeout) {
this.logger.debug(`Request timeout ms: ${String(timeout)}`);
if (timeout !== undefined && timeout <= 0) {
throw new __1.InvalidArgumentError('request timeout must be greater than zero.');
}
}
convertECacheResult(result) {
switch (result) {
case grpcCache.ECacheResult.Hit:
return grpc_response_types_1._ECacheResult.Hit;
case grpcCache.ECacheResult.Invalid:
return grpc_response_types_1._ECacheResult.Invalid;
case grpcCache.ECacheResult.Miss:
return grpc_response_types_1._ECacheResult.Miss;
case grpcCache.ECacheResult.Ok:
return grpc_response_types_1._ECacheResult.Ok;
}
}
convertItemTypeResult(result) {
switch (result) {
case _ItemGetTypeResponse.ItemType.SCALAR:
return __1.ItemType.SCALAR;
case _ItemGetTypeResponse.ItemType.LIST:
return __1.ItemType.LIST;
case _ItemGetTypeResponse.ItemType.DICTIONARY:
return __1.ItemType.DICTIONARY;
case _ItemGetTypeResponse.ItemType.SET:
return __1.ItemType.SET;
case _ItemGetTypeResponse.ItemType.SORTED_SET:
return __1.ItemType.SORTED_SET;
}
}
// If maxConcurrentRequests is set, use the semaphore to limit the number of concurrent requests.
// Otherwise, execute the cache operation without any rate limiting.
async rateLimited(cacheOperation) {
try {
if (this.requestConcurrencySemaphore !== undefined)
await this.requestConcurrencySemaphore.acquire();
return await cacheOperation();
}
finally {
if (this.requestConcurrencySemaphore !== undefined)
this.requestConcurrencySemaphore.release();
}
}
async set(cacheName, key, value, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
if ((options === null || options === void 0 ? void 0 : options.ttl) !== undefined) {
(0, utils_1.validateTtlSeconds)(options.ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSet.Error(err));
}
const ttlToUse = (options === null || options === void 0 ? void 0 : options.ttl) || this.defaultTtlSeconds;
const encodedKey = this.convert(key);
let encodedValue = this.convert(value);
if (options === null || options === void 0 ? void 0 : options.compress) {
this.logger.trace('CacheClient.set; compression enabled, calling value compressor');
if (this.compressionDetails === undefined) {
return this.cacheServiceErrorMapper.returnOrThrowError(new compression_error_1.CompressionError('CacheClient.set', 'compress'), err => new __1.CacheSet.Error(err));
}
encodedValue = await this.compressionDetails.valueCompressor.compress(this.compressionDetails.compressionLevel, encodedValue);
}
return await this.rateLimited(async () => {
return await this.sendSet(cacheName, encodedKey, encodedValue, ttlToUse);
});
}
async sendSet(cacheName, key, value, ttl) {
const request = new grpcCache._SetRequest({
cache_body: value,
cache_key: key,
ttl_milliseconds: ttl * 1000,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Set(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheSet.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSet.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setFetch(cacheName, setName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetFetch(cacheName, this.convert(setName));
});
}
async sendSetFetch(cacheName, setName) {
const request = new grpcCache._SetFetchRequest({
set_name: setName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetFetch.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheSetFetch.Hit(resp.found.elements));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setAddElements(cacheName, setName, elements, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetAddElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetAddElements(cacheName, this.convert(setName), this.convertArray(elements), ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendSetAddElements(cacheName, setName, elements, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SetUnionRequest({
set_name: setName,
elements: elements,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetUnion(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetAddElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSetAddElements.Success());
}
});
});
}
async setContainsElement(cacheName, setName, element) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetContainsElement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetContainsElement(cacheName, this.convert(setName), this.convert(element));
});
}
async sendSetContainsElement(cacheName, setName, element) {
const request = new grpcCache._SetContainsRequest({
set_name: setName,
elements: [element],
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetContains(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
const found_mask = resp === null || resp === void 0 ? void 0 : resp.found.contains;
if (found_mask === undefined || found_mask.length === 0) {
return reject(new __1.CacheSetContainsElement.Error(new __1.UnknownError('SetContains response missing contains mask')));
}
resolve(new __1.CacheSetContainsElement.Hit(found_mask[0]));
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetContainsElement.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetContainsElement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setContainsElements(cacheName, setName, elements) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetContainsElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetContainsElements(cacheName, this.convert(setName), this.convertArray(elements));
});
}
async sendSetContainsElements(cacheName, setName, elements) {
const request = new grpcCache._SetContainsRequest({
set_name: setName,
elements: elements,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetContains(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheSetContainsElements.Hit(elements, resp === null || resp === void 0 ? void 0 : resp.found.contains));
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetContainsElements.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetContainsElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setRemoveElements(cacheName, setName, elements) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetRemoveElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetRemoveElements(cacheName, this.convert(setName), this.convertArray(elements));
});
}
async sendSetRemoveElements(cacheName, setName, elements) {
const subtrahend = new grpcCache._SetDifferenceRequest._Subtrahend({
set: new grpcCache._SetDifferenceRequest._Subtrahend._Set({
elements: elements,
}),
});
const request = new grpcCache._SetDifferenceRequest({
set_name: setName,
subtrahend: subtrahend,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetDifference(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetRemoveElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSetRemoveElements.Success());
}
});
});
}
async setSample(cacheName, setName, limit) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
(0, utils_1.validateSetSampleLimit)(limit);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetSample.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetSample(cacheName, this.convert(setName), limit);
});
}
async sendSetSample(cacheName, setName, limit) {
const request = new grpcCache._SetSampleRequest({
set_name: setName,
limit: limit,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetSample(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSetSample.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheSetSample.Hit(resp.found.elements));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetSample.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setPop(cacheName, setName, count) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
(0, utils_1.validateSetPopCount)(count);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.CacheSetPop.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetPop(cacheName, this.convert(setName), count);
});
}
async sendSetPop(cacheName, setName, count) {
const request = new grpcCache._SetPopRequest({
set_name: setName,
count: count,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetPop(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new sdk_core_1.CacheSetPop.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new sdk_core_1.CacheSetPop.Hit(resp.found.elements));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new sdk_core_1.CacheSetPop.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setLength(cacheName, setName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSetName)(setName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new sdk_core_1.CacheSetLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetLength(cacheName, this.convert(setName));
});
}
async sendSetLength(cacheName, setName) {
const request = new grpcCache._SetLengthRequest({
set_name: setName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new sdk_core_1.CacheSetLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
if (!resp.found.length) {
resolve(new sdk_core_1.CacheSetLength.Miss());
}
else {
resolve(new sdk_core_1.CacheSetLength.Hit(resp.found.length));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new sdk_core_1.CacheSetLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
// setIfNotExists is deprecated on the service. Here we call the new `SetIf` method with the absent field set
// and return `CacheSetIfNotExists` responses.
async setIfNotExists(cacheName, key, value, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfNotExists.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfNotExists(cacheName, this.convert(key), this.convert(value), ttl ? ttl * 1000 : this.defaultTtlSeconds * 1000);
});
}
async sendSetIfNotExists(cacheName, key, value, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
absent: new Absent(),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfNotExists.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfNotExists.NotStored());
break;
default:
resolve(new __1.CacheSetIfNotExists.Error(new __1.UnknownError('SetIfNotExists responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfNotExists.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfAbsent(cacheName, key, value, options) {
const ttl = options === null || options === void 0 ? void 0 : options.ttl;
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfAbsent.Error(err));
}
return await this.rateLimited(async () => {
let encodedValue = this.convert(value);
if (options === null || options === void 0 ? void 0 : options.compress) {
this.logger.trace('CacheClient.setIfAbsent; compression enabled, calling value compressor');
if (this.compressionDetails === undefined) {
return this.cacheServiceErrorMapper.returnOrThrowError(new __1.InvalidArgumentError('Compressor is not set, but `CacheClient.setIfAbsent` was called with the `compress` option; please install @gomomento/sdk-nodejs-compression and call `Configuration.withCompressionStrategy` to enable compression.'), err => new __1.CacheSetIfAbsent.Error(err));
}
encodedValue = await this.compressionDetails.valueCompressor.compress(this.compressionDetails.compressionLevel, encodedValue);
}
return await this.sendSetIfAbsent(cacheName, this.convert(key), encodedValue, ttl ? ttl * 1000 : this.defaultTtlSeconds * 1000);
});
}
async sendSetIfAbsent(cacheName, key, value, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
absent: new Absent(),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfAbsent.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfAbsent.NotStored());
break;
default:
resolve(new __1.CacheSetIfAbsent.Error(new __1.UnknownError('SetIfAbsent responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfAbsent.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfPresent(cacheName, key, value, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfPresent.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfPresent(cacheName, this.convert(key), this.convert(value), ttl ? ttl * 1000 : this.defaultTtlSeconds * 1000);
});
}
async sendSetIfPresent(cacheName, key, value, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
present: new Present(),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfPresent.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfPresent.NotStored());
break;
default:
resolve(new __1.CacheSetIfPresent.Error(new __1.UnknownError('SetIfPresent responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfPresent.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfEqual(cacheName, key, value, equal, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfEqual(cacheName, this.convert(key), this.convert(value), this.convert(equal), ttl ? ttl * 1000 : this.defaultTtlSeconds * 1000);
});
}
async sendSetIfEqual(cacheName, key, value, equal, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
equal: new Equal({ value_to_check: equal }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfEqual.Error(new __1.UnknownError('SetIfEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfNotEqual(cacheName, key, value, notEqual, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfNotEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfNotEqual(cacheName, this.convert(key), this.convert(value), this.convert(notEqual), ttl ? ttl * 1000 : this.defaultTtlSeconds * 1000);
});
}
async sendSetIfNotEqual(cacheName, key, value, notEqual, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
not_equal: new NotEqual({ value_to_check: notEqual }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfNotEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfNotEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfNotEqual.Error(new __1.UnknownError('SetIfNotEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfNotEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfPresentAndNotEqual(cacheName, key, value, notEqual, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfPresentAndNotEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfPresentAndNotEqual(cacheName, this.convert(key), this.convert(value), this.convert(notEqual), ttl ? ttl * 1000 : this.defaultTtlSeconds * 1000);
});
}
async sendSetIfPresentAndNotEqual(cacheName, key, value, notEqual, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
present_and_not_equal: new PresentAndNotEqual({ value_to_check: notEqual }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfPresentAndNotEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfPresentAndNotEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfPresentAndNotEqual.Error(new __1.UnknownError('SetIfPresentAndNotEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfPresentAndNotEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async setIfAbsentOrEqual(cacheName, key, value, equal, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetIfAbsentOrEqual.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSetIfAbsentOrEqual(cacheName, this.convert(key), this.convert(value), this.convert(equal), ttl ? ttl * 1000 : this.defaultTtlSeconds * 1000);
});
}
async sendSetIfAbsentOrEqual(cacheName, key, value, equal, ttlMilliseconds) {
const request = new grpcCache._SetIfRequest({
cache_key: key,
cache_body: value,
ttl_milliseconds: ttlMilliseconds,
absent_or_equal: new AbsentOrEqual({ value_to_check: equal }),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SetIf(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
switch (resp.result) {
case 'stored':
resolve(new __1.CacheSetIfAbsentOrEqual.Stored());
break;
case 'not_stored':
resolve(new __1.CacheSetIfAbsentOrEqual.NotStored());
break;
default:
resolve(new __1.CacheSetIfAbsentOrEqual.Error(new __1.UnknownError('SetIfAbsentOrEqual responded with an unknown result')));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetIfAbsentOrEqual.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async delete(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDelete.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDelete(cacheName, this.convert(key));
});
}
async sendDelete(cacheName, key) {
const request = new grpcCache._DeleteRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Delete(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDelete.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDelete.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async get(cacheName, key, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheGet.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendGet(cacheName, this.convert(key), options);
});
}
async sendGet(cacheName, key, options) {
const request = new grpcCache._GetRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Get(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
var _a, _b;
if (resp) {
switch (resp.result) {
case grpcCache.ECacheResult.Miss:
resolve(new __1.CacheGet.Miss());
break;
case grpcCache.ECacheResult.Hit: {
const shouldDecompress = (_a = options === null || options === void 0 ? void 0 : options.decompress) !== null && _a !== void 0 ? _a : ((_b = this.compressionDetails) === null || _b === void 0 ? void 0 : _b.autoDecompressEnabled) === true;
if (!shouldDecompress) {
resolve(new __1.CacheGet.Hit(resp.cache_body));
}
else {
if (this.compressionDetails === undefined) {
resolve(new __1.CacheGet.Error(new compression_error_1.CompressionError('CacheClient.Get', 'decompress')));
}
else {
this.compressionDetails.valueCompressor
.decompressIfCompressed(resp.cache_body)
.then(v => resolve(new __1.CacheGet.Hit(v)))
.catch(e => resolve(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
new __1.CacheGet.Error(new __1.InvalidArgumentError(`${e}`))));
}
}
break;
}
case grpcCache.ECacheResult.Invalid:
case grpcCache.ECacheResult.Ok:
resolve(new __1.CacheGet.Error(new __1.UnknownError(resp.message)));
break;
default:
resolve(new __1.CacheGet.Error(new __1.UnknownError('An unknown error occurred: ' + resp.message)));
break;
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheGet.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async getBatch(cacheName, keys, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheGetBatch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendGetBatch(cacheName, keys.map(key => this.convert(key)), options === null || options === void 0 ? void 0 : options.decompress);
});
}
async sendGetBatch(cacheName, keys, decompress) {
const getRequests = [];
for (const k of keys) {
const getRequest = new grpcCache._GetRequest({
cache_key: k,
});
getRequests.push(getRequest);
}
const request = new grpcCache._GetBatchRequest({
items: getRequests,
});
const metadata = this.createMetadata(cacheName);
const call = this.clientWrapper.getClient().GetBatch(request, metadata, {
interceptors: this.streamingInterceptors,
});
return await new Promise((resolve, reject) => {
const results = [];
call.on('data', (getResponse) => {
const result = getResponse.result;
switch (result) {
case grpcCache.ECacheResult.Hit:
results.push(new __1.CacheGet.Hit(getResponse.cache_body));
break;
case grpcCache.ECacheResult.Miss:
results.push(new __1.CacheGet.Miss());
break;
default:
results.push(new __1.CacheGet.Error(new __1.UnknownError(getResponse.message)));
}
});
call.on('end', () => {
var _a;
const shouldDecompress = decompress !== null && decompress !== void 0 ? decompress : ((_a = this.compressionDetails) === null || _a === void 0 ? void 0 : _a.autoDecompressEnabled) === true;
if (!shouldDecompress) {
resolve(new __1.CacheGetBatch.Success(results, keys));
}
else {
if (this.compressionDetails === undefined) {
resolve(new __1.CacheGetBatch.Error(new compression_error_1.CompressionError('CacheClient.Get', 'decompress')));
}
else {
const compressor = this.compressionDetails.valueCompressor;
Promise.all(results.map(async (r) => {
if (r instanceof __1.CacheGet.Hit) {
return new __1.CacheGet.Hit(await compressor.decompressIfCompressed(r.valueUint8Array()));
}
return r;
}))
.then(decompressedResults => resolve(new __1.CacheGetBatch.Success(decompressedResults, keys)))
.catch(e =>
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
resolve(new __1.CacheGetBatch.Error(new __1.UnknownError(`${e}`))));
}
}
});
call.on('error', (err) => {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheGetBatch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
});
});
}
async setBatch(cacheName, items, options) {
try {
(0, utils_1.validateCacheName)(cacheName);
if ((options === null || options === void 0 ? void 0 : options.ttl) !== undefined) {
(0, utils_1.validateTtlSeconds)(options === null || options === void 0 ? void 0 : options.ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSetBatch.Error(err));
}
const ttlToUse = (options === null || options === void 0 ? void 0 : options.ttl) || this.defaultTtlSeconds;
return await this.rateLimited(async () => {
let itemsToUse = this.convertSetBatchElements(items, ttlToUse);
if (options === null || options === void 0 ? void 0 : options.compress) {
this.logger.trace('CacheClient.setBatch; compression enabled, calling value compressor');
if (this.compressionDetails === undefined) {
return this.cacheServiceErrorMapper.returnOrThrowError(new compression_error_1.CompressionError('CacheClient.setBatch', 'compress'), err => new __1.CacheSetBatch.Error(err));
}
else {
const compressor = this.compressionDetails.valueCompressor;
const compressionLevel = this.compressionDetails.compressionLevel;
itemsToUse = await Promise.all(itemsToUse.map(async ([key, value, ttl]) => {
return [
key,
await compressor.compress(compressionLevel, value),
ttl,
];
}));
}
}
return await this.sendSetBatch(cacheName, itemsToUse);
});
}
async sendSetBatch(cacheName, items) {
const setRequests = [];
for (const item of items) {
const setRequest = new grpcCache._SetRequest({
cache_key: item[0],
cache_body: item[1],
ttl_milliseconds: item[2] * 1000,
});
setRequests.push(setRequest);
}
const request = new grpcCache._SetBatchRequest({
items: setRequests,
});
const metadata = this.createMetadata(cacheName);
const call = this.clientWrapper.getClient().SetBatch(request, metadata, {
interceptors: this.streamingInterceptors,
});
return await new Promise((resolve, reject) => {
const results = [];
call.on('data', (setResponse) => {
const result = setResponse.result;
switch (result) {
case grpcCache.ECacheResult.Ok:
results.push(new __1.CacheSet.Success());
break;
default:
results.push(new __1.CacheSet.Error(new __1.UnknownError(setResponse.message)));
}
});
call.on('end', () => {
resolve(new __1.CacheSetBatch.Success(results));
});
call.on('error', (err) => {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSetBatch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
});
});
}
async listConcatenateBack(cacheName, listName, values, truncateFrontToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListConcatenateBack.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListConcatenateBack(cacheName, this.convert(listName), this.convertArray(values), ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl(), truncateFrontToSize);
});
}
async sendListConcatenateBack(cacheName, listName, values, ttlMilliseconds, refreshTtl, truncateFrontToSize) {
const request = new grpcCache._ListConcatenateBackRequest({
list_name: listName,
values: values,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_front_to_size: truncateFrontToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListConcatenateBack(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListConcatenateBack.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListConcatenateBack.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listConcatenateFront(cacheName, listName, values, truncateBackToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListConcatenateFront.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListConcatenateFront(cacheName, this.convert(listName), this.convertArray(values), ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl(), truncateBackToSize);
});
}
async sendListConcatenateFront(cacheName, listName, values, ttlMilliseconds, refreshTtl, truncateBackToSize) {
const request = new grpcCache._ListConcatenateFrontRequest({
list_name: listName,
values: values,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_back_to_size: truncateBackToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListConcatenateFront(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListConcatenateFront.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListConcatenateFront.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listFetch(cacheName, listName, startIndex, endIndex) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
(0, utils_1.validateListSliceStartEnd)(startIndex, endIndex);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListFetch(cacheName, this.convert(listName), startIndex, endIndex);
});
}
async sendListFetch(cacheName, listName, start, end) {
const request = new grpcCache._ListFetchRequest({
list_name: listName,
});
if (start) {
request.inclusive_start = start;
}
else {
request.unbounded_start = new _Unbounded();
}
if (end) {
request.exclusive_end = end;
}
else {
request.unbounded_end = new _Unbounded();
}
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListFetch.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListFetch.Hit(resp.found.values));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listRetain(cacheName, listName, startIndex, endIndex, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
(0, utils_1.validateListSliceStartEnd)(startIndex, endIndex);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListRetain.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListRetain(cacheName, this.convert(listName), startIndex, endIndex, ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendListRetain(cacheName, listName, start, end, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._ListRetainRequest({
list_name: listName,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
if (start) {
request.inclusive_start = start;
}
else {
request.unbounded_start = new _Unbounded();
}
if (end) {
request.exclusive_end = end;
}
else {
request.unbounded_end = new _Unbounded();
}
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListRetain(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListRetain.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListRetain.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listLength(cacheName, listName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListLength(cacheName, this.convert(listName));
});
}
async sendListLength(cacheName, listName) {
const request = new grpcCache._ListLengthRequest({
list_name: listName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListLength.Hit(resp.found.length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPopBack(cacheName, listName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPopBack.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPopBack(cacheName, this.convert(listName));
});
}
async sendListPopBack(cacheName, listName) {
const request = new grpcCache._ListPopBackRequest({
list_name: listName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPopBack(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListPopBack.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListPopBack.Hit(resp.found.back));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPopBack.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPopFront(cacheName, listName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPopFront.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPopFront(cacheName, this.convert(listName));
});
}
async sendListPopFront(cacheName, listName) {
const request = new grpcCache._ListPopFrontRequest({
list_name: listName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPopFront(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheListPopFront.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheListPopFront.Hit(resp.found.front));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPopFront.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPushBack(cacheName, listName, value, truncateFrontToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPushBack.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPushBack(cacheName, this.convert(listName), this.convert(value), ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl(), truncateFrontToSize);
});
}
async sendListPushBack(cacheName, listName, value, ttlMilliseconds, refreshTtl, truncateFrontToSize) {
const request = new grpcCache._ListPushBackRequest({
list_name: listName,
value: value,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_front_to_size: truncateFrontToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPushBack(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListPushBack.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPushBack.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listPushFront(cacheName, listName, value, truncateBackToSize, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListPushFront.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListPushFront(cacheName, this.convert(listName), this.convert(value), ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl(), truncateBackToSize);
});
}
async sendListPushFront(cacheName, listName, value, ttlMilliseconds, refreshTtl, truncateBackToSize) {
const request = new grpcCache._ListPushFrontRequest({
list_name: listName,
value: value,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
truncate_back_to_size: truncateBackToSize,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListPushFront(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListPushFront.Success(resp.list_length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListPushFront.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async listRemoveValue(cacheName, listName, value) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateListName)(listName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheListRemoveValue.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendListRemoveValue(cacheName, this.convert(listName), this.convert(value));
});
}
async sendListRemoveValue(cacheName, listName, value) {
const request = new grpcCache._ListRemoveRequest({
list_name: listName,
all_elements_with_value: value,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ListRemove(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheListRemoveValue.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheListRemoveValue.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryFetch(cacheName, dictionaryName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryFetch(cacheName, this.convert(dictionaryName));
});
}
async sendDictionaryFetch(cacheName, dictionaryName) {
const request = new grpcCache._DictionaryFetchRequest({
dictionary_name: dictionaryName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheDictionaryFetch.Hit(resp.found.items));
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheDictionaryFetch.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionarySetField(cacheName, dictionaryName, field, value, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionarySetField.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionarySetField(cacheName, this.convert(dictionaryName), this.convert(field), this.convert(value), ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendDictionarySetField(cacheName, dictionaryName, field, value, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._DictionarySetRequest({
dictionary_name: dictionaryName,
items: this.toSingletonFieldValuePair(field, value),
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionarySet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionarySetField.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionarySetField.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionarySetFields(cacheName, dictionaryName, elements, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionarySetFields.Error(err));
}
return await this.rateLimited(async () => {
const dictionaryFieldValuePairs = this.convertElements(elements);
return await this.sendDictionarySetFields(cacheName, this.convert(dictionaryName), dictionaryFieldValuePairs, ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendDictionarySetFields(cacheName, dictionaryName, elements, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._DictionarySetRequest({
dictionary_name: dictionaryName,
items: elements,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionarySet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionarySetFields.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionarySetFields.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryGetField(cacheName, dictionaryName, field) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryGetField.Error(err, this.convert(field)));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryGetField(cacheName, this.convert(dictionaryName), this.convert(field));
});
}
async sendDictionaryGetField(cacheName, dictionaryName, field) {
const request = new grpcCache._DictionaryGetRequest({
dictionary_name: dictionaryName,
fields: [field],
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryGet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'missing') {
resolve(new __1.CacheDictionaryGetField.Miss(field));
}
else if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'found') {
if ((resp === null || resp === void 0 ? void 0 : resp.found.items.length) === 0) {
resolve(new __1.CacheDictionaryGetField.Error(new __1.UnknownError('_DictionaryGetResponseResponse contained no data but was found'), field));
}
else if ((resp === null || resp === void 0 ? void 0 : resp.found.items[0].result) === grpcCache.ECacheResult.Miss) {
resolve(new __1.CacheDictionaryGetField.Miss(field));
}
else {
resolve(new __1.CacheDictionaryGetField.Hit(resp === null || resp === void 0 ? void 0 : resp.found.items[0].cache_body, field));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryGetField.Error(e, field),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryGetFields(cacheName, dictionaryName, fields) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryGetFields.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryGetFields(cacheName, this.convert(dictionaryName), this.convertArray(fields));
});
}
async sendDictionaryGetFields(cacheName, dictionaryName, fields) {
const request = new grpcCache._DictionaryGetRequest({
dictionary_name: dictionaryName,
fields: fields,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryGet(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'found') {
const items = resp.found.items.map(item => {
const result = this.convertECacheResult(item.result);
return new grpc_response_types_1._DictionaryGetResponsePart(result, item.cache_body);
});
resolve(new __1.CacheDictionaryGetFields.Hit(items, fields));
}
else if ((resp === null || resp === void 0 ? void 0 : resp.dictionary) === 'missing') {
resolve(new __1.CacheDictionaryGetFields.Miss());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryGetFields.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryRemoveField(cacheName, dictionaryName, field) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryRemoveField.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryRemoveField(cacheName, this.convert(dictionaryName), this.convert(field));
});
}
async sendDictionaryRemoveField(cacheName, dictionaryName, field) {
const request = new grpcCache._DictionaryDeleteRequest({
dictionary_name: dictionaryName,
some: new grpcCache._DictionaryDeleteRequest.Some(),
});
request.some.fields.push(field);
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryDelete(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionaryRemoveField.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryRemoveField.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryRemoveFields(cacheName, dictionaryName, fields) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryRemoveFields.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryRemoveFields(cacheName, this.convert(dictionaryName), this.convertArray(fields));
});
}
async sendDictionaryRemoveFields(cacheName, dictionaryName, fields) {
const request = new grpcCache._DictionaryDeleteRequest({
dictionary_name: dictionaryName,
some: new grpcCache._DictionaryDeleteRequest.Some(),
});
fields.forEach(field => request.some.fields.push(field));
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryDelete(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheDictionaryRemoveFields.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryRemoveFields.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryLength(cacheName, dictionaryName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryLength(cacheName, this.convert(dictionaryName));
});
}
async sendDictionaryLength(cacheName, dictionaryName) {
const request = new grpcCache._DictionaryLengthRequest({
dictionary_name: dictionaryName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheDictionaryLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheDictionaryLength.Hit(resp.found.length));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async increment(cacheName, field, amount = 1, ttl) {
try {
(0, utils_1.validateCacheName)(cacheName);
if (ttl !== undefined) {
(0, utils_1.validateTtlSeconds)(ttl);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheIncrement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendIncrement(cacheName, this.convert(field), amount, (ttl || this.defaultTtlSeconds) * 1000);
});
}
async sendIncrement(cacheName, field, amount = 1, ttlMilliseconds) {
const request = new grpcCache._IncrementRequest({
cache_key: field,
amount,
ttl_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().Increment(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
if (resp.value) {
resolve(new __1.CacheIncrement.Success(resp.value));
}
else {
resolve(new __1.CacheIncrement.Success(0));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheIncrement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async dictionaryIncrement(cacheName, dictionaryName, field, amount = 1, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateDictionaryName)(dictionaryName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDictionaryIncrement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDictionaryIncrement(cacheName, this.convert(dictionaryName), this.convert(field), amount, ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendDictionaryIncrement(cacheName, dictionaryName, field, amount, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._DictionaryIncrementRequest({
dictionary_name: dictionaryName,
field,
amount,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().DictionaryIncrement(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
if (resp.value) {
resolve(new __1.CacheDictionaryIncrement.Success(resp.value));
}
else {
resolve(new __1.CacheDictionaryIncrement.Success(0));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDictionaryIncrement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetPutElement(cacheName, sortedSetName, value, score, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetPutElement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetPutElement(cacheName, this.convert(sortedSetName), this.convert(value), score, ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendSortedSetPutElement(cacheName, sortedSetName, value, score, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SortedSetPutRequest({
set_name: sortedSetName,
elements: [new grpcCache._SortedSetElement({ value, score })],
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetPut(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheSortedSetPutElement.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetPutElement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetPutElements(cacheName, sortedSetName, elements, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetPutElements.Error(err));
}
return await this.rateLimited(async () => {
const sortedSetValueScorePairs = this.convertSortedSetMapOrRecord(elements);
return await this.sendSortedSetPutElements(cacheName, this.convert(sortedSetName), sortedSetValueScorePairs, ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendSortedSetPutElements(cacheName, sortedSetName, elements, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SortedSetPutRequest({
set_name: sortedSetName,
elements: elements,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetPut(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheSortedSetPutElements.Success());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetPutElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetFetchByRank(cacheName, sortedSetName, order, startRank, endRank) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
(0, utils_1.validateSortedSetRanks)(startRank, endRank);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetFetchByRank(cacheName, this.convert(sortedSetName), order, startRank, endRank);
});
}
async sendSortedSetFetchByRank(cacheName, sortedSetName, order, startRank, endRank) {
const by_index = new grpcCache._SortedSetFetchRequest._ByIndex();
if (startRank) {
by_index.inclusive_start_index = startRank;
}
else {
by_index.unbounded_start = new _Unbounded();
}
if (endRank) {
by_index.exclusive_end_index = endRank;
}
else {
by_index.unbounded_end = new _Unbounded();
}
const protoBufOrder = order === __1.SortedSetOrder.Descending
? grpcCache._SortedSetFetchRequest.Order.DESCENDING
: grpcCache._SortedSetFetchRequest.Order.ASCENDING;
const request = new grpcCache._SortedSetFetchRequest({
set_name: sortedSetName,
order: protoBufOrder,
with_scores: true,
by_index: by_index,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
var _a;
if (resp) {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
if ((_a = resp === null || resp === void 0 ? void 0 : resp.found) === null || _a === void 0 ? void 0 : _a.values_with_scores) {
resolve(new __1.CacheSortedSetFetch.Hit(resp.found.values_with_scores.elements));
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch hit response type')));
}
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetFetch.Miss());
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch response type')));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetFetchByScore(cacheName, sortedSetName, order, minScore, maxScore, offset, count) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
(0, utils_1.validateSortedSetScores)(minScore, maxScore);
if (offset !== undefined) {
(0, utils_1.validateSortedSetOffset)(offset);
}
if (count !== undefined) {
(0, utils_1.validateSortedSetCount)(count);
}
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetFetch.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetFetchByScore(cacheName, this.convert(sortedSetName), order, minScore, maxScore, offset, count);
});
}
async sendSortedSetFetchByScore(cacheName, sortedSetName, order, minScore, maxScore, offset, count) {
const by_score = new grpcCache._SortedSetFetchRequest._ByScore();
if (minScore !== undefined) {
by_score.min_score = new grpcCache._SortedSetFetchRequest._ByScore._Score({
score: minScore,
exclusive: false,
});
}
else {
by_score.unbounded_min = new _Unbounded();
}
if (maxScore !== undefined) {
by_score.max_score = new grpcCache._SortedSetFetchRequest._ByScore._Score({
score: maxScore,
exclusive: false,
});
}
else {
by_score.unbounded_max = new _Unbounded();
}
by_score.offset = offset !== null && offset !== void 0 ? offset : 0;
// Note: the service reserves negative counts to mean all elements in the
// result set.
by_score.count = count !== null && count !== void 0 ? count : -1;
const protoBufOrder = order === __1.SortedSetOrder.Descending
? grpcCache._SortedSetFetchRequest.Order.DESCENDING
: grpcCache._SortedSetFetchRequest.Order.ASCENDING;
const request = new grpcCache._SortedSetFetchRequest({
set_name: sortedSetName,
order: protoBufOrder,
with_scores: true,
by_score: by_score,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetFetch(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
var _a;
if (resp) {
if (resp === null || resp === void 0 ? void 0 : resp.found) {
if ((_a = resp === null || resp === void 0 ? void 0 : resp.found) === null || _a === void 0 ? void 0 : _a.values_with_scores) {
resolve(new __1.CacheSortedSetFetch.Hit(resp.found.values_with_scores.elements));
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch hit response type')));
}
}
else if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetFetch.Miss());
}
else {
resolve(new __1.CacheSortedSetFetch.Error(new __1.UnknownError('Unknown sorted set fetch response type')));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetFetch.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetGetRank(cacheName, sortedSetName, value, order) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetGetRank.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetGetRank(cacheName, this.convert(sortedSetName), this.convert(value), order);
});
}
async sendSortedSetGetRank(cacheName, sortedSetName, value, order) {
const protoBufOrder = order === __1.SortedSetOrder.Descending
? grpcCache._SortedSetGetRankRequest.Order.DESCENDING
: grpcCache._SortedSetGetRankRequest.Order.ASCENDING;
const request = new grpcCache._SortedSetGetRankRequest({
set_name: sortedSetName,
value: value,
order: protoBufOrder,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper
.getClient()
.SortedSetGetRank(request, metadata, { interceptors: this.interceptors }, (err, resp) => {
var _a, _b;
if ((resp === null || resp === void 0 ? void 0 : resp.missing) ||
((_a = resp === null || resp === void 0 ? void 0 : resp.element_rank) === null || _a === void 0 ? void 0 : _a.result) === ECacheResult.Miss) {
resolve(new __1.CacheSortedSetGetRank.Miss());
}
else if (((_b = resp === null || resp === void 0 ? void 0 : resp.element_rank) === null || _b === void 0 ? void 0 : _b.result) === ECacheResult.Hit) {
if ((resp === null || resp === void 0 ? void 0 : resp.element_rank.rank) === undefined) {
resolve(new __1.CacheSortedSetGetRank.Miss());
}
else {
resolve(new __1.CacheSortedSetGetRank.Hit(resp.element_rank.rank));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetGetRank.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetGetScore(cacheName, sortedSetName, value) {
const responses = await this.sortedSetGetScores(cacheName, sortedSetName, [
value,
]);
if (responses instanceof __1.CacheSortedSetGetScores.Hit) {
return responses.responses()[0];
}
else if (responses instanceof __1.CacheSortedSetGetScores.Miss) {
return new __1.CacheSortedSetGetScore.Miss(this.convert(value));
}
else if (responses instanceof __1.CacheSortedSetGetScores.Error) {
return this.cacheServiceErrorMapper.returnOrThrowError(responses.innerException(), err => new __1.CacheSortedSetGetScore.Error(err, this.convert(value)));
}
return this.cacheServiceErrorMapper.returnOrThrowError(new __1.UnknownError('Unknown response type'), err => new __1.CacheSortedSetGetScore.Error(err, this.convert(value)));
}
async sortedSetGetScores(cacheName, sortedSetName, values) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetGetScores.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetGetScores(cacheName, this.convert(sortedSetName), values.map(value => this.convert(value)));
});
}
async sendSortedSetGetScores(cacheName, sortedSetName, values) {
const request = new grpcCache._SortedSetGetScoreRequest({
set_name: sortedSetName,
values: values,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper
.getClient()
.SortedSetGetScore(request, metadata, { interceptors: this.interceptors }, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetGetScores.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
const elements = resp.found.elements.map(ele => {
const result = this.convertECacheResult(ele.result);
return new grpc_response_types_1._SortedSetGetScoreResponsePart(result, ele.score);
});
resolve(new __1.CacheSortedSetGetScores.Hit(elements, values));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetGetScores.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetIncrementScore(cacheName, sortedSetName, value, amount = 1, ttl = __1.CollectionTtl.fromCacheTtl()) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetIncrementScore.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetIncrementScore(cacheName, this.convert(sortedSetName), this.convert(value), amount, ttl.ttlMilliseconds() || this.defaultTtlSeconds * 1000, ttl.refreshTtl());
});
}
async sendSortedSetIncrementScore(cacheName, sortedSetName, value, amount, ttlMilliseconds, refreshTtl) {
const request = new grpcCache._SortedSetIncrementRequest({
set_name: sortedSetName,
value: value,
amount: amount,
ttl_milliseconds: ttlMilliseconds,
refresh_ttl: refreshTtl,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper
.getClient()
.SortedSetIncrement(request, metadata, { interceptors: this.interceptors }, (err, resp) => {
if (resp) {
if (resp.score) {
resolve(new __1.CacheSortedSetIncrementScore.Success(resp.score));
}
else {
resolve(new __1.CacheSortedSetIncrementScore.Success(0));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetIncrementScore.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetRemoveElement(cacheName, sortedSetName, value) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetRemoveElement.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetRemoveElement(cacheName, this.convert(sortedSetName), this.convert(value));
});
}
async sendSortedSetRemoveElement(cacheName, sortedSetName, value) {
const request = new grpcCache._SortedSetRemoveRequest({
set_name: sortedSetName,
some: new grpcCache._SortedSetRemoveRequest._Some({
values: [value],
}),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetRemove(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetRemoveElement.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSortedSetRemoveElement.Success());
}
});
});
}
async sortedSetRemoveElements(cacheName, sortedSetName, values) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetRemoveElements.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetRemoveElements(cacheName, this.convert(sortedSetName), this.convertArray(values));
});
}
async sendSortedSetRemoveElements(cacheName, sortedSetName, values) {
const request = new grpcCache._SortedSetRemoveRequest({
set_name: sortedSetName,
some: new grpcCache._SortedSetRemoveRequest._Some({
values: values,
}),
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetRemove(request, metadata, {
interceptors: this.interceptors,
}, err => {
if (err) {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetRemoveElements.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
else {
resolve(new __1.CacheSortedSetRemoveElements.Success());
}
});
});
}
async sortedSetLength(cacheName, sortedSetName) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetLength.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetLength(cacheName, this.convert(sortedSetName));
});
}
async sendSortedSetLength(cacheName, sortedSetName) {
const request = new grpcCache._SortedSetLengthRequest({
set_name: sortedSetName,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetLength(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetLength.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
if (!resp.found.length) {
resolve(new __1.CacheSortedSetLength.Miss());
}
else {
resolve(new __1.CacheSortedSetLength.Hit(resp.found.length));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetLength.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async sortedSetLengthByScore(cacheName, sortedSetName, minScore, maxScore) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateSortedSetName)(sortedSetName);
(0, utils_1.validateSortedSetScores)(minScore, maxScore);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheSortedSetLengthByScore.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendSortedSetLengthByScore(cacheName, this.convert(sortedSetName), minScore, maxScore);
});
}
async sendSortedSetLengthByScore(cacheName, sortedSetName, minScore, maxScore) {
const request = new grpcCache._SortedSetLengthByScoreRequest({
set_name: sortedSetName,
});
if (minScore === undefined) {
request.unbounded_min = new _Unbounded();
}
else {
request.inclusive_min = minScore;
}
if (maxScore === undefined) {
request.unbounded_max = new _Unbounded();
}
else {
request.inclusive_max = maxScore;
}
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().SortedSetLengthByScore(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheSortedSetLengthByScore.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
if (!resp.found.length) {
resolve(new __1.CacheSortedSetLengthByScore.Miss());
}
else {
resolve(new __1.CacheSortedSetLengthByScore.Hit(resp.found.length));
}
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheSortedSetLengthByScore.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
initializeInterceptors(headers, loggerFactory, middlewares, middlewareRequestContext) {
return [
(0, middlewares_interceptor_1.middlewaresInterceptor)(loggerFactory, middlewares, middlewareRequestContext, this.clientWrapper.getClient()),
headers_interceptor_1.HeaderInterceptor.createHeadersInterceptor(headers),
retry_interceptor_1.RetryInterceptor.createRetryInterceptor({
clientName: 'CacheDataClient',
loggerFactory: this.configuration.getLoggerFactory(),
retryStrategy: this.configuration.getRetryStrategy(),
overallRequestTimeoutMs: this.requestTimeoutMs,
}),
];
}
// TODO https://github.com/momentohq/client-sdk-nodejs/issues/349
// decide on streaming interceptors and middlewares
initializeStreamingInterceptors(headers) {
return [headers_interceptor_1.HeaderInterceptor.createHeadersInterceptor(headers)];
}
convert(v) {
if (typeof v === 'string') {
return this.textEncoder.encode(v);
}
return v;
}
convertArray(v) {
return v.map(i => this.convert(i));
}
convertElements(elements) {
if (elements instanceof Array) {
return this.convertElements(new Map(elements));
}
else if (elements instanceof Map) {
return [...elements.entries()].map(element => new grpcCache._DictionaryFieldValuePair({
field: this.convert(element[0]),
value: this.convert(element[1]),
}));
}
else {
return Object.entries(elements).map(element => new grpcCache._DictionaryFieldValuePair({
field: this.convert(element[0]),
value: this.convert(element[1]),
}));
}
}
convertSortedSetMapOrRecord(elements) {
if (elements instanceof Array) {
return this.convertSortedSetMapOrRecord(new Map(elements));
}
else if (elements instanceof Map) {
return [...elements.entries()].map(element => new grpcCache._SortedSetElement({
value: this.convert(element[0]),
score: element[1],
}));
}
else {
return Object.entries(elements).map(element => new grpcCache._SortedSetElement({
value: this.convert(element[0]),
score: element[1],
}));
}
}
convertSetBatchElements(elements, ttl) {
if (elements instanceof Array) {
return elements.map(element => {
var _a;
return [
this.convert(element.key),
this.convert(element.value),
(_a = element.ttl) !== null && _a !== void 0 ? _a : ttl,
];
});
}
else if (elements instanceof Map) {
return [...elements.entries()].map(([k, v]) => [
this.convert(k),
this.convert(v),
ttl,
]);
}
else {
return Object.entries(elements).map(element => [
this.convert(element[0]),
this.convert(element[1]),
ttl,
]);
}
}
async itemGetType(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheItemGetType.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendItemGetType(cacheName, this.convert(key));
});
}
async sendItemGetType(cacheName, key) {
const request = new grpcCache._ItemGetTypeRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ItemGetType(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheItemGetType.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheItemGetType.Hit(this.convertItemTypeResult(resp.found.item_type)));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheItemGetType.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async itemGetTtl(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheItemGetTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendItemGetTtl(cacheName, this.convert(key));
});
}
async sendItemGetTtl(cacheName, key) {
const request = new grpcCache._ItemGetTtlRequest({
cache_key: key,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().ItemGetTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheItemGetTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.found) {
resolve(new __1.CacheItemGetTtl.Hit(resp.found.remaining_ttl_millis));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheItemGetTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async keyExists(cacheName, key) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheKeyExists.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendKeyExists(cacheName, this.convert(key));
});
}
async sendKeyExists(cacheName, key) {
const request = new grpcCache._KeysExistRequest({
cache_keys: [key],
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().KeysExist(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheKeyExists.Success(resp.exists));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheKeyExists.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async updateTtl(cacheName, key, ttlMilliseconds) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateValidForSeconds)(ttlMilliseconds);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheUpdateTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendUpdateTtl(cacheName, this.convert(key), ttlMilliseconds);
});
}
async sendUpdateTtl(cacheName, key, ttlMilliseconds) {
const request = new grpcCache._UpdateTtlRequest({
cache_key: key,
overwrite_to_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().UpdateTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheUpdateTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.set) {
resolve(new __1.CacheUpdateTtl.Set());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheUpdateTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async keysExist(cacheName, keys) {
try {
(0, utils_1.validateCacheName)(cacheName);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheKeysExist.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendKeysExist(cacheName, this.convertArray(keys));
});
}
async sendKeysExist(cacheName, keys) {
const request = new grpcCache._KeysExistRequest({
cache_keys: keys,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().KeysExist(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp) {
resolve(new __1.CacheKeysExist.Success(keys, resp.exists));
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheKeysExist.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async increaseTtl(cacheName, key, ttlMilliseconds) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateValidForSeconds)(ttlMilliseconds);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheIncreaseTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendIncreaseTtl(cacheName, this.convert(key), ttlMilliseconds);
});
}
async sendIncreaseTtl(cacheName, key, ttlMilliseconds) {
const request = new grpcCache._UpdateTtlRequest({
cache_key: key,
increase_to_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().UpdateTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheIncreaseTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.set) {
resolve(new __1.CacheIncreaseTtl.Set());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheIncreaseTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
async decreaseTtl(cacheName, key, ttlMilliseconds) {
try {
(0, utils_1.validateCacheName)(cacheName);
(0, utils_1.validateValidForSeconds)(ttlMilliseconds);
}
catch (err) {
return this.cacheServiceErrorMapper.returnOrThrowError(err, err => new __1.CacheDecreaseTtl.Error(err));
}
return await this.rateLimited(async () => {
return await this.sendDecreaseTtl(cacheName, this.convert(key), ttlMilliseconds);
});
}
async sendDecreaseTtl(cacheName, key, ttlMilliseconds) {
const request = new grpcCache._UpdateTtlRequest({
cache_key: key,
decrease_to_milliseconds: ttlMilliseconds,
});
const metadata = this.createMetadata(cacheName);
return await new Promise((resolve, reject) => {
this.clientWrapper.getClient().UpdateTtl(request, metadata, {
interceptors: this.interceptors,
}, (err, resp) => {
if (resp === null || resp === void 0 ? void 0 : resp.missing) {
resolve(new __1.CacheDecreaseTtl.Miss());
}
else if (resp === null || resp === void 0 ? void 0 : resp.set) {
resolve(new __1.CacheDecreaseTtl.Set());
}
else {
this.cacheServiceErrorMapper.resolveOrRejectError({
err: err,
errorResponseFactoryFn: e => new __1.CacheDecreaseTtl.Error(e),
resolveFn: resolve,
rejectFn: reject,
});
}
});
});
}
createMetadata(cacheName) {
const metadata = new grpc_js_1.Metadata();
metadata.set('cache', cacheName);
return metadata;
}
toSingletonFieldValuePair(field, value) {
return [
new grpcCache._DictionaryFieldValuePair({
field: field,
value: value,
}),
];
}
}
exports.CacheDataClient = CacheDataClient;
CacheDataClient.DEFAULT_REQUEST_TIMEOUT_MS = 5 * 1000;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUtZGF0YS1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaW50ZXJuYWwvY2FjaGUtZGF0YS1jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQWlEO0FBQ2pELDBHQUEwRztBQUMxRywrQkFBaUM7QUFDakMsb0VBQXFFO0FBQ3JFLGdFQUEwRDtBQUMxRCxxRkFBNkU7QUFDN0UsMkNBS3VCO0FBQ3ZCLDBCQW9FWTtBQUNaLHFEQUEyQztBQUMzQyw4RUFBc0U7QUFNdEUsNEVBQXNFO0FBQ3RFLDZFQUF5RTtBQUV6RSx1RUFnQnFEO0FBQ3JELDZHQUk2RTtBQUU3RSxtRkFBNkU7QUFFN0Usc0VBQTZFO0FBQzdFLGdFQUFvRTtBQUNwRSxtRUFBOEQ7QUFTOUQsbUVBQTZEO0FBQzdELElBQU8sU0FBUyxHQUFHLHVCQUFLLENBQUMsWUFBWSxDQUFDO0FBQ3RDLElBQU8sWUFBWSxHQUFHLDBCQUFZLENBQUMsWUFBWSxDQUFDO0FBQ2hELElBQU8sb0JBQW9CLEdBQUcsMEJBQVksQ0FBQyxvQkFBb0IsQ0FBQztBQUNoRSxJQUFPLFVBQVUsR0FBRyxlQUFNLENBQUMsVUFBVSxDQUFDO0FBQ3RDLElBQU8sTUFBTSxHQUFHLGVBQU0sQ0FBQyxNQUFNLENBQUM7QUFDOUIsSUFBTyxPQUFPLEdBQUcsZUFBTSxDQUFDLE9BQU8sQ0FBQztBQUNoQyxJQUFPLEtBQUssR0FBRyxlQUFNLENBQUMsS0FBSyxDQUFDO0FBQzVCLElBQU8sUUFBUSxHQUFHLGVBQU0sQ0FBQyxRQUFRLENBQUM7QUFDbEMsSUFBTyxrQkFBa0IsR0FBRyxlQUFNLENBQUMsa0JBQWtCLENBQUM7QUFDdEQsSUFBTyxhQUFhLEdBQUcsZUFBTSxDQUFDLGFBQWEsQ0FBQztBQUM1QyxrREFBZ0U7QUFFbkQsUUFBQSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7QUFReEQsTUFBYSxlQUFlO0lBZTFCOzs7O09BSUc7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QWdCLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztpQkFDdEM7cUJBQU0sSUFBSSxJQUFJLGFBQUosSUFBSSx1QkFBSixJQUFJLENBQUUsR0FBRyxFQUFFO29CQUNwQixPQUFPLENBQUMsSUFBSSxvQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO2lCQUNyQztxQkFBTTtvQkFDTCxJQUFJLENBQUMsdUJBQXVCLENBQUMsb0JBQW9CLENBQUM7d0JBQ2hELEdBQUcsRUFBRSxHQUFHO3dCQUNSLHNCQUFzQixFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxvQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO3dCQUMxRCxTQUFTLEVBQUUsT0FBTzt3QkFDbEIsUUFBUSxFQUFFLE1BQU07cUJBQ2pCLENBQUMsQ0FBQztpQkFDSjtZQUNILENBQUMsQ0FDRixDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sY0FBYyxDQUFDLFNBQWlCO1FBQ3RDLE1BQU0sUUFBUSxHQUFHLElBQUksa0JBQVEsRUFBRSxDQUFDO1FBQ2hDLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFTyx5QkFBeUIsQ0FDL0IsS0FBaUIsRUFDakIsS0FBaUI7UUFFakIsT0FBTztZQUNMLElBQUksU0FBUyxDQUFDLHlCQUF5QixDQUFDO2dCQUN0QyxLQUFLLEVBQUUsS0FBSztnQkFDWixLQUFLLEVBQUUsS0FBSzthQUNiLENBQUM7U0FDSCxDQUFDO0lBQ0osQ0FBQzs7QUEvM0lILDBDQWc0SUM7QUF6M0l5QiwwQ0FBMEIsR0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtjYWNoZX0gZnJvbSAnQGdvbW9tZW50by9nZW5lcmF0ZWQtdHlwZXMnO1xuLy8gb2xkZXIgdmVyc2lvbnMgb2Ygbm9kZSBkb24ndCBoYXZlIHRoZSBnbG9iYWwgdXRpbCB2YXJpYWJsZXMgaHR0cHM6Ly9naXRodWIuY29tL25vZGVqcy9ub2RlL2lzc3Vlcy8yMDM2NVxuaW1wb3J0IHtUZXh0RW5jb2Rlcn0gZnJvbSAndXRpbCc7XG5pbXBvcnQge0hlYWRlciwgSGVhZGVySW50ZXJjZXB0b3J9IGZyb20gJy4vZ3JwYy9oZWFkZXJzLWludGVyY2VwdG9yJztcbmltcG9ydCB7UmV0cnlJbnRlcmNlcHRvcn0gZnJvbSAnLi9ncnBjL3JldHJ5LWludGVyY2VwdG9yJztcbmltcG9ydCB7Q2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXJ9IGZyb20gJy4uL2Vycm9ycy9jYWNoZS1zZXJ2aWNlLWVycm9yLW1hcHBlcic7XG5pbXBvcnQge1xuICBDaGFubmVsQ3JlZGVudGlhbHMsXG4gIEludGVyY2VwdG9yLFxuICBNZXRhZGF0YSxcbiAgU2VydmljZUVycm9yLFxufSBmcm9tICdAZ3JwYy9ncnBjLWpzJztcbmltcG9ydCB7XG4gIEF1dG9tYXRpY0RlY29tcHJlc3Npb24sXG4gIENhY2hlRGVjcmVhc2VUdGwsXG4gIENhY2hlRGVsZXRlLFxuICBDYWNoZURpY3Rpb25hcnlGZXRjaCxcbiAgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQsXG4gIENhY2hlRGljdGlvbmFyeUdldEZpZWxkcyxcbiAgQ2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LFxuICBDYWNoZURpY3Rpb25hcnlMZW5ndGgsXG4gIENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkLFxuICBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMsXG4gIENhY2hlRGljdGlvbmFyeVNldEZpZWxkLFxuICBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZHMsXG4gIENhY2hlR2V0LFxuICBDYWNoZUdldEJhdGNoLFxuICBDYWNoZUluY3JlYXNlVHRsLFxuICBDYWNoZUluY3JlbWVudCxcbiAgQ2FjaGVJdGVtR2V0VHRsLFxuICBDYWNoZUl0ZW1HZXRUeXBlLFxuICBDYWNoZUtleUV4aXN0cyxcbiAgQ2FjaGVLZXlzRXhpc3QsXG4gIENhY2hlTGlzdENvbmNhdGVuYXRlQmFjayxcbiAgQ2FjaGVMaXN0Q29uY2F0ZW5hdGVGcm9udCxcbiAgQ2FjaGVMaXN0RmV0Y2gsXG4gIENhY2hlTGlzdExlbmd0aCxcbiAgQ2FjaGVMaXN0UG9wQmFjayxcbiAgQ2FjaGVMaXN0UG9wRnJvbnQsXG4gIENhY2hlTGlzdFB1c2hCYWNrLFxuICBDYWNoZUxpc3RQdXNoRnJvbnQsXG4gIENhY2hlTGlzdFJlbW92ZVZhbHVlLFxuICBDYWNoZUxpc3RSZXRhaW4sXG4gIENhY2hlU2V0LFxuICBDYWNoZVNldEFkZEVsZW1lbnRzLFxuICBDYWNoZVNldEJhdGNoLFxuICBDYWNoZVNldEZldGNoLFxuICBDYWNoZVNldENvbnRhaW5zRWxlbWVudCxcbiAgQ2FjaGVTZXRDb250YWluc0VsZW1lbnRzLFxuICBDYWNoZVNldElmQWJzZW50LFxuICBDYWNoZVNldElmQWJzZW50T3JFcXVhbCxcbiAgQ2FjaGVTZXRJZkVxdWFsLFxuICBDYWNoZVNldElmTm90RXF1YWwsXG4gIENhY2hlU2V0SWZOb3RFeGlzdHMsXG4gIENhY2hlU2V0SWZQcmVzZW50LFxuICBDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLFxuICBDYWNoZVNldFJlbW92ZUVsZW1lbnRzLFxuICBDYWNoZVNldFNhbXBsZSxcbiAgQ2FjaGVTb3J0ZWRTZXRGZXRjaCxcbiAgQ2FjaGVTb3J0ZWRTZXRHZXRSYW5rLFxuICBDYWNoZVNvcnRlZFNldEdldFNjb3JlLFxuICBDYWNoZVNvcnRlZFNldEdldFNjb3JlcyxcbiAgQ2FjaGVTb3J0ZWRTZXRJbmNyZW1lbnRTY29yZSxcbiAgQ2FjaGVTb3J0ZWRTZXRMZW5ndGgsXG4gIENhY2hlU29ydGVkU2V0TGVuZ3RoQnlTY29yZSxcbiAgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LFxuICBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnRzLFxuICBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnQsXG4gIENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudHMsXG4gIENhY2hlVXBkYXRlVHRsLFxuICBDb2xsZWN0aW9uVHRsLFxuICBDb21wcmVzc2lvbkxldmVsLFxuICBDcmVkZW50aWFsUHJvdmlkZXIsXG4gIElDb21wcmVzc2lvbixcbiAgSW52YWxpZEFyZ3VtZW50RXJyb3IsXG4gIEl0ZW1UeXBlLFxuICBNb21lbnRvTG9nZ2VyLFxuICBNb21lbnRvTG9nZ2VyRmFjdG9yeSxcbiAgU29ydGVkU2V0T3JkZXIsXG4gIFVua25vd25FcnJvcixcbn0gZnJvbSAnLi4nO1xuaW1wb3J0IHt2ZXJzaW9ufSBmcm9tICcuLi8uLi9wYWNrYWdlLmpzb24nO1xuaW1wb3J0IHtJZGxlR3JwY0NsaWVudFdyYXBwZXJ9IGZyb20gJy4vZ3JwYy9pZGxlLWdycGMtY2xpZW50LXdyYXBwZXInO1xuaW1wb3J0IHtHcnBjQ2xpZW50V3JhcHBlcn0gZnJvbSAnLi9ncnBjL2dycGMtY2xpZW50LXdyYXBwZXInO1xuaW1wb3J0IHtcbiAgTWlkZGxld2FyZSxcbiAgTWlkZGxld2FyZVJlcXVlc3RIYW5kbGVyQ29udGV4dCxcbn0gZnJvbSAnLi4vY29uZmlnL21pZGRsZXdhcmUvbWlkZGxld2FyZSc7XG5pbXBvcnQge21pZGRsZXdhcmVzSW50ZXJjZXB0b3J9IGZyb20gJy4vZ3JwYy9taWRkbGV3YXJlcy1pbnRlcmNlcHRvcic7XG5pbXBvcnQge2NhY2hlX2NsaWVudH0gZnJvbSAnQGdvbW9tZW50by9nZW5lcmF0ZWQtdHlwZXMvZGlzdC9jYWNoZWNsaWVudCc7XG5pbXBvcnQge0NvbmZpZ3VyYXRpb259IGZyb20gJy4uL2NvbmZpZy9jb25maWd1cmF0aW9uJztcbmltcG9ydCB7XG4gIFNlbWFwaG9yZSxcbiAgdmFsaWRhdGVDYWNoZU5hbWUsXG4gIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUsXG4gIHZhbGlkYXRlTGlzdE5hbWUsXG4gIHZhbGlkYXRlTGlzdFNsaWNlU3RhcnRFbmQsXG4gIHZhbGlkYXRlU2V0TmFtZSxcbiAgdmFsaWRhdGVTZXRQb3BDb3VudCxcbiAgdmFsaWRhdGVTZXRTYW1wbGVMaW1pdCxcbiAgdmFsaWRhdGVTb3J0ZWRTZXRDb3VudCxcbiAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lLFxuICB2YWxpZGF0ZVNvcnRlZFNldE9mZnNldCxcbiAgdmFsaWRhdGVTb3J0ZWRTZXRSYW5rcyxcbiAgdmFsaWRhdGVTb3J0ZWRTZXRTY29yZXMsXG4gIHZhbGlkYXRlVHRsU2Vjb25kcyxcbiAgdmFsaWRhdGVWYWxpZEZvclNlY29uZHMsXG59IGZyb20gJ0Bnb21vbWVudG8vc2RrLWNvcmUvZGlzdC9zcmMvaW50ZXJuYWwvdXRpbHMnO1xuaW1wb3J0IHtcbiAgX0RpY3Rpb25hcnlHZXRSZXNwb25zZVBhcnQsXG4gIF9FQ2FjaGVSZXN1bHQsXG4gIF9Tb3J0ZWRTZXRHZXRTY29yZVJlc3BvbnNlUGFydCxcbn0gZnJvbSAnQGdvbW9tZW50by9zZGstY29yZS9kaXN0L3NyYy9tZXNzYWdlcy9yZXNwb25zZXMvZ3JwYy1yZXNwb25zZS10eXBlcyc7XG5pbXBvcnQge0lEYXRhQ2xpZW50fSBmcm9tICdAZ29tb21lbnRvL3Nkay1jb3JlL2Rpc3Qvc3JjL2ludGVybmFsL2NsaWVudHMnO1xuaW1wb3J0IHtDb25uZWN0aXZpdHlTdGF0ZX0gZnJvbSAnQGdycGMvZ3JwYy1qcy9idWlsZC9zcmMvY29ubmVjdGl2aXR5LXN0YXRlJztcbmltcG9ydCB7Q2FjaGVDbGllbnRBbGxQcm9wc30gZnJvbSAnLi9jYWNoZS1jbGllbnQtYWxsLXByb3BzJztcbmltcG9ydCB7Z3JwY0NoYW5uZWxPcHRpb25zRnJvbUdycGNDb25maWd9IGZyb20gJy4vZ3JwYy9ncnBjLWNoYW5uZWwtb3B0aW9ucyc7XG5pbXBvcnQge0Nvbm5lY3Rpb25FcnJvcn0gZnJvbSAnQGdvbW9tZW50by9zZGstY29yZS9kaXN0L3NyYy9lcnJvcnMnO1xuaW1wb3J0IHtjb21tb259IGZyb20gJ0Bnb21vbWVudG8vZ2VuZXJhdGVkLXR5cGVzL2Rpc3QvY29tbW9uJztcbmltcG9ydCB7XG4gIEdldEJhdGNoQ2FsbE9wdGlvbnMsXG4gIEdldENhbGxPcHRpb25zLFxuICBTZXRCYXRjaENhbGxPcHRpb25zLFxuICBTZXRCYXRjaEl0ZW0sXG4gIFNldENhbGxPcHRpb25zLFxuICBTZXRJZkFic2VudENhbGxPcHRpb25zLFxufSBmcm9tICdAZ29tb21lbnRvL3Nkay1jb3JlL2Rpc3Qvc3JjL3V0aWxzJztcbmltcG9ydCB7Q29tcHJlc3Npb25FcnJvcn0gZnJvbSAnLi4vZXJyb3JzL2NvbXByZXNzaW9uLWVycm9yJztcbmltcG9ydCBncnBjQ2FjaGUgPSBjYWNoZS5jYWNoZV9jbGllbnQ7XG5pbXBvcnQgRUNhY2hlUmVzdWx0ID0gY2FjaGVfY2xpZW50LkVDYWNoZVJlc3VsdDtcbmltcG9ydCBfSXRlbUdldFR5cGVSZXNwb25zZSA9IGNhY2hlX2NsaWVudC5fSXRlbUdldFR5cGVSZXNwb25zZTtcbmltcG9ydCBfVW5ib3VuZGVkID0gY29tbW9uLl9VbmJvdW5kZWQ7XG5pbXBvcnQgQWJzZW50ID0gY29tbW9uLkFic2VudDtcbmltcG9ydCBQcmVzZW50ID0gY29tbW9uLlByZXNlbnQ7XG5pbXBvcnQgRXF1YWwgPSBjb21tb24uRXF1YWw7XG5pbXBvcnQgTm90RXF1YWwgPSBjb21tb24uTm90RXF1YWw7XG5pbXBvcnQgUHJlc2VudEFuZE5vdEVxdWFsID0gY29tbW9uLlByZXNlbnRBbmROb3RFcXVhbDtcbmltcG9ydCBBYnNlbnRPckVxdWFsID0gY29tbW9uLkFic2VudE9yRXF1YWw7XG5pbXBvcnQge0NhY2hlU2V0TGVuZ3RoLCBDYWNoZVNldFBvcH0gZnJvbSAnQGdvbW9tZW50by9zZGstY29yZSc7XG5cbmV4cG9ydCBjb25zdCBDT05ORUNUSU9OX0lEX0tFWSA9IFN5bWJvbCgnY29ubmVjdGlvbklEJyk7XG5cbmludGVyZmFjZSBDb21wcmVzc2lvbkRldGFpbHMge1xuICB2YWx1ZUNvbXByZXNzb3I6IElDb21wcmVzc2lvbjtcbiAgY29tcHJlc3Npb25MZXZlbDogQ29tcHJlc3Npb25MZXZlbDtcbiAgYXV0b0RlY29tcHJlc3NFbmFibGVkOiBib29sZWFuO1xufVxuXG5leHBvcnQgY2xhc3MgQ2FjaGVEYXRhQ2xpZW50IGltcGxlbWVudHMgSURhdGFDbGllbnQge1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudFdyYXBwZXI6IEdycGNDbGllbnRXcmFwcGVyPGdycGNDYWNoZS5TY3NDbGllbnQ+O1xuICBwcml2YXRlIHJlYWRvbmx5IHRleHRFbmNvZGVyOiBUZXh0RW5jb2RlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWd1cmF0aW9uOiBDb25maWd1cmF0aW9uO1xuICBwcml2YXRlIHJlYWRvbmx5IGNyZWRlbnRpYWxQcm92aWRlcjogQ3JlZGVudGlhbFByb3ZpZGVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRUdGxTZWNvbmRzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdFRpbWVvdXRNczogbnVtYmVyO1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUzogbnVtYmVyID0gNSAqIDEwMDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyOiBNb21lbnRvTG9nZ2VyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNhY2hlU2VydmljZUVycm9yTWFwcGVyOiBDYWNoZVNlcnZpY2VFcnJvck1hcHBlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBpbnRlcmNlcHRvcnM6IEludGVyY2VwdG9yW107XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RyZWFtaW5nSW50ZXJjZXB0b3JzOiBJbnRlcmNlcHRvcltdO1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbXByZXNzaW9uRGV0YWlscz86IENvbXByZXNzaW9uRGV0YWlscztcbiAgcHJpdmF0ZSByZWFkb25seSByZXF1ZXN0Q29uY3VycmVuY3lTZW1hcGhvcmU6IFNlbWFwaG9yZSB8IHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogQHBhcmFtIHtDYWNoZUNsaWVudFByb3BzfSBwcm9wc1xuICAgKiBAcGFyYW0gZGF0YUNsaWVudElEXG4gICAqIEBwYXJhbSBzZW1hcGhvcmVcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3BzOiBDYWNoZUNsaWVudEFsbFByb3BzLFxuICAgIGRhdGFDbGllbnRJRDogc3RyaW5nLFxuICAgIHNlbWFwaG9yZTogU2VtYXBob3JlIHwgdW5kZWZpbmVkXG4gICkge1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IHByb3BzLmNvbmZpZ3VyYXRpb247XG4gICAgdGhpcy5jcmVkZW50aWFsUHJvdmlkZXIgPSBwcm9wcy5jcmVkZW50aWFsUHJvdmlkZXI7XG4gICAgdGhpcy5sb2dnZXIgPSB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0TG9nZ2VyRmFjdG9yeSgpLmdldExvZ2dlcih0aGlzKTtcbiAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyID0gbmV3IENhY2hlU2VydmljZUVycm9yTWFwcGVyKFxuICAgICAgcHJvcHMuY29uZmlndXJhdGlvbi5nZXRUaHJvd09uRXJyb3JzKClcbiAgICApO1xuICAgIGNvbnN0IGNvbXByZXNzaW9uID0gdGhpcy5jb25maWd1cmF0aW9uLmdldENvbXByZXNzaW9uU3RyYXRlZ3koKTtcbiAgICBpZiAoY29tcHJlc3Npb24gIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5jb21wcmVzc2lvbkRldGFpbHMgPSB7XG4gICAgICAgIHZhbHVlQ29tcHJlc3NvcjogY29tcHJlc3Npb24uY29tcHJlc3NvckZhY3RvcnksXG4gICAgICAgIGNvbXByZXNzaW9uTGV2ZWw6XG4gICAgICAgICAgY29tcHJlc3Npb24uY29tcHJlc3Npb25MZXZlbCA/PyBDb21wcmVzc2lvbkxldmVsLkJhbGFuY2VkLFxuICAgICAgICBhdXRvRGVjb21wcmVzc0VuYWJsZWQ6XG4gICAgICAgICAgKGNvbXByZXNzaW9uLmF1dG9tYXRpY0RlY29tcHJlc3Npb24gPz9cbiAgICAgICAgICAgIEF1dG9tYXRpY0RlY29tcHJlc3Npb24uRW5hYmxlZCkgPT09IEF1dG9tYXRpY0RlY29tcHJlc3Npb24uRW5hYmxlZCxcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29tcHJlc3Npb25EZXRhaWxzID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLnJlcXVlc3RDb25jdXJyZW5jeVNlbWFwaG9yZSA9IHNlbWFwaG9yZTtcblxuICAgIGNvbnN0IGdycGNDb25maWcgPSB0aGlzLmNvbmZpZ3VyYXRpb25cbiAgICAgIC5nZXRUcmFuc3BvcnRTdHJhdGVneSgpXG4gICAgICAuZ2V0R3JwY0NvbmZpZygpO1xuXG4gICAgdGhpcy5yZXF1ZXN0VGltZW91dE1zID1cbiAgICAgIGdycGNDb25maWcuZ2V0RGVhZGxpbmVNaWxsaXMoKSB8fFxuICAgICAgQ2FjaGVEYXRhQ2xpZW50LkRFRkFVTFRfUkVRVUVTVF9USU1FT1VUX01TO1xuICAgIHRoaXMudmFsaWRhdGVSZXF1ZXN0VGltZW91dCh0aGlzLnJlcXVlc3RUaW1lb3V0TXMpO1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgYENyZWF0aW5nIGNhY2hlIGNsaWVudCB1c2luZyBlbmRwb2ludDogJyR7dGhpcy5jcmVkZW50aWFsUHJvdmlkZXIuZ2V0Q2FjaGVFbmRwb2ludCgpfSdgXG4gICAgKTtcblxuICAgIGNvbnN0IGNoYW5uZWxPcHRpb25zID0gZ3JwY0NoYW5uZWxPcHRpb25zRnJvbUdycGNDb25maWcoZ3JwY0NvbmZpZyk7XG5cbiAgICB0aGlzLmNsaWVudFdyYXBwZXIgPSBuZXcgSWRsZUdycGNDbGllbnRXcmFwcGVyKHtcbiAgICAgIGNsaWVudEZhY3RvcnlGbjogKCkgPT4ge1xuICAgICAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgQ29uc3RydWN0aW5nIGNoYW5uZWwgZm9yIGNsaWVudElEICR7ZGF0YUNsaWVudElEfWApO1xuICAgICAgICByZXR1cm4gbmV3IGdycGNDYWNoZS5TY3NDbGllbnQoXG4gICAgICAgICAgdGhpcy5jcmVkZW50aWFsUHJvdmlkZXIuZ2V0Q2FjaGVFbmRwb2ludCgpLFxuICAgICAgICAgIHRoaXMuY3JlZGVudGlhbFByb3ZpZGVyLmlzQ2FjaGVFbmRwb2ludFNlY3VyZSgpXG4gICAgICAgICAgICA/IENoYW5uZWxDcmVkZW50aWFscy5jcmVhdGVTc2woKVxuICAgICAgICAgICAgOiBDaGFubmVsQ3JlZGVudGlhbHMuY3JlYXRlSW5zZWN1cmUoKSxcbiAgICAgICAgICBjaGFubmVsT3B0aW9uc1xuICAgICAgICApO1xuICAgICAgfSxcbiAgICAgIGxvZ2dlckZhY3Rvcnk6IHRoaXMuY29uZmlndXJhdGlvbi5nZXRMb2dnZXJGYWN0b3J5KCksXG4gICAgICBtYXhJZGxlTWlsbGlzOiB0aGlzLmNvbmZpZ3VyYXRpb25cbiAgICAgICAgLmdldFRyYW5zcG9ydFN0cmF0ZWd5KClcbiAgICAgICAgLmdldE1heElkbGVNaWxsaXMoKSxcbiAgICAgIG1heENsaWVudEFnZU1pbGxpczogdGhpcy5jb25maWd1cmF0aW9uXG4gICAgICAgIC5nZXRUcmFuc3BvcnRTdHJhdGVneSgpXG4gICAgICAgIC5nZXRNYXhDbGllbnRBZ2VNaWxsaXMoKSxcbiAgICB9KTtcblxuICAgIHRoaXMudGV4dEVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKTtcbiAgICB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzID0gcHJvcHMuZGVmYXVsdFR0bFNlY29uZHM7XG5cbiAgICAvLyB0aGlzIGNvbnRleHQgb2JqZWN0IGlzIGN1cnJlbnRseSBpbnRlcm5hbCBvbmx5IGJ1dCBjYW4gYmUgZXh0ZW5kZWQgaW4gdGhlIENvbmZpZ3VyYXRpb24gb2JqZWN0IGlzIHdlIHdhbnRzIGNsaWVudHNcbiAgICAvLyB0byBiZSBhYmxlIHRvIHNldCBpdC5cbiAgICBjb25zdCBjb250ZXh0OiBNaWRkbGV3YXJlUmVxdWVzdEhhbmRsZXJDb250ZXh0ID0ge307XG4gICAgY29udGV4dFtDT05ORUNUSU9OX0lEX0tFWV0gPSBkYXRhQ2xpZW50SUQ7XG5cbiAgICBjb25zdCBoZWFkZXJzID0gW1xuICAgICAgbmV3IEhlYWRlcignQXV0aG9yaXphdGlvbicsIHRoaXMuY3JlZGVudGlhbFByb3ZpZGVyLmdldEF1dGhUb2tlbigpKSxcbiAgICAgIG5ldyBIZWFkZXIoJ2FnZW50JywgYG5vZGVqczpjYWNoZToke3ZlcnNpb259YCksXG4gICAgICBuZXcgSGVhZGVyKCdyZWFkLWNvbmNlcm4nLCB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0UmVhZENvbmNlcm4oKSksXG4gICAgICBuZXcgSGVhZGVyKCdydW50aW1lLXZlcnNpb24nLCBgbm9kZWpzOiR7cHJvY2Vzcy52ZXJzaW9ucy5ub2RlfWApLFxuICAgIF07XG5cbiAgICB0aGlzLmludGVyY2VwdG9ycyA9IHRoaXMuaW5pdGlhbGl6ZUludGVyY2VwdG9ycyhcbiAgICAgIGhlYWRlcnMsXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uZ2V0TG9nZ2VyRmFjdG9yeSgpLFxuICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmdldE1pZGRsZXdhcmVzKCksXG4gICAgICBjb250ZXh0XG4gICAgKTtcbiAgICB0aGlzLnN0cmVhbWluZ0ludGVyY2VwdG9ycyA9IHRoaXMuaW5pdGlhbGl6ZVN0cmVhbWluZ0ludGVyY2VwdG9ycyhoZWFkZXJzKTtcbiAgfVxuXG4gIGNsb3NlKCkge1xuICAgIHRoaXMubG9nZ2VyLmRlYnVnKCdDbG9zaW5nIGNhY2hlIGRhdGEgY2xpZW50Jyk7XG4gICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLmNsb3NlKCk7XG4gIH1cblxuICBwdWJsaWMgY29ubmVjdCh0aW1lb3V0U2Vjb25kcyA9IDEwKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5sb2dnZXIuZGVidWcoJ0F0dGVtcHRpbmcgdG8gZWFnZXJseSBjb25uZWN0IHRvIGNoYW5uZWwnKTtcbiAgICBjb25zdCBkZWFkbGluZSA9IG5ldyBEYXRlKCk7XG4gICAgZGVhZGxpbmUuc2V0U2Vjb25kcyhkZWFkbGluZS5nZXRTZWNvbmRzKCkgKyB0aW1lb3V0U2Vjb25kcyk7XG5cbiAgICByZXR1cm4gdGhpcy5jb25uZWN0V2l0aGluRGVhZGxpbmUoZGVhZGxpbmUpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25uZWN0aW9uU3RhdGVUb1N0cmluZyhzdGF0ZTogQ29ubmVjdGl2aXR5U3RhdGUpOiBzdHJpbmcge1xuICAgIHN3aXRjaCAoc3RhdGUpIHtcbiAgICAgIGNhc2UgQ29ubmVjdGl2aXR5U3RhdGUuSURMRTpcbiAgICAgICAgcmV0dXJuICdJRExFJztcbiAgICAgIGNhc2UgQ29ubmVjdGl2aXR5U3RhdGUuQ09OTkVDVElORzpcbiAgICAgICAgcmV0dXJuICdDT05ORUNUSU5HJztcbiAgICAgIGNhc2UgQ29ubmVjdGl2aXR5U3RhdGUuUkVBRFk6XG4gICAgICAgIHJldHVybiAnUkVBRFknO1xuICAgICAgY2FzZSBDb25uZWN0aXZpdHlTdGF0ZS5UUkFOU0lFTlRfRkFJTFVSRTpcbiAgICAgICAgcmV0dXJuICdUUkFOU0lFTlRfRkFJTFVSRSc7XG4gICAgICBjYXNlIENvbm5lY3Rpdml0eVN0YXRlLlNIVVRET1dOOlxuICAgICAgICByZXR1cm4gJ1NIVVRET1dOJztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbm5lY3RXaXRoaW5EZWFkbGluZShkZWFkbGluZTogRGF0ZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBHZXQgdGhlIGN1cnJlbnQgc3RhdGUgYW5kIGluaXRpYXRlIGEgY29ubmVjdGlvblxuICAgICAgY29uc3QgY3VycmVudFN0YXRlID0gdGhpcy5jbGllbnRXcmFwcGVyXG4gICAgICAgIC5nZXRDbGllbnQoKVxuICAgICAgICAuZ2V0Q2hhbm5lbCgpXG4gICAgICAgIC5nZXRDb25uZWN0aXZpdHlTdGF0ZSh0cnVlKTtcblxuICAgICAgdGhpcy5sb2dnZXIuZGVidWcoYENsaWVudCBjb25uZWN0aXZpdHkgc3RhdGU6ICR7Y3VycmVudFN0YXRlfWApO1xuXG4gICAgICBpZiAoY3VycmVudFN0YXRlID09PSBDb25uZWN0aXZpdHlTdGF0ZS5SRUFEWSkge1xuICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgbm93ID0gbmV3IERhdGUoKTtcblxuICAgICAgaWYgKG5vdyA+PSBkZWFkbGluZSkge1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSAnVW5hYmxlIHRvIGNvbm5lY3QgdG8gTW9tZW50bzogZGVhZGxpbmUgZXhjZWVkZWQuJztcbiAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgcmVqZWN0KG5ldyBDb25uZWN0aW9uRXJyb3IoZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyXG4gICAgICAgIC5nZXRDbGllbnQoKVxuICAgICAgICAuZ2V0Q2hhbm5lbCgpXG4gICAgICAgIC53YXRjaENvbm5lY3Rpdml0eVN0YXRlKGN1cnJlbnRTdGF0ZSwgZGVhZGxpbmUsIChlcnJvcj86IEVycm9yKSA9PiB7XG4gICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBgVW5hYmxlIHRvIGVhZ2VybHkgY29ubmVjdCB0byBNb21lbnRvLiBQbGVhc2UgY29udGFjdCBNb21lbnRvIGlmIHRoaXMgcGVyc2lzdHMuIGN1cnJlbnRTdGF0ZTogJHt0aGlzLmNvbm5lY3Rpb25TdGF0ZVRvU3RyaW5nKFxuICAgICAgICAgICAgICBjdXJyZW50U3RhdGVcbiAgICAgICAgICAgICl9LCBlcnJvck5hbWU6ICR7ZXJyb3IubmFtZX0gOiBlcnJvck1lc3NhZ2U6ICR7XG4gICAgICAgICAgICAgIGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICAgIH0sIGVycm9yU3RhY2s6ICR7XG4gICAgICAgICAgICAgIGVycm9yLnN0YWNrID8gZXJyb3Iuc3RhY2sgOiAnU3RhY2sgdHJhY2UgdW5kZWZpbmVkJ1xuICAgICAgICAgICAgfWA7XG4gICAgICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihlcnJvck1lc3NhZ2UpO1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBDb25uZWN0aW9uRXJyb3IoZXJyb3JNZXNzYWdlKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgbmV3U3RhdGUgPSB0aGlzLmNsaWVudFdyYXBwZXJcbiAgICAgICAgICAgIC5nZXRDbGllbnQoKVxuICAgICAgICAgICAgLmdldENoYW5uZWwoKVxuICAgICAgICAgICAgLmdldENvbm5lY3Rpdml0eVN0YXRlKGZhbHNlKTtcblxuICAgICAgICAgIGlmIChuZXdTdGF0ZSA9PT0gQ29ubmVjdGl2aXR5U3RhdGUuUkVBRFkpIHtcbiAgICAgICAgICAgIHRoaXMubG9nZ2VyLmRlYnVnKFxuICAgICAgICAgICAgICBgQ29ubmVjdGVkISBDdXJyZW50IHN0YXRlOiAke3RoaXMuY29ubmVjdGlvblN0YXRlVG9TdHJpbmcoXG4gICAgICAgICAgICAgICAgbmV3U3RhdGVcbiAgICAgICAgICAgICAgKX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0gZWxzZSBpZiAobmV3U3RhdGUgPT09IENvbm5lY3Rpdml0eVN0YXRlLkNPTk5FQ1RJTkcpIHtcbiAgICAgICAgICAgIC8vIFRoZSBjb25uZWN0aW9uIGdvZXMgdGhyb3VnaCB0aGUgQ09OTkVDVElORyBzdGF0ZSBiZWZvcmUgYmVjb21pbmcgUkVBRFksXG4gICAgICAgICAgICAvLyBzbyB3ZSBtdXN0IHdhdGNoIGl0IHR3aWNlLlxuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZGVidWcoXG4gICAgICAgICAgICAgIGBDb25uZWN0aW5nISBDdXJyZW50IHN0YXRlOiAke3RoaXMuY29ubmVjdGlvblN0YXRlVG9TdHJpbmcoXG4gICAgICAgICAgICAgICAgbmV3U3RhdGVcbiAgICAgICAgICAgICAgKX1gXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5jb25uZWN0V2l0aGluRGVhZGxpbmUoZGVhZGxpbmUpLnRoZW4ocmVzb2x2ZSkuY2F0Y2gocmVqZWN0KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gYFVuYWJsZSB0byBjb25uZWN0IHRvIE1vbWVudG86IFVuZXhwZWN0ZWQgY29ubmVjdGlvbiBzdGF0ZTogJHt0aGlzLmNvbm5lY3Rpb25TdGF0ZVRvU3RyaW5nKFxuICAgICAgICAgICAgICBuZXdTdGF0ZVxuICAgICAgICAgICAgKX0uLCBvbGRTdGF0ZTogJHt0aGlzLmNvbm5lY3Rpb25TdGF0ZVRvU3RyaW5nKGN1cnJlbnRTdGF0ZSl9XG4gICAgICAgICAgICAgIFBsZWFzZSBjb250YWN0IE1vbWVudG8gaWYgdGhpcyBwZXJzaXN0cy5gO1xuICAgICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICAgICAgICAgIHJlamVjdChuZXcgQ29ubmVjdGlvbkVycm9yKGVycm9yTWVzc2FnZSkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RW5kcG9pbnQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBlbmRwb2ludCA9IHRoaXMuY3JlZGVudGlhbFByb3ZpZGVyLmdldENhY2hlRW5kcG9pbnQoKTtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgVXNpbmcgY2FjaGUgZW5kcG9pbnQ6ICR7ZW5kcG9pbnR9YCk7XG4gICAgcmV0dXJuIGVuZHBvaW50O1xuICB9XG5cbiAgcHJpdmF0ZSB2YWxpZGF0ZVJlcXVlc3RUaW1lb3V0KHRpbWVvdXQ/OiBudW1iZXIpIHtcbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhgUmVxdWVzdCB0aW1lb3V0IG1zOiAke1N0cmluZyh0aW1lb3V0KX1gKTtcbiAgICBpZiAodGltZW91dCAhPT0gdW5kZWZpbmVkICYmIHRpbWVvdXQgPD0gMCkge1xuICAgICAgdGhyb3cgbmV3IEludmFsaWRBcmd1bWVudEVycm9yKFxuICAgICAgICAncmVxdWVzdCB0aW1lb3V0IG11c3QgYmUgZ3JlYXRlciB0aGFuIHplcm8uJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRFQ2FjaGVSZXN1bHQocmVzdWx0OiBncnBjQ2FjaGUuRUNhY2hlUmVzdWx0KTogX0VDYWNoZVJlc3VsdCB7XG4gICAgc3dpdGNoIChyZXN1bHQpIHtcbiAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5IaXQ6XG4gICAgICAgIHJldHVybiBfRUNhY2hlUmVzdWx0LkhpdDtcbiAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5JbnZhbGlkOlxuICAgICAgICByZXR1cm4gX0VDYWNoZVJlc3VsdC5JbnZhbGlkO1xuICAgICAgY2FzZSBncnBjQ2FjaGUuRUNhY2hlUmVzdWx0Lk1pc3M6XG4gICAgICAgIHJldHVybiBfRUNhY2hlUmVzdWx0Lk1pc3M7XG4gICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuT2s6XG4gICAgICAgIHJldHVybiBfRUNhY2hlUmVzdWx0Lk9rO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY29udmVydEl0ZW1UeXBlUmVzdWx0KFxuICAgIHJlc3VsdDogX0l0ZW1HZXRUeXBlUmVzcG9uc2UuSXRlbVR5cGVcbiAgKTogSXRlbVR5cGUge1xuICAgIHN3aXRjaCAocmVzdWx0KSB7XG4gICAgICBjYXNlIF9JdGVtR2V0VHlwZVJlc3BvbnNlLkl0ZW1UeXBlLlNDQUxBUjpcbiAgICAgICAgcmV0dXJuIEl0ZW1UeXBlLlNDQUxBUjtcbiAgICAgIGNhc2UgX0l0ZW1HZXRUeXBlUmVzcG9uc2UuSXRlbVR5cGUuTElTVDpcbiAgICAgICAgcmV0dXJuIEl0ZW1UeXBlLkxJU1Q7XG4gICAgICBjYXNlIF9JdGVtR2V0VHlwZVJlc3BvbnNlLkl0ZW1UeXBlLkRJQ1RJT05BUlk6XG4gICAgICAgIHJldHVybiBJdGVtVHlwZS5ESUNUSU9OQVJZO1xuICAgICAgY2FzZSBfSXRlbUdldFR5cGVSZXNwb25zZS5JdGVtVHlwZS5TRVQ6XG4gICAgICAgIHJldHVybiBJdGVtVHlwZS5TRVQ7XG4gICAgICBjYXNlIF9JdGVtR2V0VHlwZVJlc3BvbnNlLkl0ZW1UeXBlLlNPUlRFRF9TRVQ6XG4gICAgICAgIHJldHVybiBJdGVtVHlwZS5TT1JURURfU0VUO1xuICAgIH1cbiAgfVxuXG4gIC8vIElmIG1heENvbmN1cnJlbnRSZXF1ZXN0cyBpcyBzZXQsIHVzZSB0aGUgc2VtYXBob3JlIHRvIGxpbWl0IHRoZSBudW1iZXIgb2YgY29uY3VycmVudCByZXF1ZXN0cy5cbiAgLy8gT3RoZXJ3aXNlLCBleGVjdXRlIHRoZSBjYWNoZSBvcGVyYXRpb24gd2l0aG91dCBhbnkgcmF0ZSBsaW1pdGluZy5cbiAgcHJpdmF0ZSBhc3luYyByYXRlTGltaXRlZDxUPihjYWNoZU9wZXJhdGlvbjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5yZXF1ZXN0Q29uY3VycmVuY3lTZW1hcGhvcmUgIT09IHVuZGVmaW5lZClcbiAgICAgICAgYXdhaXQgdGhpcy5yZXF1ZXN0Q29uY3VycmVuY3lTZW1hcGhvcmUuYWNxdWlyZSgpO1xuXG4gICAgICByZXR1cm4gYXdhaXQgY2FjaGVPcGVyYXRpb24oKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKHRoaXMucmVxdWVzdENvbmN1cnJlbmN5U2VtYXBob3JlICE9PSB1bmRlZmluZWQpXG4gICAgICAgIHRoaXMucmVxdWVzdENvbmN1cnJlbmN5U2VtYXBob3JlLnJlbGVhc2UoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogU2V0Q2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZVNldC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKG9wdGlvbnM/LnR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyhvcHRpb25zLnR0bCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHR0bFRvVXNlID0gb3B0aW9ucz8udHRsIHx8IHRoaXMuZGVmYXVsdFR0bFNlY29uZHM7XG4gICAgY29uc3QgZW5jb2RlZEtleSA9IHRoaXMuY29udmVydChrZXkpO1xuICAgIGxldCBlbmNvZGVkVmFsdWUgPSB0aGlzLmNvbnZlcnQodmFsdWUpO1xuICAgIGlmIChvcHRpb25zPy5jb21wcmVzcykge1xuICAgICAgdGhpcy5sb2dnZXIudHJhY2UoXG4gICAgICAgICdDYWNoZUNsaWVudC5zZXQ7IGNvbXByZXNzaW9uIGVuYWJsZWQsIGNhbGxpbmcgdmFsdWUgY29tcHJlc3NvcidcbiAgICAgICk7XG4gICAgICBpZiAodGhpcy5jb21wcmVzc2lvbkRldGFpbHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgICAgbmV3IENvbXByZXNzaW9uRXJyb3IoJ0NhY2hlQ2xpZW50LnNldCcsICdjb21wcmVzcycpLFxuICAgICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXQuRXJyb3IoZXJyKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZW5jb2RlZFZhbHVlID0gYXdhaXQgdGhpcy5jb21wcmVzc2lvbkRldGFpbHMudmFsdWVDb21wcmVzc29yLmNvbXByZXNzKFxuICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy5jb21wcmVzc2lvbkxldmVsLFxuICAgICAgICBlbmNvZGVkVmFsdWVcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldChjYWNoZU5hbWUsIGVuY29kZWRLZXksIGVuY29kZWRWYWx1ZSwgdHRsVG9Vc2UpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICB0dGw6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldFJlcXVlc3Qoe1xuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICBjYWNoZV9rZXk6IGtleSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bCAqIDEwMDAsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXQoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldC5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0RmV0Y2goXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXROYW1lKHNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRGZXRjaC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRGZXRjaChjYWNoZU5hbWUsIHRoaXMuY29udmVydChzZXROYW1lKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRGZXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRGZXRjaFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNldE5hbWUsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRGZXRjaChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0RmV0Y2guTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldEZldGNoLkhpdChyZXNwLmZvdW5kLmVsZW1lbnRzKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTZXRGZXRjaC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldEFkZEVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IHN0cmluZyxcbiAgICBlbGVtZW50czogc3RyaW5nW10gfCBVaW50OEFycmF5W10sXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlU2V0QWRkRWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU2V0TmFtZShzZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0QWRkRWxlbWVudHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0QWRkRWxlbWVudHMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnRBcnJheShlbGVtZW50cyksXG4gICAgICAgIHR0bC50dGxNaWxsaXNlY29uZHMoKSB8fCB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMCxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldEFkZEVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZWxlbWVudHM6IFVpbnQ4QXJyYXlbXSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlcixcbiAgICByZWZyZXNoVHRsOiBib29sZWFuXG4gICk6IFByb21pc2U8Q2FjaGVTZXRBZGRFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRVbmlvblJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNldE5hbWUsXG4gICAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICByZWZyZXNoX3R0bDogcmVmcmVzaFR0bCxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldFVuaW9uKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldEFkZEVsZW1lbnRzLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRBZGRFbGVtZW50cy5TdWNjZXNzKCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRDb250YWluc0VsZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogc3RyaW5nLFxuICAgIGVsZW1lbnQ6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZVNldENvbnRhaW5zRWxlbWVudC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXROYW1lKHNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRDb250YWluc0VsZW1lbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0Q29udGFpbnNFbGVtZW50KFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzZXROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGVsZW1lbnQpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0Q29udGFpbnNFbGVtZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZWxlbWVudDogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlU2V0Q29udGFpbnNFbGVtZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldENvbnRhaW5zUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc2V0TmFtZSxcbiAgICAgIGVsZW1lbnRzOiBbZWxlbWVudF0sXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRDb250YWlucyhcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICBjb25zdCBmb3VuZF9tYXNrID0gcmVzcD8uZm91bmQuY29udGFpbnM7XG4gICAgICAgICAgICBpZiAoZm91bmRfbWFzayA9PT0gdW5kZWZpbmVkIHx8IGZvdW5kX21hc2subGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIHJldHVybiByZWplY3QoXG4gICAgICAgICAgICAgICAgbmV3IENhY2hlU2V0Q29udGFpbnNFbGVtZW50LkVycm9yKFxuICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcignU2V0Q29udGFpbnMgcmVzcG9uc2UgbWlzc2luZyBjb250YWlucyBtYXNrJylcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudC5IaXQoZm91bmRfbWFza1swXSkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRDb250YWluc0VsZW1lbnQuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldENvbnRhaW5zRWxlbWVudHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogc3RyaW5nLFxuICAgIGVsZW1lbnRzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlU2V0Q29udGFpbnNFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXROYW1lKHNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRDb250YWluc0VsZW1lbnRzLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldENvbnRhaW5zRWxlbWVudHMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnRBcnJheShlbGVtZW50cylcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRDb250YWluc0VsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZWxlbWVudHM6IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlU2V0Q29udGFpbnNFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRDb250YWluc1JlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNldE5hbWUsXG4gICAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRDb250YWlucyhcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRDb250YWluc0VsZW1lbnRzLkhpdChlbGVtZW50cywgcmVzcD8uZm91bmQuY29udGFpbnMpXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRDb250YWluc0VsZW1lbnRzLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNldENvbnRhaW5zRWxlbWVudHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRSZW1vdmVFbGVtZW50cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudHM6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVTZXRSZW1vdmVFbGVtZW50cy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTZXROYW1lKHNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRSZW1vdmVFbGVtZW50cy5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRSZW1vdmVFbGVtZW50cyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc2V0TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydEFycmF5KGVsZW1lbnRzKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldFJlbW92ZUVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZWxlbWVudHM6IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlU2V0UmVtb3ZlRWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCBzdWJ0cmFoZW5kID0gbmV3IGdycGNDYWNoZS5fU2V0RGlmZmVyZW5jZVJlcXVlc3QuX1N1YnRyYWhlbmQoe1xuICAgICAgc2V0OiBuZXcgZ3JwY0NhY2hlLl9TZXREaWZmZXJlbmNlUmVxdWVzdC5fU3VidHJhaGVuZC5fU2V0KHtcbiAgICAgICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgICAgfSksXG4gICAgfSk7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldERpZmZlcmVuY2VSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzZXROYW1lLFxuICAgICAgc3VidHJhaGVuZDogc3VidHJhaGVuZCxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0RGlmZmVyZW5jZShcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTZXRSZW1vdmVFbGVtZW50cy5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0UmVtb3ZlRWxlbWVudHMuU3VjY2VzcygpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0U2FtcGxlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IHN0cmluZyxcbiAgICBsaW1pdDogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRTYW1wbGUuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU2V0TmFtZShzZXROYW1lKTtcbiAgICAgIHZhbGlkYXRlU2V0U2FtcGxlTGltaXQobGltaXQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRTYW1wbGUuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0U2FtcGxlKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KHNldE5hbWUpLCBsaW1pdCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRTYW1wbGUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogVWludDhBcnJheSxcbiAgICBsaW1pdDogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRTYW1wbGUuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0U2FtcGxlUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc2V0TmFtZSxcbiAgICAgIGxpbWl0OiBsaW1pdCxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldFNhbXBsZShcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0U2FtcGxlLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRTYW1wbGUuSGl0KHJlc3AuZm91bmQuZWxlbWVudHMpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldFNhbXBsZS5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNldFBvcChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzZXROYW1lOiBzdHJpbmcsXG4gICAgY291bnQ6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0UG9wLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNldE5hbWUoc2V0TmFtZSk7XG4gICAgICB2YWxpZGF0ZVNldFBvcENvdW50KGNvdW50KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0UG9wLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldFBvcChjYWNoZU5hbWUsIHRoaXMuY29udmVydChzZXROYW1lKSwgY291bnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2V0UG9wKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgY291bnQ6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0UG9wLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldFBvcFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNldE5hbWUsXG4gICAgICBjb3VudDogY291bnQsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRQb3AoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldFBvcC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0UG9wLkhpdChyZXNwLmZvdW5kLmVsZW1lbnRzKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTZXRQb3AuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVTZXRMZW5ndGguUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU2V0TmFtZShzZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0TGVuZ3RoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldExlbmd0aChjYWNoZU5hbWUsIHRoaXMuY29udmVydChzZXROYW1lKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc2V0TmFtZTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlU2V0TGVuZ3RoLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldExlbmd0aFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNldE5hbWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldExlbmd0aChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0TGVuZ3RoLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgaWYgKCFyZXNwLmZvdW5kLmxlbmd0aCkge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldExlbmd0aC5NaXNzKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRMZW5ndGguSGl0KHJlc3AuZm91bmQubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTZXRMZW5ndGguRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIHNldElmTm90RXhpc3RzIGlzIGRlcHJlY2F0ZWQgb24gdGhlIHNlcnZpY2UuIEhlcmUgd2UgY2FsbCB0aGUgbmV3IGBTZXRJZmAgbWV0aG9kIHdpdGggdGhlIGFic2VudCBmaWVsZCBzZXRcbiAgLy8gYW5kIHJldHVybiBgQ2FjaGVTZXRJZk5vdEV4aXN0c2AgcmVzcG9uc2VzLlxuICBwdWJsaWMgYXN5bmMgc2V0SWZOb3RFeGlzdHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bD86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZOb3RFeGlzdHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIGlmICh0dGwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWxpZGF0ZVR0bFNlY29uZHModHRsKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0SWZOb3RFeGlzdHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0SWZOb3RFeGlzdHMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGtleSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSksXG4gICAgICAgIHR0bCA/IHR0bCAqIDEwMDAgOiB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldElmTm90RXhpc3RzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZOb3RFeGlzdHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0SWZSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICBhYnNlbnQ6IG5ldyBBYnNlbnQoKSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0SWYoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZk5vdEV4aXN0cy5TdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ25vdF9zdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZOb3RFeGlzdHMuTm90U3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRJZk5vdEV4aXN0cy5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnU2V0SWZOb3RFeGlzdHMgcmVzcG9uZGVkIHdpdGggYW4gdW5rbm93biByZXN1bHQnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0SWZOb3RFeGlzdHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRJZkFic2VudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgb3B0aW9ucz86IFNldElmQWJzZW50Q2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmQWJzZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgdHRsID0gb3B0aW9ucz8udHRsO1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZkFic2VudC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBlbmNvZGVkVmFsdWUgPSB0aGlzLmNvbnZlcnQodmFsdWUpO1xuICAgICAgaWYgKG9wdGlvbnM/LmNvbXByZXNzKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLnRyYWNlKFxuICAgICAgICAgICdDYWNoZUNsaWVudC5zZXRJZkFic2VudDsgY29tcHJlc3Npb24gZW5hYmxlZCwgY2FsbGluZyB2YWx1ZSBjb21wcmVzc29yJ1xuICAgICAgICApO1xuICAgICAgICBpZiAodGhpcy5jb21wcmVzc2lvbkRldGFpbHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgICAgIG5ldyBJbnZhbGlkQXJndW1lbnRFcnJvcihcbiAgICAgICAgICAgICAgJ0NvbXByZXNzb3IgaXMgbm90IHNldCwgYnV0IGBDYWNoZUNsaWVudC5zZXRJZkFic2VudGAgd2FzIGNhbGxlZCB3aXRoIHRoZSBgY29tcHJlc3NgIG9wdGlvbjsgcGxlYXNlIGluc3RhbGwgQGdvbW9tZW50by9zZGstbm9kZWpzLWNvbXByZXNzaW9uIGFuZCBjYWxsIGBDb25maWd1cmF0aW9uLndpdGhDb21wcmVzc2lvblN0cmF0ZWd5YCB0byBlbmFibGUgY29tcHJlc3Npb24uJ1xuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZkFic2VudC5FcnJvcihlcnIpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBlbmNvZGVkVmFsdWUgPSBhd2FpdCB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3IuY29tcHJlc3MoXG4gICAgICAgICAgdGhpcy5jb21wcmVzc2lvbkRldGFpbHMuY29tcHJlc3Npb25MZXZlbCxcbiAgICAgICAgICBlbmNvZGVkVmFsdWVcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldElmQWJzZW50KFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICBlbmNvZGVkVmFsdWUsXG4gICAgICAgIHR0bCA/IHR0bCAqIDEwMDAgOiB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldElmQWJzZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZBYnNlbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0SWZSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICBhYnNlbnQ6IG5ldyBBYnNlbnQoKSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0SWYoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZkFic2VudC5TdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ25vdF9zdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZBYnNlbnQuTm90U3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRJZkFic2VudC5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnU2V0SWZBYnNlbnQgcmVzcG9uZGVkIHdpdGggYW4gdW5rbm93biByZXN1bHQnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0SWZBYnNlbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRJZlByZXNlbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bD86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZQcmVzZW50LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICBpZiAodHRsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsaWRhdGVUdGxTZWNvbmRzKHR0bCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldElmUHJlc2VudC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRJZlByZXNlbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGtleSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSksXG4gICAgICAgIHR0bCA/IHR0bCAqIDEwMDAgOiB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldElmUHJlc2VudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmUHJlc2VudC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRJZlJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgICBjYWNoZV9ib2R5OiB2YWx1ZSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHByZXNlbnQ6IG5ldyBQcmVzZW50KCksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNldElmKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgc3dpdGNoIChyZXNwLnJlc3VsdCkge1xuICAgICAgICAgICAgICBjYXNlICdzdG9yZWQnOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0SWZQcmVzZW50LlN0b3JlZCgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAnbm90X3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZlByZXNlbnQuTm90U3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRJZlByZXNlbnQuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ1NldElmUHJlc2VudCByZXNwb25kZWQgd2l0aCBhbiB1bmtub3duIHJlc3VsdCdcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTZXRJZlByZXNlbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRJZkVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBlcXVhbDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmRXF1YWwuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIGlmICh0dGwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWxpZGF0ZVR0bFNlY29uZHModHRsKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0SWZFcXVhbC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRJZkVxdWFsKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZXF1YWwpLFxuICAgICAgICB0dGwgPyB0dGwgKiAxMDAwIDogdGhpcy5kZWZhdWx0VHRsU2Vjb25kcyAqIDEwMDBcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRJZkVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICBlcXVhbDogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZFcXVhbC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRJZlJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgICBjYWNoZV9ib2R5OiB2YWx1ZSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIGVxdWFsOiBuZXcgRXF1YWwoe3ZhbHVlX3RvX2NoZWNrOiBlcXVhbH0pLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRJZihcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHN3aXRjaCAocmVzcC5yZXN1bHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAnc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmRXF1YWwuU3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdub3Rfc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmRXF1YWwuTm90U3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXRJZkVxdWFsLkVycm9yKFxuICAgICAgICAgICAgICAgICAgICBuZXcgVW5rbm93bkVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICdTZXRJZkVxdWFsIHJlc3BvbmRlZCB3aXRoIGFuIHVua25vd24gcmVzdWx0J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldElmRXF1YWwuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRJZk5vdEVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBub3RFcXVhbDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmTm90RXF1YWwuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIGlmICh0dGwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWxpZGF0ZVR0bFNlY29uZHModHRsKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0SWZOb3RFcXVhbC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTZXRJZk5vdEVxdWFsKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQobm90RXF1YWwpLFxuICAgICAgICB0dGwgPyB0dGwgKiAxMDAwIDogdGhpcy5kZWZhdWx0VHRsU2Vjb25kcyAqIDEwMDBcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRJZk5vdEVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICBub3RFcXVhbDogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZOb3RFcXVhbC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9TZXRJZlJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgICBjYWNoZV9ib2R5OiB2YWx1ZSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIG5vdF9lcXVhbDogbmV3IE5vdEVxdWFsKHt2YWx1ZV90b19jaGVjazogbm90RXF1YWx9KSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0SWYoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZk5vdEVxdWFsLlN0b3JlZCgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAnbm90X3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZk5vdEVxdWFsLk5vdFN0b3JlZCgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU2V0SWZOb3RFcXVhbC5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnU2V0SWZOb3RFcXVhbCByZXNwb25kZWQgd2l0aCBhbiB1bmtub3duIHJlc3VsdCdcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTZXRJZk5vdEVxdWFsLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0SWZQcmVzZW50QW5kTm90RXF1YWwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG5vdEVxdWFsOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bD86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZQcmVzZW50QW5kTm90RXF1YWwuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIGlmICh0dGwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWxpZGF0ZVR0bFNlY29uZHModHRsKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU2V0SWZQcmVzZW50QW5kTm90RXF1YWwuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0SWZQcmVzZW50QW5kTm90RXF1YWwoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGtleSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSksXG4gICAgICAgIHRoaXMuY29udmVydChub3RFcXVhbCksXG4gICAgICAgIHR0bCA/IHR0bCAqIDEwMDAgOiB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMFxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNldElmUHJlc2VudEFuZE5vdEVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICB2YWx1ZTogVWludDhBcnJheSxcbiAgICBub3RFcXVhbDogVWludDhBcnJheSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU2V0SWZQcmVzZW50QW5kTm90RXF1YWwuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0SWZSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICBwcmVzZW50X2FuZF9ub3RfZXF1YWw6IG5ldyBQcmVzZW50QW5kTm90RXF1YWwoe3ZhbHVlX3RvX2NoZWNrOiBub3RFcXVhbH0pLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRJZihcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHN3aXRjaCAocmVzcC5yZXN1bHQpIHtcbiAgICAgICAgICAgICAgY2FzZSAnc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLlN0b3JlZCgpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgY2FzZSAnbm90X3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZlByZXNlbnRBbmROb3RFcXVhbC5Ob3RTdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLkVycm9yKFxuICAgICAgICAgICAgICAgICAgICBuZXcgVW5rbm93bkVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICdTZXRJZlByZXNlbnRBbmROb3RFcXVhbCByZXNwb25kZWQgd2l0aCBhbiB1bmtub3duIHJlc3VsdCdcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNldElmUHJlc2VudEFuZE5vdEVxdWFsLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc2V0SWZBYnNlbnRPckVxdWFsKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBlcXVhbDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNldElmQWJzZW50T3JFcXVhbC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTZXRJZkFic2VudE9yRXF1YWwuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU2V0SWZBYnNlbnRPckVxdWFsKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChrZXkpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZXF1YWwpLFxuICAgICAgICB0dGwgPyB0dGwgKiAxMDAwIDogdGhpcy5kZWZhdWx0VHRsU2Vjb25kcyAqIDEwMDBcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRJZkFic2VudE9yRXF1YWwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5LFxuICAgIGVxdWFsOiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTZXRJZkFic2VudE9yRXF1YWwuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0SWZSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgY2FjaGVfYm9keTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICBhYnNlbnRfb3JfZXF1YWw6IG5ldyBBYnNlbnRPckVxdWFsKHt2YWx1ZV90b19jaGVjazogZXF1YWx9KSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU2V0SWYoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgJ3N0b3JlZCc6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTZXRJZkFic2VudE9yRXF1YWwuU3RvcmVkKCkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdub3Rfc3RvcmVkJzpcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNldElmQWJzZW50T3JFcXVhbC5Ob3RTdG9yZWQoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNldElmQWJzZW50T3JFcXVhbC5FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAnU2V0SWZBYnNlbnRPckVxdWFsIHJlc3BvbmRlZCB3aXRoIGFuIHVua25vd24gcmVzdWx0J1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNldElmQWJzZW50T3JFcXVhbC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRlbGV0ZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZURlbGV0ZS5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEZWxldGUuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGVsZXRlKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGtleSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGVsZXRlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlRGVsZXRlLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0RlbGV0ZVJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EZWxldGUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURlbGV0ZS5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlRGVsZXRlLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZ2V0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogR2V0Q2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZUdldC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVHZXQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kR2V0KGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGtleSksIG9wdGlvbnMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kR2V0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheSxcbiAgICBvcHRpb25zPzogR2V0Q2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZUdldC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9HZXRSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5HZXQoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBzd2l0Y2ggKHJlc3AucmVzdWx0KSB7XG4gICAgICAgICAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5NaXNzOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlR2V0Lk1pc3MoKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5IaXQ6IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzaG91bGREZWNvbXByZXNzID1cbiAgICAgICAgICAgICAgICAgIG9wdGlvbnM/LmRlY29tcHJlc3MgPz9cbiAgICAgICAgICAgICAgICAgIHRoaXMuY29tcHJlc3Npb25EZXRhaWxzPy5hdXRvRGVjb21wcmVzc0VuYWJsZWQgPT09IHRydWU7XG4gICAgICAgICAgICAgICAgaWYgKCFzaG91bGREZWNvbXByZXNzKSB7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUdldC5IaXQocmVzcC5jYWNoZV9ib2R5KSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbXByZXNzaW9uRGV0YWlscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICAgICAgbmV3IENhY2hlR2V0LkVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IENvbXByZXNzaW9uRXJyb3IoJ0NhY2hlQ2xpZW50LkdldCcsICdkZWNvbXByZXNzJylcbiAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3JcbiAgICAgICAgICAgICAgICAgICAgICAuZGVjb21wcmVzc0lmQ29tcHJlc3NlZChyZXNwLmNhY2hlX2JvZHkpXG4gICAgICAgICAgICAgICAgICAgICAgLnRoZW4odiA9PiByZXNvbHZlKG5ldyBDYWNoZUdldC5IaXQodikpKVxuICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlID0+XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3Jlc3RyaWN0LXRlbXBsYXRlLWV4cHJlc3Npb25zXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZUdldC5FcnJvcihuZXcgSW52YWxpZEFyZ3VtZW50RXJyb3IoYCR7ZX1gKSlcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuSW52YWxpZDpcbiAgICAgICAgICAgICAgY2FzZSBncnBjQ2FjaGUuRUNhY2hlUmVzdWx0Lk9rOlxuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlR2V0LkVycm9yKG5ldyBVbmtub3duRXJyb3IocmVzcC5tZXNzYWdlKSkpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVHZXQuRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ0FuIHVua25vd24gZXJyb3Igb2NjdXJyZWQ6ICcgKyByZXNwLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVHZXQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBnZXRCYXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXlzOiBBcnJheTxzdHJpbmcgfCBVaW50OEFycmF5PixcbiAgICBvcHRpb25zPzogR2V0QmF0Y2hDYWxsT3B0aW9uc1xuICApOiBQcm9taXNlPENhY2hlR2V0QmF0Y2guUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlR2V0QmF0Y2guRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kR2V0QmF0Y2goXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAga2V5cy5tYXAoa2V5ID0+IHRoaXMuY29udmVydChrZXkpKSxcbiAgICAgICAgb3B0aW9ucz8uZGVjb21wcmVzc1xuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEdldEJhdGNoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleXM6IFVpbnQ4QXJyYXlbXSxcbiAgICBkZWNvbXByZXNzPzogYm9vbGVhblxuICApOiBQcm9taXNlPENhY2hlR2V0QmF0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCBnZXRSZXF1ZXN0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgayBvZiBrZXlzKSB7XG4gICAgICBjb25zdCBnZXRSZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fR2V0UmVxdWVzdCh7XG4gICAgICAgIGNhY2hlX2tleTogayxcbiAgICAgIH0pO1xuICAgICAgZ2V0UmVxdWVzdHMucHVzaChnZXRSZXF1ZXN0KTtcbiAgICB9XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0dldEJhdGNoUmVxdWVzdCh7XG4gICAgICBpdGVtczogZ2V0UmVxdWVzdHMsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICBjb25zdCBjYWxsID0gdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkdldEJhdGNoKHJlcXVlc3QsIG1ldGFkYXRhLCB7XG4gICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuc3RyZWFtaW5nSW50ZXJjZXB0b3JzLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdHM6IENhY2hlR2V0LlJlc3BvbnNlW10gPSBbXTtcbiAgICAgIGNhbGwub24oJ2RhdGEnLCAoZ2V0UmVzcG9uc2U6IGdycGNDYWNoZS5fR2V0UmVzcG9uc2UpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZ2V0UmVzcG9uc2UucmVzdWx0O1xuICAgICAgICBzd2l0Y2ggKHJlc3VsdCkge1xuICAgICAgICAgIGNhc2UgZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5IaXQ6XG4gICAgICAgICAgICByZXN1bHRzLnB1c2gobmV3IENhY2hlR2V0LkhpdChnZXRSZXNwb25zZS5jYWNoZV9ib2R5KSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuTWlzczpcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChuZXcgQ2FjaGVHZXQuTWlzcygpKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXN1bHRzLnB1c2goXG4gICAgICAgICAgICAgIG5ldyBDYWNoZUdldC5FcnJvcihuZXcgVW5rbm93bkVycm9yKGdldFJlc3BvbnNlLm1lc3NhZ2UpKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNhbGwub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2hvdWxkRGVjb21wcmVzcyA9XG4gICAgICAgICAgZGVjb21wcmVzcyA/PyB0aGlzLmNvbXByZXNzaW9uRGV0YWlscz8uYXV0b0RlY29tcHJlc3NFbmFibGVkID09PSB0cnVlO1xuICAgICAgICBpZiAoIXNob3VsZERlY29tcHJlc3MpIHtcbiAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUdldEJhdGNoLlN1Y2Nlc3MocmVzdWx0cywga2V5cykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmNvbXByZXNzaW9uRGV0YWlscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICBuZXcgQ2FjaGVHZXRCYXRjaC5FcnJvcihcbiAgICAgICAgICAgICAgICBuZXcgQ29tcHJlc3Npb25FcnJvcignQ2FjaGVDbGllbnQuR2V0JywgJ2RlY29tcHJlc3MnKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjb21wcmVzc29yOiBJQ29tcHJlc3Npb24gPVxuICAgICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3I7XG4gICAgICAgICAgICBQcm9taXNlLmFsbChcbiAgICAgICAgICAgICAgcmVzdWx0cy5tYXAoYXN5bmMgciA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHIgaW5zdGFuY2VvZiBDYWNoZUdldC5IaXQpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQ2FjaGVHZXQuSGl0KFxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBjb21wcmVzc29yLmRlY29tcHJlc3NJZkNvbXByZXNzZWQoci52YWx1ZVVpbnQ4QXJyYXkoKSlcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAudGhlbihkZWNvbXByZXNzZWRSZXN1bHRzID0+XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVHZXRCYXRjaC5TdWNjZXNzKGRlY29tcHJlc3NlZFJlc3VsdHMsIGtleXMpKVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgIC5jYXRjaChlID0+XG4gICAgICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9yZXN0cmljdC10ZW1wbGF0ZS1leHByZXNzaW9uc1xuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlR2V0QmF0Y2guRXJyb3IobmV3IFVua25vd25FcnJvcihgJHtlfWApKSlcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjYWxsLm9uKCdlcnJvcicsIChlcnI6IFNlcnZpY2VFcnJvciB8IG51bGwpID0+IHtcbiAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVHZXRCYXRjaC5FcnJvcihlKSxcbiAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzZXRCYXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBpdGVtczpcbiAgICAgIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgVWludDhBcnJheT5cbiAgICAgIHwgTWFwPHN0cmluZyB8IFVpbnQ4QXJyYXksIHN0cmluZyB8IFVpbnQ4QXJyYXk+XG4gICAgICB8IEFycmF5PFNldEJhdGNoSXRlbT4sXG4gICAgb3B0aW9ucz86IFNldEJhdGNoQ2FsbE9wdGlvbnNcbiAgKTogUHJvbWlzZTxDYWNoZVNldEJhdGNoLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICBpZiAob3B0aW9ucz8udHRsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsaWRhdGVUdGxTZWNvbmRzKG9wdGlvbnM/LnR0bCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldEJhdGNoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgdHRsVG9Vc2UgPSBvcHRpb25zPy50dGwgfHwgdGhpcy5kZWZhdWx0VHRsU2Vjb25kcztcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIGxldCBpdGVtc1RvVXNlOiBbVWludDhBcnJheSwgVWludDhBcnJheSwgbnVtYmVyXVtdID1cbiAgICAgICAgdGhpcy5jb252ZXJ0U2V0QmF0Y2hFbGVtZW50cyhpdGVtcywgdHRsVG9Vc2UpO1xuICAgICAgaWYgKG9wdGlvbnM/LmNvbXByZXNzKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLnRyYWNlKFxuICAgICAgICAgICdDYWNoZUNsaWVudC5zZXRCYXRjaDsgY29tcHJlc3Npb24gZW5hYmxlZCwgY2FsbGluZyB2YWx1ZSBjb21wcmVzc29yJ1xuICAgICAgICApO1xuICAgICAgICBpZiAodGhpcy5jb21wcmVzc2lvbkRldGFpbHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgICAgIG5ldyBDb21wcmVzc2lvbkVycm9yKCdDYWNoZUNsaWVudC5zZXRCYXRjaCcsICdjb21wcmVzcycpLFxuICAgICAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNldEJhdGNoLkVycm9yKGVycilcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGNvbXByZXNzb3I6IElDb21wcmVzc2lvbiA9XG4gICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy52YWx1ZUNvbXByZXNzb3I7XG4gICAgICAgICAgY29uc3QgY29tcHJlc3Npb25MZXZlbDogQ29tcHJlc3Npb25MZXZlbCA9XG4gICAgICAgICAgICB0aGlzLmNvbXByZXNzaW9uRGV0YWlscy5jb21wcmVzc2lvbkxldmVsO1xuICAgICAgICAgIGl0ZW1zVG9Vc2UgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICAgIGl0ZW1zVG9Vc2UubWFwKGFzeW5jIChba2V5LCB2YWx1ZSwgdHRsXSkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICBhd2FpdCBjb21wcmVzc29yLmNvbXByZXNzKGNvbXByZXNzaW9uTGV2ZWwsIHZhbHVlKSxcbiAgICAgICAgICAgICAgICB0dGwsXG4gICAgICAgICAgICAgIF07XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNldEJhdGNoKGNhY2hlTmFtZSwgaXRlbXNUb1VzZSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXRCYXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBpdGVtczogW1VpbnQ4QXJyYXksIFVpbnQ4QXJyYXksIG51bWJlcl1bXVxuICApOiBQcm9taXNlPENhY2hlU2V0QmF0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCBzZXRSZXF1ZXN0cyA9IFtdO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgY29uc3Qgc2V0UmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NldFJlcXVlc3Qoe1xuICAgICAgICBjYWNoZV9rZXk6IGl0ZW1bMF0sXG4gICAgICAgIGNhY2hlX2JvZHk6IGl0ZW1bMV0sXG4gICAgICAgIHR0bF9taWxsaXNlY29uZHM6IGl0ZW1bMl0gKiAxMDAwLFxuICAgICAgfSk7XG4gICAgICBzZXRSZXF1ZXN0cy5wdXNoKHNldFJlcXVlc3QpO1xuICAgIH1cbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU2V0QmF0Y2hSZXF1ZXN0KHtcbiAgICAgIGl0ZW1zOiBzZXRSZXF1ZXN0cyxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgY29uc3QgY2FsbCA9IHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5TZXRCYXRjaChyZXF1ZXN0LCBtZXRhZGF0YSwge1xuICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLnN0cmVhbWluZ0ludGVyY2VwdG9ycyxcbiAgICB9KTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCByZXN1bHRzOiBDYWNoZVNldC5SZXNwb25zZVtdID0gW107XG4gICAgICBjYWxsLm9uKCdkYXRhJywgKHNldFJlc3BvbnNlOiBncnBjQ2FjaGUuX1NldFJlc3BvbnNlKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IHNldFJlc3BvbnNlLnJlc3VsdDtcbiAgICAgICAgc3dpdGNoIChyZXN1bHQpIHtcbiAgICAgICAgICBjYXNlIGdycGNDYWNoZS5FQ2FjaGVSZXN1bHQuT2s6XG4gICAgICAgICAgICByZXN1bHRzLnB1c2gobmV3IENhY2hlU2V0LlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKFxuICAgICAgICAgICAgICBuZXcgQ2FjaGVTZXQuRXJyb3IobmV3IFVua25vd25FcnJvcihzZXRSZXNwb25zZS5tZXNzYWdlKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjYWxsLm9uKCdlbmQnLCAoKSA9PiB7XG4gICAgICAgIHJlc29sdmUobmV3IENhY2hlU2V0QmF0Y2guU3VjY2VzcyhyZXN1bHRzKSk7XG4gICAgICB9KTtcblxuICAgICAgY2FsbC5vbignZXJyb3InLCAoZXJyOiBTZXJ2aWNlRXJyb3IgfCBudWxsKSA9PiB7XG4gICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlU2V0QmF0Y2guRXJyb3IoZSksXG4gICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdENvbmNhdGVuYXRlQmFjayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlczogc3RyaW5nW10gfCBVaW50OEFycmF5W10sXG4gICAgdHJ1bmNhdGVGcm9udFRvU2l6ZT86IG51bWJlcixcbiAgICB0dGw6IENvbGxlY3Rpb25UdGwgPSBDb2xsZWN0aW9uVHRsLmZyb21DYWNoZVR0bCgpXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0Q29uY2F0ZW5hdGVCYWNrLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdENvbmNhdGVuYXRlQmFjay5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRMaXN0Q29uY2F0ZW5hdGVCYWNrKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChsaXN0TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydEFycmF5KHZhbHVlcyksXG4gICAgICAgIHR0bC50dGxNaWxsaXNlY29uZHMoKSB8fCB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMCxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKSxcbiAgICAgICAgdHJ1bmNhdGVGcm9udFRvU2l6ZVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZExpc3RDb25jYXRlbmF0ZUJhY2soXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWVzOiBVaW50OEFycmF5W10sXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhbixcbiAgICB0cnVuY2F0ZUZyb250VG9TaXplPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0Q29uY2F0ZW5hdGVCYWNrLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0xpc3RDb25jYXRlbmF0ZUJhY2tSZXF1ZXN0KHtcbiAgICAgIGxpc3RfbmFtZTogbGlzdE5hbWUsXG4gICAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgICAgdHJ1bmNhdGVfZnJvbnRfdG9fc2l6ZTogdHJ1bmNhdGVGcm9udFRvU2l6ZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkxpc3RDb25jYXRlbmF0ZUJhY2soXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RDb25jYXRlbmF0ZUJhY2suU3VjY2VzcyhyZXNwLmxpc3RfbGVuZ3RoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZUxpc3RDb25jYXRlbmF0ZUJhY2suRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0Q29uY2F0ZW5hdGVGcm9udChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlczogc3RyaW5nW10gfCBVaW50OEFycmF5W10sXG4gICAgdHJ1bmNhdGVCYWNrVG9TaXplPzogbnVtYmVyLFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RDb25jYXRlbmF0ZUZyb250LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdENvbmNhdGVuYXRlRnJvbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdENvbmNhdGVuYXRlRnJvbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0QXJyYXkodmFsdWVzKSxcbiAgICAgICAgdHRsLnR0bE1pbGxpc2Vjb25kcygpIHx8IHRoaXMuZGVmYXVsdFR0bFNlY29uZHMgKiAxMDAwLFxuICAgICAgICB0dGwucmVmcmVzaFR0bCgpLFxuICAgICAgICB0cnVuY2F0ZUJhY2tUb1NpemVcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0Q29uY2F0ZW5hdGVGcm9udChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogVWludDhBcnJheSxcbiAgICB2YWx1ZXM6IFVpbnQ4QXJyYXlbXSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlcixcbiAgICByZWZyZXNoVHRsOiBib29sZWFuLFxuICAgIHRydW5jYXRlQmFja1RvU2l6ZT86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlTGlzdENvbmNhdGVuYXRlRnJvbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdENvbmNhdGVuYXRlRnJvbnRSZXF1ZXN0KHtcbiAgICAgIGxpc3RfbmFtZTogbGlzdE5hbWUsXG4gICAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgICAgdHJ1bmNhdGVfYmFja190b19zaXplOiB0cnVuY2F0ZUJhY2tUb1NpemUsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5MaXN0Q29uY2F0ZW5hdGVGcm9udChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdENvbmNhdGVuYXRlRnJvbnQuU3VjY2VzcyhyZXNwLmxpc3RfbGVuZ3RoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZUxpc3RDb25jYXRlbmF0ZUZyb250LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbGlzdEZldGNoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBzdHJpbmcsXG4gICAgc3RhcnRJbmRleD86IG51bWJlcixcbiAgICBlbmRJbmRleD86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlTGlzdEZldGNoLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdFNsaWNlU3RhcnRFbmQoc3RhcnRJbmRleCwgZW5kSW5kZXgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVMaXN0RmV0Y2guRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdEZldGNoKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChsaXN0TmFtZSksXG4gICAgICAgIHN0YXJ0SW5kZXgsXG4gICAgICAgIGVuZEluZGV4XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kTGlzdEZldGNoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBVaW50OEFycmF5LFxuICAgIHN0YXJ0PzogbnVtYmVyLFxuICAgIGVuZD86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlTGlzdEZldGNoLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0xpc3RGZXRjaFJlcXVlc3Qoe1xuICAgICAgbGlzdF9uYW1lOiBsaXN0TmFtZSxcbiAgICB9KTtcbiAgICBpZiAoc3RhcnQpIHtcbiAgICAgIHJlcXVlc3QuaW5jbHVzaXZlX3N0YXJ0ID0gc3RhcnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3QudW5ib3VuZGVkX3N0YXJ0ID0gbmV3IF9VbmJvdW5kZWQoKTtcbiAgICB9XG4gICAgaWYgKGVuZCkge1xuICAgICAgcmVxdWVzdC5leGNsdXNpdmVfZW5kID0gZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0LnVuYm91bmRlZF9lbmQgPSBuZXcgX1VuYm91bmRlZCgpO1xuICAgIH1cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdEZldGNoKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0RmV0Y2guTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RGZXRjaC5IaXQocmVzcC5mb3VuZC52YWx1ZXMpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZUxpc3RGZXRjaC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RSZXRhaW4oXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZyxcbiAgICBzdGFydEluZGV4PzogbnVtYmVyLFxuICAgIGVuZEluZGV4PzogbnVtYmVyLFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RSZXRhaW4uUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdE5hbWUobGlzdE5hbWUpO1xuICAgICAgdmFsaWRhdGVMaXN0U2xpY2VTdGFydEVuZChzdGFydEluZGV4LCBlbmRJbmRleCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUxpc3RSZXRhaW4uRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdFJldGFpbihcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQobGlzdE5hbWUpLFxuICAgICAgICBzdGFydEluZGV4LFxuICAgICAgICBlbmRJbmRleCxcbiAgICAgICAgdHRsLnR0bE1pbGxpc2Vjb25kcygpIHx8IHRoaXMuZGVmYXVsdFR0bFNlY29uZHMgKiAxMDAwLFxuICAgICAgICB0dGwucmVmcmVzaFR0bCgpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kTGlzdFJldGFpbihcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogVWludDhBcnJheSxcbiAgICBzdGFydD86IG51bWJlcixcbiAgICBlbmQ/OiBudW1iZXIsXG4gICAgdHRsTWlsbGlzZWNvbmRzPzogbnVtYmVyLFxuICAgIHJlZnJlc2hUdGw/OiBib29sZWFuXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UmV0YWluLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0xpc3RSZXRhaW5SZXF1ZXN0KHtcbiAgICAgIGxpc3RfbmFtZTogbGlzdE5hbWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICByZWZyZXNoX3R0bDogcmVmcmVzaFR0bCxcbiAgICB9KTtcbiAgICBpZiAoc3RhcnQpIHtcbiAgICAgIHJlcXVlc3QuaW5jbHVzaXZlX3N0YXJ0ID0gc3RhcnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3QudW5ib3VuZGVkX3N0YXJ0ID0gbmV3IF9VbmJvdW5kZWQoKTtcbiAgICB9XG4gICAgaWYgKGVuZCkge1xuICAgICAgcmVxdWVzdC5leGNsdXNpdmVfZW5kID0gZW5kO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXF1ZXN0LnVuYm91bmRlZF9lbmQgPSBuZXcgX1VuYm91bmRlZCgpO1xuICAgIH1cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdFJldGFpbihcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdFJldGFpbi5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlTGlzdFJldGFpbi5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZ1xuICApOiBQcm9taXNlPENhY2hlTGlzdExlbmd0aC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVMaXN0TmFtZShsaXN0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUxpc3RMZW5ndGguRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdExlbmd0aChjYWNoZU5hbWUsIHRoaXMuY29udmVydChsaXN0TmFtZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kTGlzdExlbmd0aChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlTGlzdExlbmd0aC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9MaXN0TGVuZ3RoUmVxdWVzdCh7XG4gICAgICBsaXN0X25hbWU6IGxpc3ROYW1lLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5MaXN0TGVuZ3RoKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0TGVuZ3RoLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0TGVuZ3RoLkhpdChyZXNwLmZvdW5kLmxlbmd0aCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlTGlzdExlbmd0aC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQb3BCYWNrKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQb3BCYWNrLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdFBvcEJhY2suRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdFBvcEJhY2soY2FjaGVOYW1lLCB0aGlzLmNvbnZlcnQobGlzdE5hbWUpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZExpc3RQb3BCYWNrKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UG9wQmFjay5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9MaXN0UG9wQmFja1JlcXVlc3Qoe1xuICAgICAgbGlzdF9uYW1lOiBsaXN0TmFtZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdFBvcEJhY2soXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RQb3BCYWNrLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0UG9wQmFjay5IaXQocmVzcC5mb3VuZC5iYWNrKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVMaXN0UG9wQmFjay5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQb3BGcm9udChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UG9wRnJvbnQuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdE5hbWUobGlzdE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVMaXN0UG9wRnJvbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kTGlzdFBvcEZyb250KGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0UG9wRnJvbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQb3BGcm9udC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9MaXN0UG9wRnJvbnRSZXF1ZXN0KHtcbiAgICAgIGxpc3RfbmFtZTogbGlzdE5hbWUsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkxpc3RQb3BGcm9udChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdFBvcEZyb250Lk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0UG9wRnJvbnQuSGl0KHJlc3AuZm91bmQuZnJvbnQpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZUxpc3RQb3BGcm9udC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxpc3RQdXNoQmFjayhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBsaXN0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHRydW5jYXRlRnJvbnRUb1NpemU/OiBudW1iZXIsXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlTGlzdFB1c2hCYWNrLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdFB1c2hCYWNrLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZExpc3RQdXNoQmFjayhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQobGlzdE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICB0dGwudHRsTWlsbGlzZWNvbmRzKCkgfHwgdGhpcy5kZWZhdWx0VHRsU2Vjb25kcyAqIDEwMDAsXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKCksXG4gICAgICAgIHRydW5jYXRlRnJvbnRUb1NpemVcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0UHVzaEJhY2soXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhbixcbiAgICB0cnVuY2F0ZUZyb250VG9TaXplPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UHVzaEJhY2suUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdFB1c2hCYWNrUmVxdWVzdCh7XG4gICAgICBsaXN0X25hbWU6IGxpc3ROYW1lLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgICB0cnVuY2F0ZV9mcm9udF90b19zaXplOiB0cnVuY2F0ZUZyb250VG9TaXplLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdFB1c2hCYWNrKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVMaXN0UHVzaEJhY2suU3VjY2VzcyhyZXNwLmxpc3RfbGVuZ3RoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVMaXN0UHVzaEJhY2suRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UHVzaEZyb250KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdHJ1bmNhdGVCYWNrVG9TaXplPzogbnVtYmVyLFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZUxpc3RQdXNoRnJvbnQuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlTGlzdE5hbWUobGlzdE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVMaXN0UHVzaEZyb250LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZExpc3RQdXNoRnJvbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGxpc3ROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHZhbHVlKSxcbiAgICAgICAgdHRsLnR0bE1pbGxpc2Vjb25kcygpIHx8IHRoaXMuZGVmYXVsdFR0bFNlY29uZHMgKiAxMDAwLFxuICAgICAgICB0dGwucmVmcmVzaFR0bCgpLFxuICAgICAgICB0cnVuY2F0ZUJhY2tUb1NpemVcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRMaXN0UHVzaEZyb250KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyLFxuICAgIHJlZnJlc2hUdGw6IGJvb2xlYW4sXG4gICAgdHJ1bmNhdGVCYWNrVG9TaXplPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UHVzaEZyb250LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0xpc3RQdXNoRnJvbnRSZXF1ZXN0KHtcbiAgICAgIGxpc3RfbmFtZTogbGlzdE5hbWUsXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICB0dGxfbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgICByZWZyZXNoX3R0bDogcmVmcmVzaFR0bCxcbiAgICAgIHRydW5jYXRlX2JhY2tfdG9fc2l6ZTogdHJ1bmNhdGVCYWNrVG9TaXplLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuTGlzdFB1c2hGcm9udChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlTGlzdFB1c2hGcm9udC5TdWNjZXNzKHJlc3AubGlzdF9sZW5ndGgpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZUxpc3RQdXNoRnJvbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsaXN0UmVtb3ZlVmFsdWUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgbGlzdE5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlTGlzdFJlbW92ZVZhbHVlLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZUxpc3ROYW1lKGxpc3ROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlTGlzdFJlbW92ZVZhbHVlLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZExpc3RSZW1vdmVWYWx1ZShcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQobGlzdE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kTGlzdFJlbW92ZVZhbHVlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGxpc3ROYW1lOiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVMaXN0UmVtb3ZlVmFsdWUuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fTGlzdFJlbW92ZVJlcXVlc3Qoe1xuICAgICAgbGlzdF9uYW1lOiBsaXN0TmFtZSxcbiAgICAgIGFsbF9lbGVtZW50c193aXRoX3ZhbHVlOiB2YWx1ZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkxpc3RSZW1vdmUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUxpc3RSZW1vdmVWYWx1ZS5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlTGlzdFJlbW92ZVZhbHVlLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGljdGlvbmFyeUZldGNoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlGZXRjaC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVEaWN0aW9uYXJ5TmFtZShkaWN0aW9uYXJ5TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZURpY3Rpb25hcnlGZXRjaC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmREaWN0aW9uYXJ5RmV0Y2goXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGRpY3Rpb25hcnlOYW1lKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlGZXRjaChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeUZldGNoLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0RpY3Rpb25hcnlGZXRjaFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkRpY3Rpb25hcnlGZXRjaChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURpY3Rpb25hcnlGZXRjaC5IaXQocmVzcC5mb3VuZC5pdGVtcykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5RmV0Y2guTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZURpY3Rpb25hcnlGZXRjaC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRpY3Rpb25hcnlTZXRGaWVsZChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlTZXRGaWVsZC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVEaWN0aW9uYXJ5TmFtZShkaWN0aW9uYXJ5TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmREaWN0aW9uYXJ5U2V0RmllbGQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGRpY3Rpb25hcnlOYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGZpZWxkKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHZhbHVlKSxcbiAgICAgICAgdHRsLnR0bE1pbGxpc2Vjb25kcygpIHx8IHRoaXMuZGVmYXVsdFR0bFNlY29uZHMgKiAxMDAwLFxuICAgICAgICB0dGwucmVmcmVzaFR0bCgpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGljdGlvbmFyeVNldEZpZWxkKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBVaW50OEFycmF5LFxuICAgIGZpZWxkOiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyLFxuICAgIHJlZnJlc2hUdGw6IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlTZXRGaWVsZC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5U2V0UmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgICAgaXRlbXM6IHRoaXMudG9TaW5nbGV0b25GaWVsZFZhbHVlUGFpcihmaWVsZCwgdmFsdWUpLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5U2V0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5U2V0RmllbGQuU3VjY2VzcygpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRpY3Rpb25hcnlTZXRGaWVsZHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZyxcbiAgICBlbGVtZW50czpcbiAgICAgIHwgTWFwPHN0cmluZyB8IFVpbnQ4QXJyYXksIHN0cmluZyB8IFVpbnQ4QXJyYXk+XG4gICAgICB8IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IFVpbnQ4QXJyYXk+XG4gICAgICB8IEFycmF5PFtzdHJpbmcsIHN0cmluZyB8IFVpbnQ4QXJyYXldPixcbiAgICB0dGw6IENvbGxlY3Rpb25UdGwgPSBDb2xsZWN0aW9uVHRsLmZyb21DYWNoZVR0bCgpXG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5U2V0RmllbGRzLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZURpY3Rpb25hcnlOYW1lKGRpY3Rpb25hcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlRGljdGlvbmFyeVNldEZpZWxkcy5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGRpY3Rpb25hcnlGaWVsZFZhbHVlUGFpcnMgPSB0aGlzLmNvbnZlcnRFbGVtZW50cyhlbGVtZW50cyk7XG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmREaWN0aW9uYXJ5U2V0RmllbGRzKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChkaWN0aW9uYXJ5TmFtZSksXG4gICAgICAgIGRpY3Rpb25hcnlGaWVsZFZhbHVlUGFpcnMsXG4gICAgICAgIHR0bC50dGxNaWxsaXNlY29uZHMoKSB8fCB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMCxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlTZXRGaWVsZHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZWxlbWVudHM6IGdycGNDYWNoZS5fRGljdGlvbmFyeUZpZWxkVmFsdWVQYWlyW10sXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhblxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVNldEZpZWxkcy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5U2V0UmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgICAgaXRlbXM6IGVsZW1lbnRzLFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5U2V0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5U2V0RmllbGRzLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZURpY3Rpb25hcnlTZXRGaWVsZHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5R2V0RmllbGQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZyxcbiAgICBmaWVsZDogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeUdldEZpZWxkLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZURpY3Rpb25hcnlOYW1lKGRpY3Rpb25hcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlRGljdGlvbmFyeUdldEZpZWxkLkVycm9yKGVyciwgdGhpcy5jb252ZXJ0KGZpZWxkKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlHZXRGaWVsZChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZmllbGQpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGljdGlvbmFyeUdldEZpZWxkKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBVaW50OEFycmF5LFxuICAgIGZpZWxkOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUdldFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGZpZWxkczogW2ZpZWxkXSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuRGljdGlvbmFyeUdldChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/LmRpY3Rpb25hcnkgPT09ICdtaXNzaW5nJykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuTWlzcyhmaWVsZCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZGljdGlvbmFyeSA9PT0gJ2ZvdW5kJykge1xuICAgICAgICAgICAgaWYgKHJlc3A/LmZvdW5kLml0ZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZURpY3Rpb25hcnlHZXRGaWVsZC5FcnJvcihcbiAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICdfRGljdGlvbmFyeUdldFJlc3BvbnNlUmVzcG9uc2UgY29udGFpbmVkIG5vIGRhdGEgYnV0IHdhcyBmb3VuZCdcbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICBmaWVsZFxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgIHJlc3A/LmZvdW5kLml0ZW1zWzBdLnJlc3VsdCA9PT0gZ3JwY0NhY2hlLkVDYWNoZVJlc3VsdC5NaXNzXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuTWlzcyhmaWVsZCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuSGl0KFxuICAgICAgICAgICAgICAgICAgcmVzcD8uZm91bmQuaXRlbXNbMF0uY2FjaGVfYm9keSxcbiAgICAgICAgICAgICAgICAgIGZpZWxkXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGQuRXJyb3IoZSwgZmllbGQpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGljdGlvbmFyeUdldEZpZWxkcyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkczogc3RyaW5nW10gfCBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUoZGljdGlvbmFyeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5R2V0RmllbGRzLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlHZXRGaWVsZHMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGRpY3Rpb25hcnlOYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0QXJyYXkoZmllbGRzKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlHZXRGaWVsZHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZmllbGRzOiBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUdldFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGZpZWxkczogZmllbGRzLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5R2V0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8uZGljdGlvbmFyeSA9PT0gJ2ZvdW5kJykge1xuICAgICAgICAgICAgY29uc3QgaXRlbXMgPSByZXNwLmZvdW5kLml0ZW1zLm1hcChpdGVtID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5jb252ZXJ0RUNhY2hlUmVzdWx0KGl0ZW0ucmVzdWx0KTtcbiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBfRGljdGlvbmFyeUdldFJlc3BvbnNlUGFydChyZXN1bHQsIGl0ZW0uY2FjaGVfYm9keSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUdldEZpZWxkcy5IaXQoaXRlbXMsIGZpZWxkcykpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZGljdGlvbmFyeSA9PT0gJ21pc3NpbmcnKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURpY3Rpb25hcnlHZXRGaWVsZHMuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgbmV3IENhY2hlRGljdGlvbmFyeUdldEZpZWxkcy5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRpY3Rpb25hcnlSZW1vdmVGaWVsZChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogc3RyaW5nLFxuICAgIGZpZWxkOiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGQuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUoZGljdGlvbmFyeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGljdGlvbmFyeVJlbW92ZUZpZWxkKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChkaWN0aW9uYXJ5TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydChmaWVsZClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmREaWN0aW9uYXJ5UmVtb3ZlRmllbGQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXksXG4gICAgZmllbGQ6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RGVsZXRlUmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgICAgc29tZTogbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeURlbGV0ZVJlcXVlc3QuU29tZSgpLFxuICAgIH0pO1xuICAgIHJlcXVlc3Quc29tZS5maWVsZHMucHVzaChmaWVsZCk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG5cbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLkRpY3Rpb25hcnlEZWxldGUoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZC5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5UmVtb3ZlRmllbGRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmcsXG4gICAgZmllbGRzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkcy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVEaWN0aW9uYXJ5TmFtZShkaWN0aW9uYXJ5TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kRGljdGlvbmFyeVJlbW92ZUZpZWxkcyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZGljdGlvbmFyeU5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnRBcnJheShmaWVsZHMpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGljdGlvbmFyeVJlbW92ZUZpZWxkcyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBkaWN0aW9uYXJ5TmFtZTogVWludDhBcnJheSxcbiAgICBmaWVsZHM6IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlRGljdGlvbmFyeVJlbW92ZUZpZWxkcy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RGVsZXRlUmVxdWVzdCh7XG4gICAgICBkaWN0aW9uYXJ5X25hbWU6IGRpY3Rpb25hcnlOYW1lLFxuICAgICAgc29tZTogbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeURlbGV0ZVJlcXVlc3QuU29tZSgpLFxuICAgIH0pO1xuICAgIGZpZWxkcy5mb3JFYWNoKGZpZWxkID0+IHJlcXVlc3Quc29tZS5maWVsZHMucHVzaChmaWVsZCkpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuXG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5RGVsZXRlKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5UmVtb3ZlRmllbGRzLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZURpY3Rpb25hcnlSZW1vdmVGaWVsZHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkaWN0aW9uYXJ5TGVuZ3RoKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlMZW5ndGguUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUoZGljdGlvbmFyeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5TGVuZ3RoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlMZW5ndGgoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGRpY3Rpb25hcnlOYW1lKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZERpY3Rpb25hcnlMZW5ndGgoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlMZW5ndGguUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUxlbmd0aFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuRGljdGlvbmFyeUxlbmd0aChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUxlbmd0aC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGljdGlvbmFyeUxlbmd0aC5IaXQocmVzcC5mb3VuZC5sZW5ndGgpKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZURpY3Rpb25hcnlMZW5ndGguRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpbmNyZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZmllbGQ6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgYW1vdW50ID0gMSxcbiAgICB0dGw/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZUluY3JlbWVudC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgaWYgKHR0bCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHZhbGlkYXRlVHRsU2Vjb25kcyh0dGwpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVJbmNyZW1lbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kSW5jcmVtZW50KFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChmaWVsZCksXG4gICAgICAgIGFtb3VudCxcbiAgICAgICAgKHR0bCB8fCB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzKSAqIDEwMDBcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRJbmNyZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZmllbGQ6IFVpbnQ4QXJyYXksXG4gICAgYW1vdW50ID0gMSxcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlSW5jcmVtZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0luY3JlbWVudFJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBmaWVsZCxcbiAgICAgIGFtb3VudCxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcblxuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuSW5jcmVtZW50KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgaWYgKHJlc3AudmFsdWUpIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVJbmNyZW1lbnQuU3VjY2VzcyhyZXNwLnZhbHVlKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUluY3JlbWVudC5TdWNjZXNzKDApKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZUluY3JlbWVudC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGRpY3Rpb25hcnlJbmNyZW1lbnQoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgZGljdGlvbmFyeU5hbWU6IHN0cmluZyxcbiAgICBmaWVsZDogc3RyaW5nIHwgVWludDhBcnJheSxcbiAgICBhbW91bnQgPSAxLFxuICAgIHR0bDogQ29sbGVjdGlvblR0bCA9IENvbGxlY3Rpb25UdGwuZnJvbUNhY2hlVHRsKClcbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlJbmNyZW1lbnQuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlRGljdGlvbmFyeU5hbWUoZGljdGlvbmFyeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZERpY3Rpb25hcnlJbmNyZW1lbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGRpY3Rpb25hcnlOYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGZpZWxkKSxcbiAgICAgICAgYW1vdW50LFxuICAgICAgICB0dGwudHRsTWlsbGlzZWNvbmRzKCkgfHwgdGhpcy5kZWZhdWx0VHRsU2Vjb25kcyAqIDEwMDAsXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmREaWN0aW9uYXJ5SW5jcmVtZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGRpY3Rpb25hcnlOYW1lOiBVaW50OEFycmF5LFxuICAgIGZpZWxkOiBVaW50OEFycmF5LFxuICAgIGFtb3VudDogbnVtYmVyLFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyLFxuICAgIHJlZnJlc2hUdGw6IGJvb2xlYW5cbiAgKTogUHJvbWlzZTxDYWNoZURpY3Rpb25hcnlJbmNyZW1lbnQuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fRGljdGlvbmFyeUluY3JlbWVudFJlcXVlc3Qoe1xuICAgICAgZGljdGlvbmFyeV9uYW1lOiBkaWN0aW9uYXJ5TmFtZSxcbiAgICAgIGZpZWxkLFxuICAgICAgYW1vdW50LFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5EaWN0aW9uYXJ5SW5jcmVtZW50KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgaWYgKHJlc3AudmFsdWUpIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LlN1Y2Nlc3MocmVzcC52YWx1ZSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LlN1Y2Nlc3MoMCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVEaWN0aW9uYXJ5SW5jcmVtZW50LkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0UHV0RWxlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWU6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgc2NvcmU6IG51bWJlcixcbiAgICB0dGw6IENvbGxlY3Rpb25UdGwgPSBDb2xsZWN0aW9uVHRsLmZyb21DYWNoZVR0bCgpXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNvcnRlZFNldE5hbWUoc29ydGVkU2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnQuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU29ydGVkU2V0UHV0RWxlbWVudChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIHRoaXMuY29udmVydCh2YWx1ZSksXG4gICAgICAgIHNjb3JlLFxuICAgICAgICB0dGwudHRsTWlsbGlzZWNvbmRzKCkgfHwgdGhpcy5kZWZhdWx0VHRsU2Vjb25kcyAqIDEwMDAsXG4gICAgICAgIHR0bC5yZWZyZXNoVHRsKClcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRQdXRFbGVtZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgc2NvcmU6IG51bWJlcixcbiAgICB0dGxNaWxsaXNlY29uZHM6IG51bWJlcixcbiAgICByZWZyZXNoVHRsOiBib29sZWFuXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldFB1dFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICBlbGVtZW50czogW25ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEVsZW1lbnQoe3ZhbHVlLCBzY29yZX0pXSxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU29ydGVkU2V0UHV0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50LlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldFB1dEVsZW1lbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRQdXRFbGVtZW50cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgZWxlbWVudHM6XG4gICAgICB8IE1hcDxzdHJpbmcgfCBVaW50OEFycmF5LCBudW1iZXI+XG4gICAgICB8IFJlY29yZDxzdHJpbmcsIG51bWJlcj5cbiAgICAgIHwgQXJyYXk8W3N0cmluZywgbnVtYmVyXT4sXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBzb3J0ZWRTZXRWYWx1ZVNjb3JlUGFpcnMgPVxuICAgICAgICB0aGlzLmNvbnZlcnRTb3J0ZWRTZXRNYXBPclJlY29yZChlbGVtZW50cyk7XG5cbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRQdXRFbGVtZW50cyhcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIHNvcnRlZFNldFZhbHVlU2NvcmVQYWlycyxcbiAgICAgICAgdHRsLnR0bE1pbGxpc2Vjb25kcygpIHx8IHRoaXMuZGVmYXVsdFR0bFNlY29uZHMgKiAxMDAwLFxuICAgICAgICB0dGwucmVmcmVzaFR0bCgpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU29ydGVkU2V0UHV0RWxlbWVudHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogVWludDhBcnJheSxcbiAgICBlbGVtZW50czogZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRFbGVtZW50W10sXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhblxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UHV0RWxlbWVudHMuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0UHV0UmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc29ydGVkU2V0TmFtZSxcbiAgICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICAgIHR0bF9taWxsaXNlY29uZHM6IHR0bE1pbGxpc2Vjb25kcyxcbiAgICAgIHJlZnJlc2hfdHRsOiByZWZyZXNoVHRsLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU29ydGVkU2V0UHV0KFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50cy5TdWNjZXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT5cbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRQdXRFbGVtZW50cy5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNvcnRlZFNldEZldGNoQnlSYW5rKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgICBvcmRlcjogU29ydGVkU2V0T3JkZXIsXG4gICAgc3RhcnRSYW5rOiBudW1iZXIsXG4gICAgZW5kUmFuaz86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0RmV0Y2guUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0UmFua3Moc3RhcnRSYW5rLCBlbmRSYW5rKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU29ydGVkU2V0RmV0Y2hCeVJhbmsoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNvcnRlZFNldE5hbWUpLFxuICAgICAgICBvcmRlcixcbiAgICAgICAgc3RhcnRSYW5rLFxuICAgICAgICBlbmRSYW5rXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU29ydGVkU2V0RmV0Y2hCeVJhbmsoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogVWludDhBcnJheSxcbiAgICBvcmRlcjogU29ydGVkU2V0T3JkZXIsXG4gICAgc3RhcnRSYW5rOiBudW1iZXIsXG4gICAgZW5kUmFuaz86IG51bWJlclxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0RmV0Y2guUmVzcG9uc2U+IHtcbiAgICBjb25zdCBieV9pbmRleCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEZldGNoUmVxdWVzdC5fQnlJbmRleCgpO1xuICAgIGlmIChzdGFydFJhbmspIHtcbiAgICAgIGJ5X2luZGV4LmluY2x1c2l2ZV9zdGFydF9pbmRleCA9IHN0YXJ0UmFuaztcbiAgICB9IGVsc2Uge1xuICAgICAgYnlfaW5kZXgudW5ib3VuZGVkX3N0YXJ0ID0gbmV3IF9VbmJvdW5kZWQoKTtcbiAgICB9XG4gICAgaWYgKGVuZFJhbmspIHtcbiAgICAgIGJ5X2luZGV4LmV4Y2x1c2l2ZV9lbmRfaW5kZXggPSBlbmRSYW5rO1xuICAgIH0gZWxzZSB7XG4gICAgICBieV9pbmRleC51bmJvdW5kZWRfZW5kID0gbmV3IF9VbmJvdW5kZWQoKTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm90b0J1Zk9yZGVyID1cbiAgICAgIG9yZGVyID09PSBTb3J0ZWRTZXRPcmRlci5EZXNjZW5kaW5nXG4gICAgICAgID8gZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRGZXRjaFJlcXVlc3QuT3JkZXIuREVTQ0VORElOR1xuICAgICAgICA6IGdycGNDYWNoZS5fU29ydGVkU2V0RmV0Y2hSZXF1ZXN0Lk9yZGVyLkFTQ0VORElORztcblxuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRGZXRjaFJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICBvcmRlcjogcHJvdG9CdWZPcmRlcixcbiAgICAgIHdpdGhfc2NvcmVzOiB0cnVlLFxuICAgICAgYnlfaW5kZXg6IGJ5X2luZGV4LFxuICAgIH0pO1xuXG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5Tb3J0ZWRTZXRGZXRjaChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICAgIGlmIChyZXNwPy5mb3VuZCkge1xuICAgICAgICAgICAgICBpZiAocmVzcD8uZm91bmQ/LnZhbHVlc193aXRoX3Njb3Jlcykge1xuICAgICAgICAgICAgICAgIHJlc29sdmUoXG4gICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRGZXRjaC5IaXQoXG4gICAgICAgICAgICAgICAgICAgIHJlc3AuZm91bmQudmFsdWVzX3dpdGhfc2NvcmVzLmVsZW1lbnRzXG4gICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU29ydGVkU2V0RmV0Y2guRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgJ1Vua25vd24gc29ydGVkIHNldCBmZXRjaCBoaXQgcmVzcG9uc2UgdHlwZSdcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLk1pc3MoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLkVycm9yKFxuICAgICAgICAgICAgICAgICAgbmV3IFVua25vd25FcnJvcignVW5rbm93biBzb3J0ZWQgc2V0IGZldGNoIHJlc3BvbnNlIHR5cGUnKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0RmV0Y2hCeVNjb3JlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgICBvcmRlcjogU29ydGVkU2V0T3JkZXIsXG4gICAgbWluU2NvcmU/OiBudW1iZXIsXG4gICAgbWF4U2NvcmU/OiBudW1iZXIsXG4gICAgb2Zmc2V0PzogbnVtYmVyLFxuICAgIGNvdW50PzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXRTY29yZXMobWluU2NvcmUsIG1heFNjb3JlKTtcbiAgICAgIGlmIChvZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICB2YWxpZGF0ZVNvcnRlZFNldE9mZnNldChvZmZzZXQpO1xuICAgICAgfVxuICAgICAgaWYgKGNvdW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdmFsaWRhdGVTb3J0ZWRTZXRDb3VudChjb3VudCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldEZldGNoQnlTY29yZShcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoc29ydGVkU2V0TmFtZSksXG4gICAgICAgIG9yZGVyLFxuICAgICAgICBtaW5TY29yZSxcbiAgICAgICAgbWF4U2NvcmUsXG4gICAgICAgIG9mZnNldCxcbiAgICAgICAgY291bnRcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRGZXRjaEJ5U2NvcmUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogVWludDhBcnJheSxcbiAgICBvcmRlcjogU29ydGVkU2V0T3JkZXIsXG4gICAgbWluU2NvcmU/OiBudW1iZXIsXG4gICAgbWF4U2NvcmU/OiBudW1iZXIsXG4gICAgb2Zmc2V0PzogbnVtYmVyLFxuICAgIGNvdW50PzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRGZXRjaC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IGJ5X3Njb3JlID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0RmV0Y2hSZXF1ZXN0Ll9CeVNjb3JlKCk7XG4gICAgaWYgKG1pblNjb3JlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGJ5X3Njb3JlLm1pbl9zY29yZSA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldEZldGNoUmVxdWVzdC5fQnlTY29yZS5fU2NvcmUoXG4gICAgICAgIHtcbiAgICAgICAgICBzY29yZTogbWluU2NvcmUsXG4gICAgICAgICAgZXhjbHVzaXZlOiBmYWxzZSxcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYnlfc2NvcmUudW5ib3VuZGVkX21pbiA9IG5ldyBfVW5ib3VuZGVkKCk7XG4gICAgfVxuICAgIGlmIChtYXhTY29yZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBieV9zY29yZS5tYXhfc2NvcmUgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRGZXRjaFJlcXVlc3QuX0J5U2NvcmUuX1Njb3JlKFxuICAgICAgICB7XG4gICAgICAgICAgc2NvcmU6IG1heFNjb3JlLFxuICAgICAgICAgIGV4Y2x1c2l2ZTogZmFsc2UsXG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJ5X3Njb3JlLnVuYm91bmRlZF9tYXggPSBuZXcgX1VuYm91bmRlZCgpO1xuICAgIH1cbiAgICBieV9zY29yZS5vZmZzZXQgPSBvZmZzZXQgPz8gMDtcbiAgICAvLyBOb3RlOiB0aGUgc2VydmljZSByZXNlcnZlcyBuZWdhdGl2ZSBjb3VudHMgdG8gbWVhbiBhbGwgZWxlbWVudHMgaW4gdGhlXG4gICAgLy8gcmVzdWx0IHNldC5cbiAgICBieV9zY29yZS5jb3VudCA9IGNvdW50ID8/IC0xO1xuXG4gICAgY29uc3QgcHJvdG9CdWZPcmRlciA9XG4gICAgICBvcmRlciA9PT0gU29ydGVkU2V0T3JkZXIuRGVzY2VuZGluZ1xuICAgICAgICA/IGdycGNDYWNoZS5fU29ydGVkU2V0RmV0Y2hSZXF1ZXN0Lk9yZGVyLkRFU0NFTkRJTkdcbiAgICAgICAgOiBncnBjQ2FjaGUuX1NvcnRlZFNldEZldGNoUmVxdWVzdC5PcmRlci5BU0NFTkRJTkc7XG5cbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0RmV0Y2hSZXF1ZXN0KHtcbiAgICAgIHNldF9uYW1lOiBzb3J0ZWRTZXROYW1lLFxuICAgICAgb3JkZXI6IHByb3RvQnVmT3JkZXIsXG4gICAgICB3aXRoX3Njb3JlczogdHJ1ZSxcbiAgICAgIGJ5X3Njb3JlOiBieV9zY29yZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU29ydGVkU2V0RmV0Y2goXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgICAgaWYgKHJlc3A/LmZvdW5kPy52YWx1ZXNfd2l0aF9zY29yZXMpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU29ydGVkU2V0RmV0Y2guSGl0KFxuICAgICAgICAgICAgICAgICAgICByZXNwLmZvdW5kLnZhbHVlc193aXRoX3Njb3Jlcy5lbGVtZW50c1xuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldEZldGNoLkVycm9yKFxuICAgICAgICAgICAgICAgICAgICBuZXcgVW5rbm93bkVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICdVbmtub3duIHNvcnRlZCBzZXQgZmV0Y2ggaGl0IHJlc3BvbnNlIHR5cGUnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRGZXRjaC5NaXNzKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShcbiAgICAgICAgICAgICAgICBuZXcgQ2FjaGVTb3J0ZWRTZXRGZXRjaC5FcnJvcihcbiAgICAgICAgICAgICAgICAgIG5ldyBVbmtub3duRXJyb3IoJ1Vua25vd24gc29ydGVkIHNldCBmZXRjaCByZXNwb25zZSB0eXBlJylcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRGZXRjaC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNvcnRlZFNldEdldFJhbmsoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIG9yZGVyPzogU29ydGVkU2V0T3JkZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEdldFJhbmsuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0R2V0UmFuay5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRHZXRSYW5rKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzb3J0ZWRTZXROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHZhbHVlKSxcbiAgICAgICAgb3JkZXJcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRHZXRSYW5rKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgb3JkZXI/OiBTb3J0ZWRTZXRPcmRlclxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0UmFuay5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHByb3RvQnVmT3JkZXIgPVxuICAgICAgb3JkZXIgPT09IFNvcnRlZFNldE9yZGVyLkRlc2NlbmRpbmdcbiAgICAgICAgPyBncnBjQ2FjaGUuX1NvcnRlZFNldEdldFJhbmtSZXF1ZXN0Lk9yZGVyLkRFU0NFTkRJTkdcbiAgICAgICAgOiBncnBjQ2FjaGUuX1NvcnRlZFNldEdldFJhbmtSZXF1ZXN0Lk9yZGVyLkFTQ0VORElORztcblxuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRHZXRSYW5rUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc29ydGVkU2V0TmFtZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIG9yZGVyOiBwcm90b0J1Zk9yZGVyLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXJcbiAgICAgICAgLmdldENsaWVudCgpXG4gICAgICAgIC5Tb3J0ZWRTZXRHZXRSYW5rKFxuICAgICAgICAgIHJlcXVlc3QsXG4gICAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgICAge2ludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnN9LFxuICAgICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgcmVzcD8ubWlzc2luZyB8fFxuICAgICAgICAgICAgICByZXNwPy5lbGVtZW50X3Jhbms/LnJlc3VsdCA9PT0gRUNhY2hlUmVzdWx0Lk1pc3NcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEdldFJhbmsuTWlzcygpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZWxlbWVudF9yYW5rPy5yZXN1bHQgPT09IEVDYWNoZVJlc3VsdC5IaXQpIHtcbiAgICAgICAgICAgICAgaWYgKHJlc3A/LmVsZW1lbnRfcmFuay5yYW5rID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEdldFJhbmsuTWlzcygpKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEdldFJhbmsuSGl0KHJlc3AuZWxlbWVudF9yYW5rLnJhbmspKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRHZXRSYW5rLkVycm9yKGUpLFxuICAgICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0R2V0U2NvcmUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRHZXRTY29yZS5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlc3BvbnNlcyA9IGF3YWl0IHRoaXMuc29ydGVkU2V0R2V0U2NvcmVzKGNhY2hlTmFtZSwgc29ydGVkU2V0TmFtZSwgW1xuICAgICAgdmFsdWUsXG4gICAgXSBhcyBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXSk7XG4gICAgaWYgKHJlc3BvbnNlcyBpbnN0YW5jZW9mIENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLkhpdCkge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlcy5yZXNwb25zZXMoKVswXTtcbiAgICB9IGVsc2UgaWYgKHJlc3BvbnNlcyBpbnN0YW5jZW9mIENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLk1pc3MpIHtcbiAgICAgIHJldHVybiBuZXcgQ2FjaGVTb3J0ZWRTZXRHZXRTY29yZS5NaXNzKHRoaXMuY29udmVydCh2YWx1ZSkpO1xuICAgIH0gZWxzZSBpZiAocmVzcG9uc2VzIGluc3RhbmNlb2YgQ2FjaGVTb3J0ZWRTZXRHZXRTY29yZXMuRXJyb3IpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgcmVzcG9uc2VzLmlubmVyRXhjZXB0aW9uKCksXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRHZXRTY29yZS5FcnJvcihlcnIsIHRoaXMuY29udmVydCh2YWx1ZSkpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgIG5ldyBVbmtub3duRXJyb3IoJ1Vua25vd24gcmVzcG9uc2UgdHlwZScpLFxuICAgICAgZXJyID0+IG5ldyBDYWNoZVNvcnRlZFNldEdldFNjb3JlLkVycm9yKGVyciwgdGhpcy5jb252ZXJ0KHZhbHVlKSlcbiAgICApO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNvcnRlZFNldEdldFNjb3JlcyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmcsXG4gICAgdmFsdWVzOiBzdHJpbmdbXSB8IFVpbnQ4QXJyYXlbXVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNvcnRlZFNldE5hbWUoc29ydGVkU2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNvcnRlZFNldEdldFNjb3Jlcy5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRTb3J0ZWRTZXRHZXRTY29yZXMoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNvcnRlZFNldE5hbWUpLFxuICAgICAgICB2YWx1ZXMubWFwKHZhbHVlID0+IHRoaXMuY29udmVydCh2YWx1ZSkpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU29ydGVkU2V0R2V0U2NvcmVzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWVzOiBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldEdldFNjb3Jlcy5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRHZXRTY29yZVJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICB9KTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyXG4gICAgICAgIC5nZXRDbGllbnQoKVxuICAgICAgICAuU29ydGVkU2V0R2V0U2NvcmUoXG4gICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAgICB7aW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9yc30sXG4gICAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRHZXRTY29yZXMuTWlzcygpKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgICAgY29uc3QgZWxlbWVudHMgPSByZXNwLmZvdW5kLmVsZW1lbnRzLm1hcChlbGUgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuY29udmVydEVDYWNoZVJlc3VsdChlbGUucmVzdWx0KTtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IF9Tb3J0ZWRTZXRHZXRTY29yZVJlc3BvbnNlUGFydChyZXN1bHQsIGVsZS5zY29yZSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldEdldFNjb3Jlcy5IaXQoZWxlbWVudHMsIHZhbHVlcykpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU29ydGVkU2V0R2V0U2NvcmVzLkVycm9yKGUpLFxuICAgICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0SW5jcmVtZW50U2NvcmUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlOiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIGFtb3VudCA9IDEsXG4gICAgdHRsOiBDb2xsZWN0aW9uVHRsID0gQ29sbGVjdGlvblR0bC5mcm9tQ2FjaGVUdGwoKVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlU29ydGVkU2V0TmFtZShzb3J0ZWRTZXROYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU29ydGVkU2V0SW5jcmVtZW50U2NvcmUoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNvcnRlZFNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpLFxuICAgICAgICBhbW91bnQsXG4gICAgICAgIHR0bC50dGxNaWxsaXNlY29uZHMoKSB8fCB0aGlzLmRlZmF1bHRUdGxTZWNvbmRzICogMTAwMCxcbiAgICAgICAgdHRsLnJlZnJlc2hUdGwoKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNvcnRlZFNldEluY3JlbWVudFNjb3JlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXksXG4gICAgYW1vdW50OiBudW1iZXIsXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXIsXG4gICAgcmVmcmVzaFR0bDogYm9vbGVhblxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0SW5jcmVtZW50UmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc29ydGVkU2V0TmFtZSxcbiAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgIGFtb3VudDogYW1vdW50LFxuICAgICAgdHRsX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgICAgcmVmcmVzaF90dGw6IHJlZnJlc2hUdGwsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlclxuICAgICAgICAuZ2V0Q2xpZW50KClcbiAgICAgICAgLlNvcnRlZFNldEluY3JlbWVudChcbiAgICAgICAgICByZXF1ZXN0LFxuICAgICAgICAgIG1ldGFkYXRhLFxuICAgICAgICAgIHtpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzfSxcbiAgICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzcCkge1xuICAgICAgICAgICAgICBpZiAocmVzcC5zY29yZSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuU3VjY2VzcyhyZXNwLnNjb3JlKSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRJbmNyZW1lbnRTY29yZS5TdWNjZXNzKDApKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgICAgbmV3IENhY2hlU29ydGVkU2V0SW5jcmVtZW50U2NvcmUuRXJyb3IoZSksXG4gICAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzb3J0ZWRTZXRSZW1vdmVFbGVtZW50KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IHN0cmluZyxcbiAgICB2YWx1ZTogc3RyaW5nIHwgVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldFJlbW92ZUVsZW1lbnQoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNvcnRlZFNldE5hbWUpLFxuICAgICAgICB0aGlzLmNvbnZlcnQodmFsdWUpXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU29ydGVkU2V0UmVtb3ZlRWxlbWVudChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5LFxuICAgIHZhbHVlOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRSZW1vdmVFbGVtZW50LlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldFJlbW92ZVJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICBzb21lOiBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRSZW1vdmVSZXF1ZXN0Ll9Tb21lKHtcbiAgICAgICAgdmFsdWVzOiBbdmFsdWVdLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpLlNvcnRlZFNldFJlbW92ZShcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICBlcnIgPT4ge1xuICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnQuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnQuU3VjY2VzcygpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgc29ydGVkU2V0UmVtb3ZlRWxlbWVudHMoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIHZhbHVlczogc3RyaW5nW10gfCBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNvcnRlZFNldE5hbWUoc29ydGVkU2V0TmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnRzLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldFJlbW92ZUVsZW1lbnRzKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzb3J0ZWRTZXROYW1lKSxcbiAgICAgICAgdGhpcy5jb252ZXJ0QXJyYXkodmFsdWVzKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNvcnRlZFNldFJlbW92ZUVsZW1lbnRzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWVzOiBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnRzLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX1NvcnRlZFNldFJlbW92ZVJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgICBzb21lOiBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRSZW1vdmVSZXF1ZXN0Ll9Tb21lKHtcbiAgICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgICB9KSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU29ydGVkU2V0UmVtb3ZlKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIGVyciA9PiB7XG4gICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+XG4gICAgICAgICAgICAgICAgbmV3IENhY2hlU29ydGVkU2V0UmVtb3ZlRWxlbWVudHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldFJlbW92ZUVsZW1lbnRzLlN1Y2Nlc3MoKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNvcnRlZFNldExlbmd0aChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldExlbmd0aC5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgICAgdmFsaWRhdGVTb3J0ZWRTZXROYW1lKHNvcnRlZFNldE5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGguRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kU29ydGVkU2V0TGVuZ3RoKFxuICAgICAgICBjYWNoZU5hbWUsXG4gICAgICAgIHRoaXMuY29udmVydChzb3J0ZWRTZXROYW1lKVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFNvcnRlZFNldExlbmd0aChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBzb3J0ZWRTZXROYW1lOiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRMZW5ndGguUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0TGVuZ3RoUmVxdWVzdCh7XG4gICAgICBzZXRfbmFtZTogc29ydGVkU2V0TmFtZSxcbiAgICB9KTtcblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU29ydGVkU2V0TGVuZ3RoKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGguTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICBpZiAoIXJlc3AuZm91bmQubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0TGVuZ3RoLk1pc3MoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldExlbmd0aC5IaXQocmVzcC5mb3VuZC5sZW5ndGgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXNvbHZlT3JSZWplY3RFcnJvcih7XG4gICAgICAgICAgICAgIGVycjogZXJyLFxuICAgICAgICAgICAgICBlcnJvclJlc3BvbnNlRmFjdG9yeUZuOiBlID0+IG5ldyBDYWNoZVNvcnRlZFNldExlbmd0aC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNvcnRlZFNldExlbmd0aEJ5U2NvcmUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAgc29ydGVkU2V0TmFtZTogc3RyaW5nLFxuICAgIG1pblNjb3JlPzogbnVtYmVyLFxuICAgIG1heFNjb3JlPzogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVNvcnRlZFNldE5hbWUoc29ydGVkU2V0TmFtZSk7XG4gICAgICB2YWxpZGF0ZVNvcnRlZFNldFNjb3JlcyhtaW5TY29yZSwgbWF4U2NvcmUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZFNvcnRlZFNldExlbmd0aEJ5U2NvcmUoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KHNvcnRlZFNldE5hbWUpLFxuICAgICAgICBtaW5TY29yZSxcbiAgICAgICAgbWF4U2NvcmVcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHNlbmRTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIHNvcnRlZFNldE5hbWU6IFVpbnQ4QXJyYXksXG4gICAgbWluU2NvcmU/OiBudW1iZXIsXG4gICAgbWF4U2NvcmU/OiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVNvcnRlZFNldExlbmd0aEJ5U2NvcmUuUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXF1ZXN0ID0gbmV3IGdycGNDYWNoZS5fU29ydGVkU2V0TGVuZ3RoQnlTY29yZVJlcXVlc3Qoe1xuICAgICAgc2V0X25hbWU6IHNvcnRlZFNldE5hbWUsXG4gICAgfSk7XG5cbiAgICBpZiAobWluU2NvcmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVxdWVzdC51bmJvdW5kZWRfbWluID0gbmV3IF9VbmJvdW5kZWQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVxdWVzdC5pbmNsdXNpdmVfbWluID0gbWluU2NvcmU7XG4gICAgfVxuXG4gICAgaWYgKG1heFNjb3JlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJlcXVlc3QudW5ib3VuZGVkX21heCA9IG5ldyBfVW5ib3VuZGVkKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcXVlc3QuaW5jbHVzaXZlX21heCA9IG1heFNjb3JlO1xuICAgIH1cblxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuU29ydGVkU2V0TGVuZ3RoQnlTY29yZShcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlU29ydGVkU2V0TGVuZ3RoQnlTY29yZS5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIGlmICghcmVzcC5mb3VuZC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVTb3J0ZWRTZXRMZW5ndGhCeVNjb3JlLk1pc3MoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZVNvcnRlZFNldExlbmd0aEJ5U2NvcmUuSGl0KHJlc3AuZm91bmQubGVuZ3RoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PlxuICAgICAgICAgICAgICAgIG5ldyBDYWNoZVNvcnRlZFNldExlbmd0aEJ5U2NvcmUuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUludGVyY2VwdG9ycyhcbiAgICBoZWFkZXJzOiBIZWFkZXJbXSxcbiAgICBsb2dnZXJGYWN0b3J5OiBNb21lbnRvTG9nZ2VyRmFjdG9yeSxcbiAgICBtaWRkbGV3YXJlczogTWlkZGxld2FyZVtdLFxuICAgIG1pZGRsZXdhcmVSZXF1ZXN0Q29udGV4dDogTWlkZGxld2FyZVJlcXVlc3RIYW5kbGVyQ29udGV4dFxuICApOiBJbnRlcmNlcHRvcltdIHtcbiAgICByZXR1cm4gW1xuICAgICAgbWlkZGxld2FyZXNJbnRlcmNlcHRvcihcbiAgICAgICAgbG9nZ2VyRmFjdG9yeSxcbiAgICAgICAgbWlkZGxld2FyZXMsXG4gICAgICAgIG1pZGRsZXdhcmVSZXF1ZXN0Q29udGV4dCxcbiAgICAgICAgdGhpcy5jbGllbnRXcmFwcGVyLmdldENsaWVudCgpXG4gICAgICApLFxuICAgICAgSGVhZGVySW50ZXJjZXB0b3IuY3JlYXRlSGVhZGVyc0ludGVyY2VwdG9yKGhlYWRlcnMpLFxuICAgICAgUmV0cnlJbnRlcmNlcHRvci5jcmVhdGVSZXRyeUludGVyY2VwdG9yKHtcbiAgICAgICAgY2xpZW50TmFtZTogJ0NhY2hlRGF0YUNsaWVudCcsXG4gICAgICAgIGxvZ2dlckZhY3Rvcnk6IHRoaXMuY29uZmlndXJhdGlvbi5nZXRMb2dnZXJGYWN0b3J5KCksXG4gICAgICAgIHJldHJ5U3RyYXRlZ3k6IHRoaXMuY29uZmlndXJhdGlvbi5nZXRSZXRyeVN0cmF0ZWd5KCksXG4gICAgICAgIG92ZXJhbGxSZXF1ZXN0VGltZW91dE1zOiB0aGlzLnJlcXVlc3RUaW1lb3V0TXMsXG4gICAgICB9KSxcbiAgICBdO1xuICB9XG5cbiAgLy8gVE9ETyBodHRwczovL2dpdGh1Yi5jb20vbW9tZW50b2hxL2NsaWVudC1zZGstbm9kZWpzL2lzc3Vlcy8zNDlcbiAgLy8gZGVjaWRlIG9uIHN0cmVhbWluZyBpbnRlcmNlcHRvcnMgYW5kIG1pZGRsZXdhcmVzXG4gIHByaXZhdGUgaW5pdGlhbGl6ZVN0cmVhbWluZ0ludGVyY2VwdG9ycyhoZWFkZXJzOiBIZWFkZXJbXSk6IEludGVyY2VwdG9yW10ge1xuICAgIHJldHVybiBbSGVhZGVySW50ZXJjZXB0b3IuY3JlYXRlSGVhZGVyc0ludGVyY2VwdG9yKGhlYWRlcnMpXTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydCh2OiBzdHJpbmcgfCBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4gICAgaWYgKHR5cGVvZiB2ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMudGV4dEVuY29kZXIuZW5jb2RlKHYpO1xuICAgIH1cbiAgICByZXR1cm4gdjtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydEFycmF5KHY6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdKTogVWludDhBcnJheVtdIHtcbiAgICByZXR1cm4gdi5tYXAoaSA9PiB0aGlzLmNvbnZlcnQoaSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0RWxlbWVudHMoXG4gICAgZWxlbWVudHM6XG4gICAgICB8IE1hcDxzdHJpbmcgfCBVaW50OEFycmF5LCBzdHJpbmcgfCBVaW50OEFycmF5PlxuICAgICAgfCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBVaW50OEFycmF5PlxuICAgICAgfCBBcnJheTxbc3RyaW5nLCBzdHJpbmcgfCBVaW50OEFycmF5XT5cbiAgKTogZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RmllbGRWYWx1ZVBhaXJbXSB7XG4gICAgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRFbGVtZW50cyhuZXcgTWFwKGVsZW1lbnRzKSk7XG4gICAgfSBlbHNlIGlmIChlbGVtZW50cyBpbnN0YW5jZW9mIE1hcCkge1xuICAgICAgcmV0dXJuIFsuLi5lbGVtZW50cy5lbnRyaWVzKCldLm1hcChcbiAgICAgICAgZWxlbWVudCA9PlxuICAgICAgICAgIG5ldyBncnBjQ2FjaGUuX0RpY3Rpb25hcnlGaWVsZFZhbHVlUGFpcih7XG4gICAgICAgICAgICBmaWVsZDogdGhpcy5jb252ZXJ0KGVsZW1lbnRbMF0pLFxuICAgICAgICAgICAgdmFsdWU6IHRoaXMuY29udmVydChlbGVtZW50WzFdKSxcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGVsZW1lbnRzKS5tYXAoXG4gICAgICAgIGVsZW1lbnQgPT5cbiAgICAgICAgICBuZXcgZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RmllbGRWYWx1ZVBhaXIoe1xuICAgICAgICAgICAgZmllbGQ6IHRoaXMuY29udmVydChlbGVtZW50WzBdKSxcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNvbnZlcnQoZWxlbWVudFsxXSksXG4gICAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0U29ydGVkU2V0TWFwT3JSZWNvcmQoXG4gICAgZWxlbWVudHM6XG4gICAgICB8IE1hcDxzdHJpbmcgfCBVaW50OEFycmF5LCBudW1iZXI+XG4gICAgICB8IFJlY29yZDxzdHJpbmcsIG51bWJlcj5cbiAgICAgIHwgQXJyYXk8W3N0cmluZywgbnVtYmVyXT5cbiAgKTogZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRFbGVtZW50W10ge1xuICAgIGlmIChlbGVtZW50cyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0U29ydGVkU2V0TWFwT3JSZWNvcmQobmV3IE1hcChlbGVtZW50cykpO1xuICAgIH0gZWxzZSBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgIHJldHVybiBbLi4uZWxlbWVudHMuZW50cmllcygpXS5tYXAoXG4gICAgICAgIGVsZW1lbnQgPT5cbiAgICAgICAgICBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRFbGVtZW50KHtcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNvbnZlcnQoZWxlbWVudFswXSksXG4gICAgICAgICAgICBzY29yZTogZWxlbWVudFsxXSxcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGVsZW1lbnRzKS5tYXAoXG4gICAgICAgIGVsZW1lbnQgPT5cbiAgICAgICAgICBuZXcgZ3JwY0NhY2hlLl9Tb3J0ZWRTZXRFbGVtZW50KHtcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLmNvbnZlcnQoZWxlbWVudFswXSksXG4gICAgICAgICAgICBzY29yZTogZWxlbWVudFsxXSxcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRTZXRCYXRjaEVsZW1lbnRzKFxuICAgIGVsZW1lbnRzOlxuICAgICAgfCBNYXA8c3RyaW5nIHwgVWludDhBcnJheSwgc3RyaW5nIHwgVWludDhBcnJheT5cbiAgICAgIHwgUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgVWludDhBcnJheT5cbiAgICAgIHwgQXJyYXk8U2V0QmF0Y2hJdGVtPixcbiAgICB0dGw6IG51bWJlclxuICApOiBbVWludDhBcnJheSwgVWludDhBcnJheSwgbnVtYmVyXVtdIHtcbiAgICBpZiAoZWxlbWVudHMgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgcmV0dXJuIGVsZW1lbnRzLm1hcChlbGVtZW50ID0+IFtcbiAgICAgICAgdGhpcy5jb252ZXJ0KGVsZW1lbnQua2V5KSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGVsZW1lbnQudmFsdWUpLFxuICAgICAgICBlbGVtZW50LnR0bCA/PyB0dGwsXG4gICAgICBdKTtcbiAgICB9IGVsc2UgaWYgKGVsZW1lbnRzIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICByZXR1cm4gWy4uLmVsZW1lbnRzLmVudHJpZXMoKV0ubWFwKChbaywgdl0pID0+IFtcbiAgICAgICAgdGhpcy5jb252ZXJ0KGspLFxuICAgICAgICB0aGlzLmNvbnZlcnQodiksXG4gICAgICAgIHR0bCxcbiAgICAgIF0pO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoZWxlbWVudHMpLm1hcChlbGVtZW50ID0+IFtcbiAgICAgICAgdGhpcy5jb252ZXJ0KGVsZW1lbnRbMF0pLFxuICAgICAgICB0aGlzLmNvbnZlcnQoZWxlbWVudFsxXSksXG4gICAgICAgIHR0bCxcbiAgICAgIF0pO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpdGVtR2V0VHlwZShcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZUl0ZW1HZXRUeXBlLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUl0ZW1HZXRUeXBlLkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZEl0ZW1HZXRUeXBlKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGtleSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kSXRlbUdldFR5cGUoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVJdGVtR2V0VHlwZS5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9JdGVtR2V0VHlwZVJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5OiBrZXksXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5JdGVtR2V0VHlwZShcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlSXRlbUdldFR5cGUuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LmZvdW5kKSB7XG4gICAgICAgICAgICByZXNvbHZlKFxuICAgICAgICAgICAgICBuZXcgQ2FjaGVJdGVtR2V0VHlwZS5IaXQoXG4gICAgICAgICAgICAgICAgdGhpcy5jb252ZXJ0SXRlbVR5cGVSZXN1bHQocmVzcC5mb3VuZC5pdGVtX3R5cGUpXG4gICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVJdGVtR2V0VHlwZS5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGl0ZW1HZXRUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVJdGVtR2V0VHRsLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZUl0ZW1HZXRUdGwuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kSXRlbUdldFR0bChjYWNoZU5hbWUsIHRoaXMuY29udmVydChrZXkpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEl0ZW1HZXRUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5XG4gICk6IFByb21pc2U8Q2FjaGVJdGVtR2V0VHRsLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0l0ZW1HZXRUdGxSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuSXRlbUdldFR0bChcbiAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgbWV0YWRhdGEsXG4gICAgICAgIHtcbiAgICAgICAgICBpbnRlcmNlcHRvcnM6IHRoaXMuaW50ZXJjZXB0b3JzLFxuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXNwKSA9PiB7XG4gICAgICAgICAgaWYgKHJlc3A/Lm1pc3NpbmcpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlSXRlbUdldFR0bC5NaXNzKCkpO1xuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcD8uZm91bmQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlSXRlbUdldFR0bC5IaXQocmVzcC5mb3VuZC5yZW1haW5pbmdfdHRsX21pbGxpcykpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlSXRlbUdldFR0bC5FcnJvcihlKSxcbiAgICAgICAgICAgICAgcmVzb2x2ZUZuOiByZXNvbHZlLFxuICAgICAgICAgICAgICByZWplY3RGbjogcmVqZWN0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGtleUV4aXN0cyhcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXlcbiAgKTogUHJvbWlzZTxDYWNoZUtleUV4aXN0cy5SZXNwb25zZT4ge1xuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZUNhY2hlTmFtZShjYWNoZU5hbWUpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVLZXlFeGlzdHMuRXJyb3IoZXJyKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5yYXRlTGltaXRlZChhc3luYyAoKSA9PiB7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kS2V5RXhpc3RzKGNhY2hlTmFtZSwgdGhpcy5jb252ZXJ0KGtleSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kS2V5RXhpc3RzKFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleTogVWludDhBcnJheVxuICApOiBQcm9taXNlPENhY2hlS2V5RXhpc3RzLlJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVxdWVzdCA9IG5ldyBncnBjQ2FjaGUuX0tleXNFeGlzdFJlcXVlc3Qoe1xuICAgICAgY2FjaGVfa2V5czogW2tleV0sXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5LZXlzRXhpc3QoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUtleUV4aXN0cy5TdWNjZXNzKHJlc3AuZXhpc3RzKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVLZXlFeGlzdHMuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyB1cGRhdGVUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBzdHJpbmcgfCBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVVcGRhdGVUdGwuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICAgIHZhbGlkYXRlVmFsaWRGb3JTZWNvbmRzKHR0bE1pbGxpc2Vjb25kcyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jYWNoZVNlcnZpY2VFcnJvck1hcHBlci5yZXR1cm5PclRocm93RXJyb3IoXG4gICAgICAgIGVyciBhcyBFcnJvcixcbiAgICAgICAgZXJyID0+IG5ldyBDYWNoZVVwZGF0ZVR0bC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRVcGRhdGVUdGwoXG4gICAgICAgIGNhY2hlTmFtZSxcbiAgICAgICAgdGhpcy5jb252ZXJ0KGtleSksXG4gICAgICAgIHR0bE1pbGxpc2Vjb25kc1xuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZFVwZGF0ZVR0bChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZVVwZGF0ZVR0bC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9VcGRhdGVUdGxSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgb3ZlcndyaXRlX3RvX21pbGxpc2Vjb25kczogdHRsTWlsbGlzZWNvbmRzLFxuICAgIH0pO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5jcmVhdGVNZXRhZGF0YShjYWNoZU5hbWUpO1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmNsaWVudFdyYXBwZXIuZ2V0Q2xpZW50KCkuVXBkYXRlVHRsKFxuICAgICAgICByZXF1ZXN0LFxuICAgICAgICBtZXRhZGF0YSxcbiAgICAgICAge1xuICAgICAgICAgIGludGVyY2VwdG9yczogdGhpcy5pbnRlcmNlcHRvcnMsXG4gICAgICAgIH0sXG4gICAgICAgIChlcnIsIHJlc3ApID0+IHtcbiAgICAgICAgICBpZiAocmVzcD8ubWlzc2luZykge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVVcGRhdGVUdGwuTWlzcygpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3A/LnNldCkge1xuICAgICAgICAgICAgcmVzb2x2ZShuZXcgQ2FjaGVVcGRhdGVUdGwuU2V0KCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlVXBkYXRlVHRsLkVycm9yKGUpLFxuICAgICAgICAgICAgICByZXNvbHZlRm46IHJlc29sdmUsXG4gICAgICAgICAgICAgIHJlamVjdEZuOiByZWplY3QsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMga2V5c0V4aXN0KFxuICAgIGNhY2hlTmFtZTogc3RyaW5nLFxuICAgIGtleXM6IHN0cmluZ1tdIHwgVWludDhBcnJheVtdXG4gICk6IFByb21pc2U8Q2FjaGVLZXlzRXhpc3QuUmVzcG9uc2U+IHtcbiAgICB0cnkge1xuICAgICAgdmFsaWRhdGVDYWNoZU5hbWUoY2FjaGVOYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJldHVybk9yVGhyb3dFcnJvcihcbiAgICAgICAgZXJyIGFzIEVycm9yLFxuICAgICAgICBlcnIgPT4gbmV3IENhY2hlS2V5c0V4aXN0LkVycm9yKGVycilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMucmF0ZUxpbWl0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2VuZEtleXNFeGlzdChjYWNoZU5hbWUsIHRoaXMuY29udmVydEFycmF5KGtleXMpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZEtleXNFeGlzdChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXlzOiBVaW50OEFycmF5W11cbiAgKTogUHJvbWlzZTxDYWNoZUtleXNFeGlzdC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9LZXlzRXhpc3RSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleXM6IGtleXMsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5LZXlzRXhpc3QoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUtleXNFeGlzdC5TdWNjZXNzKGtleXMsIHJlc3AuZXhpc3RzKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmVzb2x2ZU9yUmVqZWN0RXJyb3Ioe1xuICAgICAgICAgICAgICBlcnI6IGVycixcbiAgICAgICAgICAgICAgZXJyb3JSZXNwb25zZUZhY3RvcnlGbjogZSA9PiBuZXcgQ2FjaGVLZXlzRXhpc3QuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBpbmNyZWFzZVR0bChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZUluY3JlYXNlVHRsLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVZhbGlkRm9yU2Vjb25kcyh0dGxNaWxsaXNlY29uZHMpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVJbmNyZWFzZVR0bC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRJbmNyZWFzZVR0bChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoa2V5KSxcbiAgICAgICAgdHRsTWlsbGlzZWNvbmRzXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kSW5jcmVhc2VUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVJbmNyZWFzZVR0bC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9VcGRhdGVUdGxSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgaW5jcmVhc2VfdG9fbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5VcGRhdGVUdGwoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZUluY3JlYXNlVHRsLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5zZXQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlSW5jcmVhc2VUdGwuU2V0KCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlSW5jcmVhc2VUdGwuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZWNyZWFzZVR0bChcbiAgICBjYWNoZU5hbWU6IHN0cmluZyxcbiAgICBrZXk6IHN0cmluZyB8IFVpbnQ4QXJyYXksXG4gICAgdHRsTWlsbGlzZWNvbmRzOiBudW1iZXJcbiAgKTogUHJvbWlzZTxDYWNoZURlY3JlYXNlVHRsLlJlc3BvbnNlPiB7XG4gICAgdHJ5IHtcbiAgICAgIHZhbGlkYXRlQ2FjaGVOYW1lKGNhY2hlTmFtZSk7XG4gICAgICB2YWxpZGF0ZVZhbGlkRm9yU2Vjb25kcyh0dGxNaWxsaXNlY29uZHMpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGVTZXJ2aWNlRXJyb3JNYXBwZXIucmV0dXJuT3JUaHJvd0Vycm9yKFxuICAgICAgICBlcnIgYXMgRXJyb3IsXG4gICAgICAgIGVyciA9PiBuZXcgQ2FjaGVEZWNyZWFzZVR0bC5FcnJvcihlcnIpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnJhdGVMaW1pdGVkKGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmREZWNyZWFzZVR0bChcbiAgICAgICAgY2FjaGVOYW1lLFxuICAgICAgICB0aGlzLmNvbnZlcnQoa2V5KSxcbiAgICAgICAgdHRsTWlsbGlzZWNvbmRzXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kRGVjcmVhc2VUdGwoXG4gICAgY2FjaGVOYW1lOiBzdHJpbmcsXG4gICAga2V5OiBVaW50OEFycmF5LFxuICAgIHR0bE1pbGxpc2Vjb25kczogbnVtYmVyXG4gICk6IFByb21pc2U8Q2FjaGVEZWNyZWFzZVR0bC5SZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSBuZXcgZ3JwY0NhY2hlLl9VcGRhdGVUdGxSZXF1ZXN0KHtcbiAgICAgIGNhY2hlX2tleToga2V5LFxuICAgICAgZGVjcmVhc2VfdG9fbWlsbGlzZWNvbmRzOiB0dGxNaWxsaXNlY29uZHMsXG4gICAgfSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmNyZWF0ZU1ldGFkYXRhKGNhY2hlTmFtZSk7XG4gICAgcmV0dXJuIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuY2xpZW50V3JhcHBlci5nZXRDbGllbnQoKS5VcGRhdGVUdGwoXG4gICAgICAgIHJlcXVlc3QsXG4gICAgICAgIG1ldGFkYXRhLFxuICAgICAgICB7XG4gICAgICAgICAgaW50ZXJjZXB0b3JzOiB0aGlzLmludGVyY2VwdG9ycyxcbiAgICAgICAgfSxcbiAgICAgICAgKGVyciwgcmVzcCkgPT4ge1xuICAgICAgICAgIGlmIChyZXNwPy5taXNzaW5nKSB7XG4gICAgICAgICAgICByZXNvbHZlKG5ldyBDYWNoZURlY3JlYXNlVHRsLk1pc3MoKSk7XG4gICAgICAgICAgfSBlbHNlIGlmIChyZXNwPy5zZXQpIHtcbiAgICAgICAgICAgIHJlc29sdmUobmV3IENhY2hlRGVjcmVhc2VUdGwuU2V0KCkpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlU2VydmljZUVycm9yTWFwcGVyLnJlc29sdmVPclJlamVjdEVycm9yKHtcbiAgICAgICAgICAgICAgZXJyOiBlcnIsXG4gICAgICAgICAgICAgIGVycm9yUmVzcG9uc2VGYWN0b3J5Rm46IGUgPT4gbmV3IENhY2hlRGVjcmVhc2VUdGwuRXJyb3IoZSksXG4gICAgICAgICAgICAgIHJlc29sdmVGbjogcmVzb2x2ZSxcbiAgICAgICAgICAgICAgcmVqZWN0Rm46IHJlamVjdCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTWV0YWRhdGEoY2FjaGVOYW1lOiBzdHJpbmcpOiBNZXRhZGF0YSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBuZXcgTWV0YWRhdGEoKTtcbiAgICBtZXRhZGF0YS5zZXQoJ2NhY2hlJywgY2FjaGVOYW1lKTtcbiAgICByZXR1cm4gbWV0YWRhdGE7XG4gIH1cblxuICBwcml2YXRlIHRvU2luZ2xldG9uRmllbGRWYWx1ZVBhaXIoXG4gICAgZmllbGQ6IFVpbnQ4QXJyYXksXG4gICAgdmFsdWU6IFVpbnQ4QXJyYXlcbiAgKTogZ3JwY0NhY2hlLl9EaWN0aW9uYXJ5RmllbGRWYWx1ZVBhaXJbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBncnBjQ2FjaGUuX0RpY3Rpb25hcnlGaWVsZFZhbHVlUGFpcih7XG4gICAgICAgIGZpZWxkOiBmaWVsZCxcbiAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgfSksXG4gICAgXTtcbiAgfVxufVxuIl19