ngx-http-annotations
Version:
This is a library to angular to use http request via decorator/annotations
296 lines • 49.3 kB
JavaScript
import { delay } from 'rxjs/operators';
// noinspection ES6PreferShortImport
import { HTTP_ANNOTATIONS_USE_DELAY, HTTP_ANNOTATIONS_USE_MOCKS, MOCK_DEFAULT_DELAY, NO_DELAY, RESOURCE_METADATA_ROOT } from './ngx-http-annotations.const';
export function observe(annotations) {
return (...args) => HttpRestUtils.decorate('observe', annotations, ...args);
}
export function path(annotations) {
return (...args) => {
return HttpRestUtils.decorate('path', annotations, ...args);
};
}
export function body(annotations) {
return (...args) => HttpRestUtils.decorate('body', annotations, ...args);
}
export function response(annotations) {
return (...args) => HttpRestUtils.decorate('response', annotations, ...args);
}
export function query(annotations) {
return (...args) => HttpRestUtils.decorate('query', annotations, ...args);
}
export function headers(annotations) {
return (...args) => HttpRestUtils.decorate('headers', annotations, ...args);
}
export function produces(annotations) {
return (...args) => HttpRestUtils.decorate('produces', annotations, ...args);
}
export var RequestMethodParams;
(function (RequestMethodParams) {
RequestMethodParams["get"] = "Get";
RequestMethodParams["post"] = "Post";
RequestMethodParams["put"] = "Put";
RequestMethodParams["delete"] = "Delete";
RequestMethodParams["options"] = "Options";
RequestMethodParams["head"] = "Head";
RequestMethodParams["patch"] = "Patch";
})(RequestMethodParams || (RequestMethodParams = {}));
export class HttpRestUtils {
static decorate(decoratorName, annotations, ...args) {
switch (args.length) {
case 1: {
const [target] = args;
HttpRestUtils.constructMetadata(decoratorName, 'class', annotations, target.prototype);
break;
}
case 2: {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [target, __key] = args;
HttpRestUtils.constructMetadata(decoratorName, 'props', annotations, target);
break;
}
case 3:
if (typeof args[2] === 'number') {
const [target, keyName, index] = args;
HttpRestUtils.constructMetadata(decoratorName, 'params', annotations, target, { keyName, index });
break;
}
else {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [target, keyName, __descriptor] = args;
HttpRestUtils.constructMetadata(decoratorName, 'methods', annotations, target, { keyName });
break;
}
default:
throw new Error('Decorators are not valid here!');
}
}
/**
* Set up metadata
* @param entityType
* @param value Value of metadata
* @param target Prototype of current object
* @param metaName Decorator name
* @param entityData Entity extra data
*/
static constructMetadata(metaName, entityType, value, target, entityData) {
target[RESOURCE_METADATA_ROOT] = target[RESOURCE_METADATA_ROOT] || {};
target[RESOURCE_METADATA_ROOT][entityType] = target[RESOURCE_METADATA_ROOT][entityType] || {};
const metadataObj = target[RESOURCE_METADATA_ROOT][entityType];
if (entityData && entityData.keyName) {
metadataObj[entityData.keyName] = metadataObj[entityData.keyName] || {};
}
if (entityData && entityData.index != null) {
metadataObj[entityData.keyName][metaName] = metadataObj[entityData.keyName][metaName] || {};
}
switch (entityType) {
case 'class':
metadataObj[metaName] = value;
break;
case 'props':
metadataObj[metaName] = value;
break;
case 'methods':
(entityData) ? metadataObj[entityData.keyName][metaName] = value : undefined;
break;
case 'params':
(entityData) ? metadataObj[entityData.keyName][metaName][value || 'default'] = entityData.index : undefined;
break;
}
target[RESOURCE_METADATA_ROOT][entityType] = metadataObj;
}
static requestMethod(requestMethodName) {
// @dynamic
return (target, key, descriptor) => {
const originalFunction = descriptor.value;
descriptor.value = function (...args) {
const url = HttpRestUtils.collectUrl(target, key, args);
// tslint:disable-next-line:no-shadowed-variable
const body = HttpRestUtils.collectBodyContent(target, key, args);
const search = HttpRestUtils.collectQueryParams(target, key, args);
// tslint:disable-next-line:no-shadowed-variable
const headers = HttpRestUtils.collectHttpHeaders(target, key, args);
const producesType = HttpRestUtils.produce(target, key, args);
// tslint:disable-next-line:no-shadowed-variable
const observe = HttpRestUtils.getHttpClientObserve(target, key, args);
const params = {
body,
params: search,
headers,
responseType: producesType,
observe
};
const newArgs = args;
const responseIndex = HttpRestUtils.collectResponseIndex(target, key, args);
const callConfig = {
url,
requestMethodName,
params,
args: newArgs,
};
if (HttpRestUtils.ifUseMock(callConfig)) { // If "use mock" is true, call original function, to get mock directly from function
return HttpRestUtils.processIfUseMock(responseIndex, args, newArgs, originalFunction);
}
const request = HttpRestUtils.getRequest(callConfig);
if (responseIndex >= 0) {
if (args.length > responseIndex) {
newArgs[responseIndex] = request;
}
else {
newArgs.splice(responseIndex, 0, request);
}
return originalFunction(...newArgs).pipe(HttpRestUtils.getDelay(callConfig));
}
return request.pipe(HttpRestUtils.getDelay(callConfig));
};
};
}
static getRequest(callConfig) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { body: any, ...params } = callConfig.params;
const requestBody = callConfig.params?.body ?? undefined;
switch (callConfig.requestMethodName) {
case RequestMethodParams.get:
return HttpRestUtils.http.get(callConfig.url, callConfig.params);
case RequestMethodParams.post:
return HttpRestUtils.http.post(callConfig.url, requestBody, params);
case RequestMethodParams.put:
return HttpRestUtils.http.put(callConfig.url, requestBody, params);
case RequestMethodParams.delete:
return HttpRestUtils.http.delete(callConfig.url, callConfig.params);
case RequestMethodParams.options:
return HttpRestUtils.http.options(callConfig.url, callConfig.params);
case RequestMethodParams.head:
return HttpRestUtils.http.head(callConfig.url, callConfig.params);
case RequestMethodParams.patch:
return HttpRestUtils.http.patch(callConfig.url, requestBody, params);
default:
return HttpRestUtils.http.request(callConfig.requestMethodName, callConfig.url, callConfig.params);
}
}
static ifUseMock(callConfig) {
let useMock = HttpRestUtils.appInjector?.get(HTTP_ANNOTATIONS_USE_MOCKS, false);
if (typeof useMock === 'function') {
const useMockFunction = useMock;
useMock = useMockFunction(callConfig.url, callConfig.requestMethodName, callConfig.params, callConfig.args);
}
return useMock;
}
static processIfUseMock(responseIndex, args, newArgs, originalFunction) {
if (responseIndex >= 0) {
if (args.length > responseIndex) {
newArgs[responseIndex] = undefined;
}
else {
newArgs.splice(responseIndex, 0, undefined);
}
}
return originalFunction(...newArgs).pipe(this.getDelay(null, MOCK_DEFAULT_DELAY));
}
static getDelay(callConfig, defaultDelay = NO_DELAY) {
let useDelay = HttpRestUtils.appInjector.get(HTTP_ANNOTATIONS_USE_DELAY, defaultDelay);
if (typeof useDelay === 'function' && callConfig) {
const useGetDelayFunction = useDelay;
useDelay = useGetDelayFunction(callConfig.url, callConfig.requestMethodName, callConfig.params, callConfig.args);
}
return delay(useDelay);
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static getHttpClientObserve(target, methodName, __args) {
if (target[RESOURCE_METADATA_ROOT].methods
&& target[RESOURCE_METADATA_ROOT].methods[methodName]) {
return target[RESOURCE_METADATA_ROOT].methods[methodName].observe;
}
return undefined;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static produce(target, methodName, __args) {
if (target[RESOURCE_METADATA_ROOT].methods
&& target[RESOURCE_METADATA_ROOT].methods[methodName]) {
return target[RESOURCE_METADATA_ROOT].methods[methodName].produces;
}
return 'json';
}
static collectUrl(target, methodName, args) {
const baseUrl = target[RESOURCE_METADATA_ROOT] && target[RESOURCE_METADATA_ROOT].class
? target[RESOURCE_METADATA_ROOT].class.path
: '';
const methodUrl = target[RESOURCE_METADATA_ROOT].methods && target[RESOURCE_METADATA_ROOT].methods[methodName]
? target[RESOURCE_METADATA_ROOT].methods[methodName].path
: '';
const isRelativePath = `${baseUrl}${methodUrl}`[0] === '/';
const methodUrlWithParams = [baseUrl, methodUrl]
.filter(pathToFilter => pathToFilter)
.join('/')
.split('/')
.map(pathParams => {
if (pathParams[0] === ':') {
const paramName = pathParams.substring(1);
const index = target[RESOURCE_METADATA_ROOT].params
&& target[RESOURCE_METADATA_ROOT].params[methodName]
&& target[RESOURCE_METADATA_ROOT].params[methodName].path
? target[RESOURCE_METADATA_ROOT].params[methodName].path[paramName]
: '';
return args[index];
}
return pathParams;
})
.filter(pathToFilter => pathToFilter)
.join('/');
if (!isRelativePath) {
const [absolutePrefix, ...paths] = methodUrlWithParams.split('/');
return `${absolutePrefix}//${paths.join('/')}`;
}
return `/${methodUrlWithParams}`;
}
static collectBodyContent(target, methodName, args) {
if (!target[RESOURCE_METADATA_ROOT].params
|| !target[RESOURCE_METADATA_ROOT].params[methodName]
|| !target[RESOURCE_METADATA_ROOT].params[methodName].body) {
return undefined;
}
const index = target[RESOURCE_METADATA_ROOT].params[methodName].body.default;
return args[index];
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static collectResponseIndex(target, methodName, __args) {
if (!target[RESOURCE_METADATA_ROOT].params
|| !target[RESOURCE_METADATA_ROOT].params[methodName]
|| !target[RESOURCE_METADATA_ROOT].params[methodName].response) {
return undefined;
}
return target[RESOURCE_METADATA_ROOT].params[methodName].response.default;
}
static collectQueryParams(target, methodName, args) {
if (!target[RESOURCE_METADATA_ROOT].params
|| !target[RESOURCE_METADATA_ROOT].params[methodName]
|| !target[RESOURCE_METADATA_ROOT].params[methodName].query) {
return undefined;
}
const queryParams = {};
const queryParamsObjectIndex = target[RESOURCE_METADATA_ROOT].params[methodName].query.default;
const queryMetadata = target[RESOURCE_METADATA_ROOT].params[methodName].query;
const queryParamsCollection = queryParamsObjectIndex !== undefined
? args[queryParamsObjectIndex]
: Object.keys(queryMetadata).reduce((mergedObj, paramName) => Object.assign(mergedObj, { [paramName]: args[queryMetadata[paramName]] }), {});
Object.keys(queryParamsCollection)
.forEach((paramName) => {
let value = queryParamsCollection[paramName];
if (!Array.isArray(value)) {
value = [value];
}
value.forEach((curParam) => {
return queryParams[paramName] = curParam;
});
});
return queryParams;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static collectHttpHeaders(target, methodName, __args) {
const classHeaders = target[RESOURCE_METADATA_ROOT].class ? target[RESOURCE_METADATA_ROOT].class.headers : {};
const methodHeaders = target[RESOURCE_METADATA_ROOT].methods && target[RESOURCE_METADATA_ROOT].methods[methodName]
? target[RESOURCE_METADATA_ROOT].methods[methodName].headers
: {};
return Object.assign({}, classHeaders, methodHeaders);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWh0dHAtYW5ub3RhdGlvbnMudXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL25neC1odHRwLWFubm90YXRpb25zL3NyYy9saWIvbmd4LWh0dHAtYW5ub3RhdGlvbnMudXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBSUEsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3ZDLG9DQUFvQztBQUNwQyxPQUFPLEVBQ0wsMEJBQTBCLEVBQzFCLDBCQUEwQixFQUMxQixrQkFBa0IsRUFDbEIsUUFBUSxFQUNSLHNCQUFzQixFQUN2QixNQUFNLDhCQUE4QixDQUFDO0FBUXRDLE1BQU0sVUFBVSxPQUFPLENBQUMsV0FBZ0I7SUFDdEMsT0FBTyxDQUFDLEdBQUcsSUFBVyxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQztBQUNyRixDQUFDO0FBQ0QsTUFBTSxVQUFVLElBQUksQ0FBQyxXQUFnQjtJQUNuQyxPQUFPLENBQUMsR0FBRyxJQUFXLEVBQUUsRUFBRTtRQUN4QixPQUFPLGFBQWEsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQzlELENBQUMsQ0FBQztBQUNKLENBQUM7QUFDRCxNQUFNLFVBQVUsSUFBSSxDQUFDLFdBQWdCO0lBQ25DLE9BQU8sQ0FBQyxHQUFHLElBQVcsRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsV0FBVyxFQUFFLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDbEYsQ0FBQztBQUVELE1BQU0sVUFBVSxRQUFRLENBQUMsV0FBZ0I7SUFDdkMsT0FBTyxDQUFDLEdBQUcsSUFBVyxFQUFFLEVBQUUsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxXQUFXLEVBQUUsR0FB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SSxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO1lBQzlGLENBQUMsQ0FBQyxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsT0FBTztZQUM1RCxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsWUFBWSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3hELENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3RvciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTW9ub1R5cGVPcGVyYXRvckZ1bmN0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWxheSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbi8vIG5vaW5zcGVjdGlvbiBFUzZQcmVmZXJTaG9ydEltcG9ydFxuaW1wb3J0IHtcbiAgSFRUUF9BTk5PVEFUSU9OU19VU0VfREVMQVksXG4gIEhUVFBfQU5OT1RBVElPTlNfVVNFX01PQ0tTLFxuICBNT0NLX0RFRkFVTFRfREVMQVksXG4gIE5PX0RFTEFZLFxuICBSRVNPVVJDRV9NRVRBREFUQV9ST09UXG59IGZyb20gJy4vbmd4LWh0dHAtYW5ub3RhdGlvbnMuY29uc3QnO1xuXG5cbmludGVyZmFjZSBDYWxsQ29uZmlnIHt1cmw6IHN0cmluZzsgcmVxdWVzdE1ldGhvZE5hbWU6IHN0cmluZzsgcGFyYW1zOiBhbnk7IGFyZ3M6IGFueVtdOyB9XG50eXBlIE1vY2tGdW5jdGlvbiA9ICh1cmw6IHN0cmluZywgcmVxdWVzdE1ldGhvZE5hbWU6IHN0cmluZywgcGFyYW1zOiBhbnksIGFyZ3M6IGFueVtdKSA9PiBhbnk7XG50eXBlIERlbGF5RnVuY3Rpb24gPSAodXJsOiBzdHJpbmcsIHJlcXVlc3RNZXRob2ROYW1lOiBzdHJpbmcsIHBhcmFtczogYW55LCBhcmdzOiBhbnlbXSkgPT4gYW55O1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBvYnNlcnZlKGFubm90YXRpb25zOiBhbnkpIHtcbiAgcmV0dXJuICguLi5hcmdzOiBhbnlbXSkgPT4gSHR0cFJlc3RVdGlscy5kZWNvcmF0ZSgnb2JzZXJ2ZScsIGFubm90YXRpb25zLCAuLi5hcmdzKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBwYXRoKGFubm90YXRpb25zOiBhbnkpIHtcbiAgcmV0dXJuICguLi5hcmdzOiBhbnlbXSkgPT4ge1xuICAgIHJldHVybiBIdHRwUmVzdFV0aWxzLmRlY29yYXRlKCdwYXRoJywgYW5ub3RhdGlvbnMsIC4uLmFyZ3MpO1xuICB9O1xufVxuZXhwb3J0IGZ1bmN0aW9uIGJvZHkoYW5ub3RhdGlvbnM6IGFueSkge1xuICByZXR1cm4gKC4uLmFyZ3M6IGFueVtdKSA9PiBIdHRwUmVzdFV0aWxzLmRlY29yYXRlKCdib2R5JywgYW5ub3RhdGlvbnMsIC4uLmFyZ3MpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzcG9uc2UoYW5ub3RhdGlvbnM6IGFueSkge1xuICByZXR1cm4gKC4uLmFyZ3M6IGFueVtdKSA9PiBIdHRwUmVzdFV0aWxzLmRlY29yYXRlKCdyZXNwb25zZScsIGFubm90YXRpb25zLCAuLi5hcmdzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHF1ZXJ5KGFubm90YXRpb25zOiBhbnkpIHtcbiAgcmV0dXJuICguLi5hcmdzOiBhbnlbXSkgPT4gSHR0cFJlc3RVdGlscy5kZWNvcmF0ZSgncXVlcnknLCBhbm5vdGF0aW9ucywgLi4uYXJncyk7XG59XG5leHBvcnQgZnVuY3Rpb24gaGVhZGVycyhhbm5vdGF0aW9uczogYW55KSB7XG4gIHJldHVybiAoLi4uYXJnczogYW55W10pID0+IEh0dHBSZXN0VXRpbHMuZGVjb3JhdGUoJ2hlYWRlcnMnLCBhbm5vdGF0aW9ucywgLi4uYXJncyk7XG59XG5leHBvcnQgZnVuY3Rpb24gcHJvZHVjZXMoYW5ub3RhdGlvbnM6ICdhcnJheWJ1ZmZlcicgfCAnYmxvYicgfCAnanNvbicgfCAndGV4dCcpIHtcbiAgcmV0dXJuICguLi5hcmdzOiBhbnlbXSkgPT4gSHR0cFJlc3RVdGlscy5kZWNvcmF0ZSgncHJvZHVjZXMnLCBhbm5vdGF0aW9ucywgLi4uYXJncyk7XG59XG5cbnR5cGUgUmVzb3VyY2VNZXRhZGF0YVR5cGUgPSAnY2xhc3MnfCdtZXRob2RzJ3wncGFyYW1zJ3wncHJvcHMnO1xuaW50ZXJmYWNlIEV4dHJhRW50aXR5RGF0YSB7XG4gIGtleU5hbWU6IHN0cmluZztcbiAgaW5kZXg/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBlbnVtIFJlcXVlc3RNZXRob2RQYXJhbXMge1xuICBnZXQgPSAnR2V0JyxcbiAgcG9zdCA9ICdQb3N0JyxcbiAgcHV0ID0gJ1B1dCcsXG4gIGRlbGV0ZSA9ICdEZWxldGUnLFxuICBvcHRpb25zID0gJ09wdGlvbnMnLFxuICBoZWFkID0gJ0hlYWQnLFxuICBwYXRjaCA9ICdQYXRjaCdcbn1cblxuZXhwb3J0IGNsYXNzIEh0dHBSZXN0VXRpbHMge1xuXG4gIHB1YmxpYyBzdGF0aWMgaHR0cDogSHR0cENsaWVudDtcbiAgcHVibGljIHN0YXRpYyBhcHBJbmplY3RvcjogSW5qZWN0b3I7XG5cbiAgcHVibGljIHN0YXRpYyBkZWNvcmF0ZShkZWNvcmF0b3JOYW1lOiBzdHJpbmcsIGFubm90YXRpb25zOiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgIHN3aXRjaCAoYXJncy5sZW5ndGgpIHtcbiAgICAgICAgY2FzZSAxOiB7XG4gICAgICAgICAgY29uc3QgW3RhcmdldF0gPSBhcmdzO1xuICAgICAgICAgIEh0dHBSZXN0VXRpbHMuY29uc3RydWN0TWV0YWRhdGEoIGRlY29yYXRvck5hbWUsICdjbGFzcycsIGFubm90YXRpb25zLCB0YXJnZXQucHJvdG90eXBlICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSAyOiB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgICAgIGNvbnN0IFt0YXJnZXQsIF9fa2V5XSA9IGFyZ3M7XG4gICAgICAgICAgSHR0cFJlc3RVdGlscy5jb25zdHJ1Y3RNZXRhZGF0YSggZGVjb3JhdG9yTmFtZSwgJ3Byb3BzJywgYW5ub3RhdGlvbnMsIHRhcmdldCApO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgMzpcbiAgICAgICAgICBpZiAodHlwZW9mIGFyZ3NbMl0gPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBjb25zdCBbdGFyZ2V0LCBrZXlOYW1lLCBpbmRleF0gPSBhcmdzO1xuICAgICAgICAgICAgSHR0cFJlc3RVdGlscy5jb25zdHJ1Y3RNZXRhZGF0YSggZGVjb3JhdG9yTmFtZSwgJ3BhcmFtcycsIGFubm90YXRpb25zLCB0YXJnZXQsIHsga2V5TmFtZSwgaW5kZXggfSApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgICAgICAgIGNvbnN0IFt0YXJnZXQsIGtleU5hbWUsIF9fZGVzY3JpcHRvcl0gPSBhcmdzO1xuICAgICAgICAgICAgSHR0cFJlc3RVdGlscy5jb25zdHJ1Y3RNZXRhZGF0YSggZGVjb3JhdG9yTmFtZSwgJ21ldGhvZHMnLCBhbm5vdGF0aW9ucywgdGFyZ2V0LCB7IGtleU5hbWUgfSApO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGVjb3JhdG9ycyBhcmUgbm90IHZhbGlkIGhlcmUhJyk7XG4gICAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0IHVwIG1ldGFkYXRhXG4gICAqIEBwYXJhbSBlbnRpdHlUeXBlXG4gICAqIEBwYXJhbSB2YWx1ZSBWYWx1ZSBvZiBtZXRhZGF0YVxuICAgKiBAcGFyYW0gdGFyZ2V0IFByb3RvdHlwZSBvZiBjdXJyZW50IG9iamVjdFxuICAgKiBAcGFyYW0gbWV0YU5hbWUgRGVjb3JhdG9yIG5hbWVcbiAgICogQHBhcmFtIGVudGl0eURhdGEgRW50aXR5IGV4dHJhIGRhdGFcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGNvbnN0cnVjdE1ldGFkYXRhKFxuICAgIG1ldGFOYW1lOiBzdHJpbmcsXG4gICAgZW50aXR5VHlwZTogUmVzb3VyY2VNZXRhZGF0YVR5cGUsXG4gICAgdmFsdWU6IGFueSxcbiAgICB0YXJnZXQ6IGFueSxcbiAgICBlbnRpdHlEYXRhPzogRXh0cmFFbnRpdHlEYXRhKSB7XG5cbiAgICB0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0gPSB0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0gfHwge307XG4gICAgdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdW2VudGl0eVR5cGVdID0gdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdW2VudGl0eVR5cGVdIHx8IHt9O1xuXG4gICBjb25zdCBtZXRhZGF0YU9iaiA9IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXVtlbnRpdHlUeXBlXTtcbiAgICBpZiAoZW50aXR5RGF0YSAmJiBlbnRpdHlEYXRhLmtleU5hbWUpIHtcbiAgICAgIG1ldGFkYXRhT2JqW2VudGl0eURhdGEua2V5TmFtZV0gPSBtZXRhZGF0YU9ialtlbnRpdHlEYXRhLmtleU5hbWVdIHx8IHt9O1xuICAgIH1cbiAgICBpZiAoZW50aXR5RGF0YSAmJiBlbnRpdHlEYXRhLmluZGV4ICE9IG51bGwpIHtcbiAgICAgIG1ldGFkYXRhT2JqW2VudGl0eURhdGEua2V5TmFtZV1bbWV0YU5hbWVdID0gbWV0YWRhdGFPYmpbZW50aXR5RGF0YS5rZXlOYW1lXVttZXRhTmFtZV0gfHwge307XG4gICAgfVxuICAgIHN3aXRjaCAoZW50aXR5VHlwZSkge1xuICAgICAgY2FzZSAnY2xhc3MnOiBtZXRhZGF0YU9ialttZXRhTmFtZV0gPSB2YWx1ZTsgYnJlYWs7XG4gICAgICBjYXNlICdwcm9wcyc6IG1ldGFkYXRhT2JqW21ldGFOYW1lXSA9IHZhbHVlOyBicmVhaztcbiAgICAgIGNhc2UgJ21ldGhvZHMnOlxuICAgICAgICAoZW50aXR5RGF0YSk/IG1ldGFkYXRhT2JqW2VudGl0eURhdGEua2V5TmFtZV1bbWV0YU5hbWVdID0gdmFsdWUgOiB1bmRlZmluZWQ7XG4gICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3BhcmFtcyc6XG4gICAgICAgIChlbnRpdHlEYXRhKT8gbWV0YWRhdGFPYmpbZW50aXR5RGF0YS5rZXlOYW1lXVttZXRhTmFtZV1bdmFsdWUgfHwgJ2RlZmF1bHQnXSA9IGVudGl0eURhdGEuaW5kZXg6IHVuZGVmaW5lZDtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdW2VudGl0eVR5cGVdID0gbWV0YWRhdGFPYmo7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIHJlcXVlc3RNZXRob2QocmVxdWVzdE1ldGhvZE5hbWU6IFJlcXVlc3RNZXRob2RQYXJhbXMpOiBhbnkge1xuICAgICAgLy8gQGR5bmFtaWNcbiAgICByZXR1cm4gKHRhcmdldDogYW55LCBrZXk6IHN0cmluZywgZGVzY3JpcHRvcjogYW55KSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW5hbEZ1bmN0aW9uID0gZGVzY3JpcHRvci52YWx1ZTtcblxuICAgICAgICBkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24gKC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgICAgICAgY29uc3QgdXJsID0gSHR0cFJlc3RVdGlscy5jb2xsZWN0VXJsKHRhcmdldCwga2V5LCBhcmdzKTtcbiAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tc2hhZG93ZWQtdmFyaWFibGVcbiAgICAgICAgICBjb25zdCBib2R5ID0gSHR0cFJlc3RVdGlscy5jb2xsZWN0Qm9keUNvbnRlbnQodGFyZ2V0LCBrZXksIGFyZ3MpO1xuICAgICAgICAgIGNvbnN0IHNlYXJjaCA9IEh0dHBSZXN0VXRpbHMuY29sbGVjdFF1ZXJ5UGFyYW1zKHRhcmdldCwga2V5LCBhcmdzKTtcbiAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tc2hhZG93ZWQtdmFyaWFibGVcbiAgICAgICAgICBjb25zdCBoZWFkZXJzID0gSHR0cFJlc3RVdGlscy5jb2xsZWN0SHR0cEhlYWRlcnModGFyZ2V0LCBrZXksIGFyZ3MpO1xuICAgICAgICAgIGNvbnN0IHByb2R1Y2VzVHlwZSA9IEh0dHBSZXN0VXRpbHMucHJvZHVjZSh0YXJnZXQsIGtleSwgYXJncyk7XG4gICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXNoYWRvd2VkLXZhcmlhYmxlXG4gICAgICAgICAgY29uc3Qgb2JzZXJ2ZSA9IEh0dHBSZXN0VXRpbHMuZ2V0SHR0cENsaWVudE9ic2VydmUodGFyZ2V0LCBrZXksIGFyZ3MpO1xuICAgICAgICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgIHBhcmFtczogc2VhcmNoLFxuICAgICAgICAgICAgaGVhZGVycyxcbiAgICAgICAgICAgIHJlc3BvbnNlVHlwZTogcHJvZHVjZXNUeXBlLFxuICAgICAgICAgICAgb2JzZXJ2ZVxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgbmV3QXJncyA9IGFyZ3M7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2VJbmRleCA9IEh0dHBSZXN0VXRpbHMuY29sbGVjdFJlc3BvbnNlSW5kZXgodGFyZ2V0LCBrZXksIGFyZ3MpO1xuICAgICAgICAgIGNvbnN0IGNhbGxDb25maWc6IENhbGxDb25maWcgPSB7XG4gICAgICAgICAgICB1cmwsXG4gICAgICAgICAgICByZXF1ZXN0TWV0aG9kTmFtZSxcbiAgICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICAgIGFyZ3M6IG5ld0FyZ3MsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGlmIChIdHRwUmVzdFV0aWxzLmlmVXNlTW9jayhjYWxsQ29uZmlnKSkgeyAvLyBJZiBcInVzZSBtb2NrXCIgaXMgdHJ1ZSwgY2FsbCBvcmlnaW5hbCBmdW5jdGlvbiwgdG8gZ2V0IG1vY2sgZGlyZWN0bHkgZnJvbSBmdW5jdGlvblxuICAgICAgICAgICAgcmV0dXJuIEh0dHBSZXN0VXRpbHMucHJvY2Vzc0lmVXNlTW9jayhyZXNwb25zZUluZGV4LCBhcmdzLCBuZXdBcmdzLCBvcmlnaW5hbEZ1bmN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcmVxdWVzdCA9IEh0dHBSZXN0VXRpbHMuZ2V0UmVxdWVzdChjYWxsQ29uZmlnKTtcblxuXG5cbiAgICAgICAgICBpZiAocmVzcG9uc2VJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPiByZXNwb25zZUluZGV4KSB7XG4gICAgICAgICAgICAgIG5ld0FyZ3NbcmVzcG9uc2VJbmRleF0gPSByZXF1ZXN0O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgbmV3QXJncy5zcGxpY2UocmVzcG9uc2VJbmRleCwgMCwgcmVxdWVzdCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBvcmlnaW5hbEZ1bmN0aW9uKC4uLm5ld0FyZ3MpLnBpcGUoSHR0cFJlc3RVdGlscy5nZXREZWxheShjYWxsQ29uZmlnKSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlcXVlc3QucGlwZShIdHRwUmVzdFV0aWxzLmdldERlbGF5KGNhbGxDb25maWcpKTtcbiAgICAgICAgfTtcblxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBnZXRSZXF1ZXN0KGNhbGxDb25maWc6IENhbGxDb25maWcpIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgY29uc3Qge2JvZHk6IGFueSwgLi4ucGFyYW1zfSA9ICBjYWxsQ29uZmlnLnBhcmFtcztcbiAgICBjb25zdCByZXF1ZXN0Qm9keSA9IGNhbGxDb25maWcucGFyYW1zPy5ib2R5ID8/IHVuZGVmaW5lZDtcbiAgICBzd2l0Y2ggKGNhbGxDb25maWcucmVxdWVzdE1ldGhvZE5hbWUpIHtcbiAgICAgIGNhc2UgUmVxdWVzdE1ldGhvZFBhcmFtcy5nZXQ6XG4gICAgICAgIHJldHVybiBIdHRwUmVzdFV0aWxzLmh0dHAuZ2V0KGNhbGxDb25maWcudXJsLCBjYWxsQ29uZmlnLnBhcmFtcyk7XG4gICAgICBjYXNlIFJlcXVlc3RNZXRob2RQYXJhbXMucG9zdDpcbiAgICAgICAgcmV0dXJuIEh0dHBSZXN0VXRpbHMuaHR0cC5wb3N0KGNhbGxDb25maWcudXJsLCByZXF1ZXN0Qm9keSwgcGFyYW1zKTtcbiAgICAgIGNhc2UgUmVxdWVzdE1ldGhvZFBhcmFtcy5wdXQ6XG4gICAgICAgIHJldHVybiBIdHRwUmVzdFV0aWxzLmh0dHAucHV0KGNhbGxDb25maWcudXJsLCByZXF1ZXN0Qm9keSwgcGFyYW1zKTtcbiAgICAgIGNhc2UgUmVxdWVzdE1ldGhvZFBhcmFtcy5kZWxldGU6XG4gICAgICAgIHJldHVybiBIdHRwUmVzdFV0aWxzLmh0dHAuZGVsZXRlKGNhbGxDb25maWcudXJsLCBjYWxsQ29uZmlnLnBhcmFtcyk7XG4gICAgICBjYXNlIFJlcXVlc3RNZXRob2RQYXJhbXMub3B0aW9uczpcbiAgICAgICAgcmV0dXJuIEh0dHBSZXN0VXRpbHMuaHR0cC5vcHRpb25zKGNhbGxDb25maWcudXJsLCBjYWxsQ29uZmlnLnBhcmFtcyk7XG4gICAgICBjYXNlIFJlcXVlc3RNZXRob2RQYXJhbXMuaGVhZDpcbiAgICAgICAgcmV0dXJuIEh0dHBSZXN0VXRpbHMuaHR0cC5oZWFkKGNhbGxDb25maWcudXJsLCBjYWxsQ29uZmlnLnBhcmFtcyk7XG4gICAgICBjYXNlIFJlcXVlc3RNZXRob2RQYXJhbXMucGF0Y2g6XG4gICAgICAgIHJldHVybiBIdHRwUmVzdFV0aWxzLmh0dHAucGF0Y2goY2FsbENvbmZpZy51cmwsIHJlcXVlc3RCb2R5LCBwYXJhbXMpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIEh0dHBSZXN0VXRpbHMuaHR0cC5yZXF1ZXN0KGNhbGxDb25maWcucmVxdWVzdE1ldGhvZE5hbWUsIGNhbGxDb25maWcudXJsLCBjYWxsQ29uZmlnLnBhcmFtcyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgaWZVc2VNb2NrKGNhbGxDb25maWc6IENhbGxDb25maWcpOiBib29sZWFuIHwgTW9ja0Z1bmN0aW9uIHtcbiAgICBsZXQgdXNlTW9jazogYm9vbGVhbiB8IE1vY2tGdW5jdGlvbiA9IEh0dHBSZXN0VXRpbHMuYXBwSW5qZWN0b3I/LmdldChIVFRQX0FOTk9UQVRJT05TX1VTRV9NT0NLUywgZmFsc2UpO1xuICAgIGlmICh0eXBlb2YgdXNlTW9jayA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgdXNlTW9ja0Z1bmN0aW9uID0gdXNlTW9jayBhcyBNb2NrRnVuY3Rpb247XG4gICAgICB1c2VNb2NrID0gdXNlTW9ja0Z1bmN0aW9uKGNhbGxDb25maWcudXJsLCBjYWxsQ29uZmlnLnJlcXVlc3RNZXRob2ROYW1lLCBjYWxsQ29uZmlnLnBhcmFtcywgY2FsbENvbmZpZy5hcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIHVzZU1vY2s7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBwcm9jZXNzSWZVc2VNb2NrKHJlc3BvbnNlSW5kZXg6IG51bWJlciwgYXJnczogYW55W10sIG5ld0FyZ3M6IGFueVtdLCBvcmlnaW5hbEZ1bmN0aW9uOiBhbnkpOiBhbnkge1xuICAgIGlmIChyZXNwb25zZUluZGV4ID49IDApIHtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA+IHJlc3BvbnNlSW5kZXgpIHtcbiAgICAgICAgbmV3QXJnc1tyZXNwb25zZUluZGV4XSA9IHVuZGVmaW5lZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld0FyZ3Muc3BsaWNlKHJlc3BvbnNlSW5kZXgsIDAsIHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvcmlnaW5hbEZ1bmN0aW9uKC4uLm5ld0FyZ3MpLnBpcGUodGhpcy5nZXREZWxheShudWxsLCBNT0NLX0RFRkFVTFRfREVMQVkpKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGdldERlbGF5KGNhbGxDb25maWc6IENhbGxDb25maWcgfCBudWxsLCBkZWZhdWx0RGVsYXk6IG51bWJlciA9IE5PX0RFTEFZKTogTW9ub1R5cGVPcGVyYXRvckZ1bmN0aW9uPHVua25vd24+IHtcbiAgICBsZXQgdXNlRGVsYXk6IG51bWJlciB8IERlbGF5RnVuY3Rpb24gPSBIdHRwUmVzdFV0aWxzLmFwcEluamVjdG9yLmdldChIVFRQX0FOTk9UQVRJT05TX1VTRV9ERUxBWSwgZGVmYXVsdERlbGF5KTtcbiAgICBpZiAodHlwZW9mIHVzZURlbGF5ID09PSAnZnVuY3Rpb24nICYmIGNhbGxDb25maWcpIHtcbiAgICAgIGNvbnN0IHVzZUdldERlbGF5RnVuY3Rpb24gPSB1c2VEZWxheSBhcyBEZWxheUZ1bmN0aW9uO1xuICAgICAgdXNlRGVsYXkgPSB1c2VHZXREZWxheUZ1bmN0aW9uKGNhbGxDb25maWcudXJsLCBjYWxsQ29uZmlnLnJlcXVlc3RNZXRob2ROYW1lLCBjYWxsQ29uZmlnLnBhcmFtcywgY2FsbENvbmZpZy5hcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlbGF5KHVzZURlbGF5IGFzIG51bWJlcik7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIHByaXZhdGUgc3RhdGljIGdldEh0dHBDbGllbnRPYnNlcnZlKHRhcmdldDogYW55LCBtZXRob2ROYW1lOiBzdHJpbmcsIF9fYXJnczogYW55W10pIHtcbiAgICBpZiAodGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLm1ldGhvZHNcbiAgICAgICYmIHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5tZXRob2RzW21ldGhvZE5hbWVdKSB7XG4gICAgICAgcmV0dXJuIHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5tZXRob2RzW21ldGhvZE5hbWVdLm9ic2VydmU7XG4gICAgIH1cbiAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcHJpdmF0ZSBzdGF0aWMgcHJvZHVjZSh0YXJnZXQ6IGFueSwgbWV0aG9kTmFtZTogc3RyaW5nLCBfX2FyZ3M6IGFueVtdKSB7XG4gICAgaWYgKHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5tZXRob2RzXG4gICAgICYmIHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5tZXRob2RzW21ldGhvZE5hbWVdKSB7XG4gICAgICByZXR1cm4gdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLm1ldGhvZHNbbWV0aG9kTmFtZV0ucHJvZHVjZXM7XG4gICAgfVxuICAgIHJldHVybiAnanNvbic7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjb2xsZWN0VXJsKHRhcmdldDogYW55LCBtZXRob2ROYW1lOiBzdHJpbmcsIGFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgYmFzZVVybCA9IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXSAmJiB0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0uY2xhc3NcbiAgICAgICAgICAgICAgICAgID8gdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLmNsYXNzLnBhdGhcbiAgICAgICAgICAgICAgICAgIDogJyc7XG4gICAgY29uc3QgbWV0aG9kVXJsID0gdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLm1ldGhvZHMgJiYgdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLm1ldGhvZHNbbWV0aG9kTmFtZV1cbiAgICAgICAgICAgICAgICAgICAgPyB0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0ubWV0aG9kc1ttZXRob2ROYW1lXS5wYXRoXG4gICAgICAgICAgICAgICAgICAgIDogJyc7XG4gICAgY29uc3QgaXNSZWxhdGl2ZVBhdGggPSBgJHtiYXNlVXJsfSR7bWV0aG9kVXJsfWBbMF0gPT09ICcvJztcbiAgICBjb25zdCBtZXRob2RVcmxXaXRoUGFyYW1zXG4gICAgICA9IFtiYXNlVXJsLCBtZXRob2RVcmxdXG4gICAgICAgIC5maWx0ZXIocGF0aFRvRmlsdGVyID0+IHBhdGhUb0ZpbHRlcilcbiAgICAgICAgLmpvaW4oJy8nKVxuICAgICAgICAuc3BsaXQoJy8nKVxuICAgICAgICAubWFwKHBhdGhQYXJhbXMgPT4ge1xuICAgICAgICAgIGlmICggcGF0aFBhcmFtc1swXSA9PT0gJzonKSB7XG4gICAgICAgICAgICBjb25zdCBwYXJhbU5hbWUgPSBwYXRoUGFyYW1zLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLnBhcmFtc1xuICAgICAgICAgICAgICAgICAgICAgICAmJiB0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0ucGFyYW1zW21ldGhvZE5hbWVdXG4gICAgICAgICAgICAgICAgICAgICAgICYmIHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5wYXJhbXNbbWV0aG9kTmFtZV0ucGF0aFxuICAgICAgICAgICAgICAgICAgICAgICAgPyB0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0ucGFyYW1zW21ldGhvZE5hbWVdLnBhdGhbcGFyYW1OYW1lXVxuICAgICAgICAgICAgICAgICAgICAgICAgOiAnJztcbiAgICAgICAgICAgIHJldHVybiBhcmdzW2luZGV4XTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHBhdGhQYXJhbXM7XG4gICAgICAgIH0pXG4gICAgICAgIC5maWx0ZXIocGF0aFRvRmlsdGVyID0+IHBhdGhUb0ZpbHRlcilcbiAgICAgICAgLmpvaW4oJy8nKTtcblxuICAgIGlmICghaXNSZWxhdGl2ZVBhdGgpIHtcbiAgICAgIGNvbnN0IFthYnNvbHV0ZVByZWZpeCwgLi4ucGF0aHNdID0gbWV0aG9kVXJsV2l0aFBhcmFtcy5zcGxpdCgnLycpO1xuICAgICAgcmV0dXJuIGAkeyBhYnNvbHV0ZVByZWZpeCB9Ly8keyBwYXRocy5qb2luKCcvJykgfWA7XG4gICAgfVxuICAgIHJldHVybiBgLyR7IG1ldGhvZFVybFdpdGhQYXJhbXMgfWA7XG4gIH1cblxuICBwcml2YXRlIHN0YXRpYyBjb2xsZWN0Qm9keUNvbnRlbnQodGFyZ2V0OiBhbnksIG1ldGhvZE5hbWU6IHN0cmluZywgYXJnczogYW55W10pIHtcbiAgICBpZiAoIXRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5wYXJhbXNcbiAgICAgfHwgIXRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5wYXJhbXNbbWV0aG9kTmFtZV1cbiAgICAgfHwgIXRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5wYXJhbXNbbWV0aG9kTmFtZV0uYm9keSkgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG5cbiAgICBjb25zdCBpbmRleCA9IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5wYXJhbXNbbWV0aG9kTmFtZV0uYm9keS5kZWZhdWx0O1xuICAgIHJldHVybiBhcmdzW2luZGV4XTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgcHJpdmF0ZSBzdGF0aWMgY29sbGVjdFJlc3BvbnNlSW5kZXgodGFyZ2V0OiBhbnksIG1ldGhvZE5hbWU6IHN0cmluZywgX19hcmdzOiBhbnlbXSkge1xuICAgIGlmICghdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLnBhcmFtc1xuICAgICB8fCAhdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLnBhcmFtc1ttZXRob2ROYW1lXVxuICAgICB8fCAhdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLnBhcmFtc1ttZXRob2ROYW1lXS5yZXNwb25zZSkgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG5cbiAgICByZXR1cm4gdGFyZ2V0W1JFU09VUkNFX01FVEFEQVRBX1JPT1RdLnBhcmFtc1ttZXRob2ROYW1lXS5yZXNwb25zZS5kZWZhdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY29sbGVjdFF1ZXJ5UGFyYW1zKHRhcmdldDogYW55LCBtZXRob2ROYW1lOiBzdHJpbmcsIGFyZ3M6IGFueVtdKSB7XG4gICAgaWYgKCF0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0ucGFyYW1zXG4gICAgIHx8ICF0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0ucGFyYW1zW21ldGhvZE5hbWVdXG4gICAgIHx8ICF0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0ucGFyYW1zW21ldGhvZE5hbWVdLnF1ZXJ5KSB7IHJldHVybiB1bmRlZmluZWQ7IH1cblxuICAgIGNvbnN0IHF1ZXJ5UGFyYW1zOiB7W2tleTogc3RyaW5nXTogYW55fSA9IHt9O1xuICAgIGNvbnN0IHF1ZXJ5UGFyYW1zT2JqZWN0SW5kZXggPSB0YXJnZXRbUkVTT1VSQ0VfTUVUQURBVEFfUk9PVF0ucGFyYW1zW21ldGhvZE5hbWVdLnF1ZXJ5LmRlZmF1bHQ7XG4gICAgY29uc3QgcXVlcnlNZXRhZGF0YSA9IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5wYXJhbXNbbWV0aG9kTmFtZV0ucXVlcnk7XG4gICAgY29uc3QgcXVlcnlQYXJhbXNDb2xsZWN0aW9uID0gcXVlcnlQYXJhbXNPYmplY3RJbmRleCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gYXJnc1txdWVyeVBhcmFtc09iamVjdEluZGV4XVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IE9iamVjdC5rZXlzKHF1ZXJ5TWV0YWRhdGEpLnJlZHVjZSgobWVyZ2VkT2JqLCBwYXJhbU5hbWUpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihtZXJnZWRPYmosIHsgW3BhcmFtTmFtZV06IGFyZ3NbcXVlcnlNZXRhZGF0YVtwYXJhbU5hbWVdXSB9KSwge31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgIE9iamVjdC5rZXlzKHF1ZXJ5UGFyYW1zQ29sbGVjdGlvbilcbiAgICAgIC5mb3JFYWNoKChwYXJhbU5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICBsZXQgdmFsdWUgPSBxdWVyeVBhcmFtc0NvbGxlY3Rpb25bcGFyYW1OYW1lXTtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkgeyB2YWx1ZSA9IFsgdmFsdWUgXTsgfVxuICAgICAgICB2YWx1ZS5mb3JFYWNoKChjdXJQYXJhbTogYW55KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHF1ZXJ5UGFyYW1zIFtwYXJhbU5hbWVdID0gY3VyUGFyYW07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgcmV0dXJuIHF1ZXJ5UGFyYW1zO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBwcml2YXRlIHN0YXRpYyBjb2xsZWN0SHR0cEhlYWRlcnModGFyZ2V0OiBhbnksIG1ldGhvZE5hbWU6IHN0cmluZywgX19hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNsYXNzSGVhZGVycyA9IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5jbGFzcyA/IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5jbGFzcy5oZWFkZXJzIDoge307XG4gICAgY29uc3QgbWV0aG9kSGVhZGVycyA9IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5tZXRob2RzICYmIHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5tZXRob2RzW21ldGhvZE5hbWVdXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHRhcmdldFtSRVNPVVJDRV9NRVRBREFUQV9ST09UXS5tZXRob2RzW21ldGhvZE5hbWVdLmhlYWRlcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIDoge307XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGNsYXNzSGVhZGVycywgbWV0aG9kSGVhZGVycyk7XG4gIH1cbn1cbiJdfQ==