Files
speckle-server/scratch/edge-debug-selection/Default/Cache/Cache_Data/f_000061
T

431 lines
68 KiB
Plaintext

import { isNullOrUndefined, isUndefinedOrVoid } from "/_nuxt/@fs/D:/speckle-server/packages/shared/dist/esm/index.js";
import { ApolloError, defaultDataIdFromObject } from "/_nuxt/node_modules/.cache/vite/client/deps/@apollo_client_core.js?v=e4f18c29";
import { GraphQLError } from "/_nuxt/node_modules/graphql/index.mjs?v=e4f18c29";
import {
flatten,
has,
isFunction,
isString,
isArray,
intersection,
get,
set,
cloneDeep,
isObjectLike
} from "/_nuxt/node_modules/.cache/vite/client/deps/lodash-es.js?v=e4f18c29";
import { nanoid } from "/_nuxt/node_modules/.cache/vite/client/deps/nanoid.js?v=e4f18c29";
import { StackTrace } from "/_nuxt/lib/common/helpers/debugging.ts";
import __vite__cjsImport6_dayjs from "/_nuxt/node_modules/.cache/vite/client/deps/dayjs.js?v=e4f18c29"; const dayjs = __vite__cjsImport6_dayjs.__esModule ? __vite__cjsImport6_dayjs.default : __vite__cjsImport6_dayjs;
import { base64Encode } from "/_nuxt/lib/common/helpers/encodeDecode.ts";
import { useSafeLogger } from "/_nuxt/composables/logging.ts";
export const isServerError = (err) => has(err, "response") && has(err, "result") && has(err, "statusCode");
export const isServerParseError = (err) => has(err, "response") && has(err, "bodyText") && has(err, "statusCode");
export const ROOT_QUERY = "ROOT_QUERY";
export const ROOT_MUTATION = "ROOT_MUTATION";
export const ROOT_SUBSCRIPTION = "ROOT_SUBSCRIPTION";
export function getCacheId(typeName, id) {
const cachedId = defaultDataIdFromObject({
__typename: typeName,
id
});
if (!cachedId) throw new Error("Unable to build Apollo cache ID");
return cachedId;
}
export const getCacheKey = getCacheId;
export function isInvalidAuth(error) {
const networkError = error instanceof ApolloError ? error.networkError : error;
if (!networkError || !isServerError(networkError) && !isServerParseError(networkError))
return false;
const statusCode = networkError.statusCode;
const hasCorrectCode = [403].includes(statusCode);
if (!hasCorrectCode) return false;
const message = isServerError(networkError) ? isString(networkError.result) ? networkError.result : networkError.result?.error : networkError.bodyText;
return (message || "").toLowerCase().includes("token");
}
export function convertThrowIntoFetchResult(err) {
let gqlErrors;
let apolloError = void 0;
if (err instanceof ApolloError) {
gqlErrors = err.graphQLErrors;
apolloError = err;
if (!gqlErrors.length) {
if (err.networkError && "result" in err.networkError && !isString(err.networkError.result) && isArray(err.networkError.result.errors)) {
const errors = err.networkError.result.errors;
gqlErrors = errors.map((e) => new GraphQLError(e.message));
}
}
} else if (err instanceof Error) {
gqlErrors = [new GraphQLError(err.message)];
} else {
gqlErrors = [new GraphQLError(`${err}`)];
}
const hasAuthIssue = apolloError && isInvalidAuth(apolloError);
return {
data: void 0,
errors: gqlErrors,
apolloError,
isInvalidAuth: !!hasAuthIssue
};
}
export function getFirstErrorMessage(errs, fallbackMessage = "An unexpected issue occurred") {
return errs?.[0]?.message || fallbackMessage;
}
export function updateCacheByFilter(cache, filter, updater, options = {}) {
const { fragment, query } = filter;
const { ignoreCacheErrors = true, overwrite = true } = options;
const { logger } = useSafeLogger();
if (!fragment && !query) {
throw new Error(
"Either fragment or query must be specified to be able to find cached data to update"
);
}
const readData = () => {
if (fragment) {
return cache.readFragment(fragment);
} else if (query) {
return cache.readQuery(query);
} else {
return null;
}
};
const writeData = (data) => {
if (fragment) {
cache.writeFragment({ ...fragment, data, overwrite });
return true;
} else if (query) {
cache.writeQuery({ ...query, data, overwrite });
return true;
} else {
return false;
}
};
try {
const currentData = readData();
if (!currentData) return false;
const newData = updater(currentData);
if (isUndefinedOrVoid(newData)) return false;
return writeData(newData);
} catch (e) {
if (e instanceof Error) {
if (e.message.toLowerCase().includes("no fragment named")) {
throw e;
}
}
if (ignoreCacheErrors) {
logger().warn("Failed Apollo cache update:", e);
return false;
}
throw e;
}
}
export function addFragmentDependencies(fragment, ...fragmentDependencies) {
return {
kind: "Document",
definitions: [
...fragment.definitions.filter((d) => d.kind === "FragmentDefinition"),
...flatten(
fragmentDependencies.map(
(f) => f.definitions.filter((d) => d.kind === "FragmentDefinition")
)
)
]
};
}
export function getStoreFieldName(fieldName, variables) {
return fieldName + (Object.values(variables || {}).length ? `:${JSON.stringify(variables)}` : "");
}
export function getObjectReference(typeName, id) {
return {
__ref: getCacheId(typeName, id)
};
}
export const keyToRef = (key) => {
return {
__ref: key
};
};
export function isReference(obj) {
return has(obj, "__ref");
}
export const revolveFieldNameAndVariables = (storeFieldName, fieldName) => {
let variables = void 0;
if (!fieldName) {
fieldName = /^[a-zA-Z0-9_-]+(?=[:(])/.exec(storeFieldName)?.[0];
}
if (!fieldName?.length) return { fieldName: storeFieldName, variables };
const variablesStringbase = storeFieldName.substring(fieldName.length);
if (variablesStringbase.startsWith(":")) {
variables = JSON.parse(variablesStringbase.substring(1));
} else if (variablesStringbase.startsWith("(")) {
variables = JSON.parse(
variablesStringbase.substring(1, variablesStringbase.length - 1)
);
}
return {
fieldName,
variables
};
};
export function modifyObjectFields(cache, id, updater, options) {
const { fieldNameWhitelist, debug = false } = options || {};
const { logger } = useSafeLogger();
const invocationId = nanoid();
const log = (...args) => {
if (!debug) return;
const [message, ...rest] = args;
logger().debug(`[${invocationId}] ${message}`, ...rest);
};
log(
"modifyObjectFields invoked",
{
id,
fieldNameWhitelist
},
new StackTrace()
);
cache.modify({
id,
fields(fieldValue, details) {
const { storeFieldName, fieldName } = details;
if (fieldNameWhitelist?.length && !fieldNameWhitelist.includes(fieldName)) {
return fieldValue;
}
const { variables } = revolveFieldNameAndVariables(
storeFieldName,
fieldName
);
log("invoking updater", { fieldName, variables, fieldValue });
try {
const res = updater(
fieldName,
variables || {},
fieldValue,
{
...details,
ref: getObjectReference,
revolveFieldNameAndVariables
}
);
if (isUndefinedOrVoid(res)) {
return fieldValue;
} else {
log("updater returned", { res });
return res;
}
} catch (e) {
log("updater threw an error", e);
throw e;
}
}
});
}
export function evictObjectFields(cache, id, predicate) {
modifyObjectFields(
cache,
id,
(fieldName, variables, value, details) => {
if (isFunction(predicate)) {
if (!predicate(fieldName, variables, value, {
...details,
revolveFieldNameAndVariables
}))
return void 0;
} else {
const predicateFields = predicate;
if (!predicateFields.includes(fieldName)) return void 0;
}
return details.DELETE;
},
{ debug: false }
);
}
export const resolveGenericStatusCode = (errors) => {
if (errors.some((e) => e.extensions?.code === "FORBIDDEN")) return 403;
if (errors.some(
(e) => ["UNAUTHENTICATED", "UNAUTHORIZED", "UNAUTHORIZED_ACCESS_ERROR"].includes(
e.extensions?.code || ""
)
))
return 401;
if (errors.some(
(e) => ["NOT_FOUND_ERROR", "STREAM_NOT_FOUND", "AUTOMATION_NOT_FOUND"].includes(
e.extensions?.code || ""
)
))
return 404;
return 500;
};
export const errorFailedAtPathSegment = (error, segment) => {
const path = error.path || [];
return path[path.length - 1] === segment;
};
export const getDateCursorFromReference = (params) => {
const dateStr = params.readField(params.dateProp, params.ref);
if (!dateStr || !isString(dateStr)) return null;
const date = dayjs(dateStr);
if (!date.isValid()) return null;
const iso = date.toISOString();
return base64Encode(iso);
};
export const skipLoggingErrorsIfOneFieldError = (fieldName) => (err) => {
const fieldNames = isArray(fieldName) ? fieldName : [fieldName];
return err.graphQLErrors?.length === 1 && err.graphQLErrors.some((e) => intersection(e.path || [], fieldNames).length > 0);
};
export const updatePathIfExists = (val, path, updater) => {
if (!val) return val;
if (has(val, path)) {
const pathVal = get(val, path);
const newVal = updater(pathVal);
set(val, path, newVal);
}
return val;
};
export const getFromPathIfExists = (val, path) => {
if (!val) return void 0;
if (!has(val, path)) return void 0;
return get(val, path);
};
export const getCachedObjectKeys = (cache, type) => {
const data = cache.extract();
const objectIds = Object.keys(data).filter((k) => k.startsWith(`${type}:`));
return objectIds;
};
export const modifyObjectField = (cache, key, fieldName, updater, options) => {
const { autoEvictFiltered } = options || {};
modifyObjectFields(
cache,
key,
(field, variables, value, details) => {
if (field !== fieldName) return;
if (autoEvictFiltered && isObjectLike(variables)) {
const checkFilter = (filter) => {
if (!has(variables, filter)) return false;
const val = get(variables, filter);
if (isNullOrUndefined(val)) return false;
if (isArray(val)) return true;
if (!isObjectLike(val)) return true;
return false;
};
const commonFilters = [
"query",
"filter",
"search",
"filter.search",
"input.search",
...isArray(autoEvictFiltered) ? autoEvictFiltered : []
];
const hasFilter = commonFilters.some(checkFilter);
if (hasFilter) {
return details.DELETE;
}
}
const createUpdatedValue = (updateHandler) => {
let clonedValue = cloneDeep(value);
updateHandler({
update: (path, pathUpdate) => {
clonedValue = updatePathIfExists(clonedValue, path, pathUpdate);
return clonedValue;
}
});
return clonedValue;
};
const getIfExists = (path) => getFromPathIfExists(value, path);
const evict = () => details.DELETE;
const readField = (ref, fieldName2) => details.readField(fieldName2, ref);
const readObject = () => new Proxy(
{},
{
get(_target, prop) {
if (!isString(prop)) return void 0;
const ref = keyToRef(key);
return details.readField(prop, ref);
}
}
);
return updater({
fieldName: field,
variables,
value,
helpers: {
createUpdatedValue,
get: getIfExists,
evict,
readField,
ref: getObjectReference,
fromRef: parseObjectReference,
keyToRef,
readObject
}
});
},
options
);
};
export const iterateObjectField = (cache, key, fieldName, predicate, options) => {
modifyObjectField(
cache,
key,
fieldName,
(params) => {
predicate(params);
},
{
...options || {},
autoEvictFiltered: false
// no mutations here
}
);
};
export const hasErrorWith = (params) => {
const { errors, message, codes } = params;
if (!errors?.length) return void 0;
if (!message?.length && !codes?.length) return void 0;
return errors.find((e) => {
const hasMessage = message && e.message.toLowerCase().includes(message);
const hasCodes = codes && codes.some((testCode) => {
const code = e.extensions?.code;
if (!code || !isString(code)) return false;
return isString(testCode) ? code === testCode : code.match(testCode);
});
return hasMessage || hasCodes;
});
};
export const errorsToAuthResult = (params) => {
const { errors } = params;
if (!errors?.length) return { authorized: true, message: "OK", code: "OK" };
const commonAuthError = hasErrorWith({
errors,
codes: [
/forbidden/i,
/unauthorized/i,
/not[_\s]found/i,
/not[_\s]authorized/i,
"SSO_SESSION_MISSING_OR_EXPIRED_ERROR"
]
});
if (commonAuthError) {
return {
authorized: false,
code: commonAuthError.extensions.code,
message: commonAuthError.message,
payload: commonAuthError.extensions || null
};
}
const firstError = errors[0];
return {
authorized: false,
code: firstError.extensions?.code && isString(firstError.extensions?.code) ? firstError.extensions?.code : "UNKNOWN_ERROR",
message: firstError.message,
payload: firstError.extensions || null
};
};
export const parseObjectKey = (key) => {
const [type, id] = key.split(":");
return { type, id };
};
export const parseObjectReference = (ref) => {
return parseObjectKey(ref.__ref);
};
//# sourceMappingURL=data:application/json;base64,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QUFNLEVBQUUsSUFBSSxJQUFJLE1BQU0sR0FBRztBQUNoQyxTQUFPLEVBQUUsTUFBb0IsR0FBRztBQUNsQztBQUVPLGFBQU0sdUJBQXVCLENBQ2xDLFFBQytCO0FBQy9CLFNBQU8sZUFBZSxJQUFJLEtBQW1DO0FBQy9EIiwibmFtZXMiOlsiZmllbGROYW1lIl0sImlnbm9yZUxpc3QiOltdLCJzb3VyY2VzIjpbImdyYXBocWwudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNOdWxsT3JVbmRlZmluZWQsIGlzVW5kZWZpbmVkT3JWb2lkIH0gZnJvbSAnQHNwZWNrbGUvc2hhcmVkJ1xyXG5pbXBvcnQgdHlwZSB7IE1heWJlTnVsbE9yVW5kZWZpbmVkLCBPcHRpb25hbCB9IGZyb20gJ0BzcGVja2xlL3NoYXJlZCdcclxuaW1wb3J0IHsgQXBvbGxvRXJyb3IsIGRlZmF1bHREYXRhSWRGcm9tT2JqZWN0IH0gZnJvbSAnQGFwb2xsby9jbGllbnQvY29yZSdcclxuaW1wb3J0IHR5cGUge1xyXG4gIEZldGNoUmVzdWx0LFxyXG4gIERhdGFQcm94eSxcclxuICBUeXBlZERvY3VtZW50Tm9kZSxcclxuICBTZXJ2ZXJFcnJvcixcclxuICBTZXJ2ZXJQYXJzZUVycm9yLFxyXG4gIEFwb2xsb0NhY2hlLFxyXG4gIFVubWFza2VkXHJcbn0gZnJvbSAnQGFwb2xsby9jbGllbnQvY29yZSdcclxuaW1wb3J0IHsgR3JhcGhRTEVycm9yIH0gZnJvbSAnZ3JhcGhxbCdcclxuaW1wb3J0IHR5cGUgeyBEb2N1bWVudE5vZGUsIEdyYXBoUUxGb3JtYXR0ZWRFcnJvciB9IGZyb20gJ2dyYXBocWwnXHJcbmltcG9ydCB7XHJcbiAgZmxhdHRlbixcclxuICBoYXMsXHJcbiAgaXNGdW5jdGlvbixcclxuICBpc1N0cmluZyxcclxuICBpc0FycmF5LFxyXG4gIGludGVyc2VjdGlvbixcclxuICBnZXQsXHJcbiAgc2V0LFxyXG4gIGNsb25lRGVlcCxcclxuICBpc09iamVjdExpa2VcclxufSBmcm9tICdsb2Rhc2gtZXMnXHJcbmltcG9ydCB0eXBlIHsgTW9kaWZpZXIsIE1vZGlmaWVyRGV0YWlscywgUmVmZXJlbmNlIH0gZnJvbSAnQGFwb2xsby9jbGllbnQvY2FjaGUnXHJcbmltcG9ydCB0eXBlIHsgR2V0LCBQYXJ0aWFsRGVlcCwgUGF0aHMsIFJlYWRvbmx5RGVlcCwgVGFnZ2VkIH0gZnJvbSAndHlwZS1mZXN0J1xyXG5pbXBvcnQgdHlwZSB7IE5ldHdvcmtFcnJvciB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2Vycm9ycydcclxuaW1wb3J0IHsgbmFub2lkIH0gZnJvbSAnbmFub2lkJ1xyXG5pbXBvcnQgeyBTdGFja1RyYWNlIH0gZnJvbSAnfn4vbGliL2NvbW1vbi9oZWxwZXJzL2RlYnVnZ2luZydcclxuaW1wb3J0IGRheWpzIGZyb20gJ2RheWpzJ1xyXG5pbXBvcnQgeyBiYXNlNjRFbmNvZGUgfSBmcm9tICd+L2xpYi9jb21tb24vaGVscGVycy9lbmNvZGVEZWNvZGUnXHJcbmltcG9ydCB0eXBlIHsgRXJyb3JSZXNwb25zZSB9IGZyb20gJ0BhcG9sbG8vY2xpZW50L2xpbmsvZXJyb3InXHJcbmltcG9ydCB0eXBlIHtcclxuICBBbGxPYmplY3RGaWVsZEFyZ1R5cGVzLFxyXG4gIEFsbE9iamVjdFR5cGVzLFxyXG4gIFBlcm1pc3Npb25DaGVja1Jlc3VsdFxyXG59IGZyb20gJ34vbGliL2NvbW1vbi9nZW5lcmF0ZWQvZ3FsL2dyYXBocWwnXHJcblxyXG4vKipcclxuICogQ2FjaGUga2V5IG9mIGEgc3BlY2lmaWMgY2FjaGVkIEdRTCBvYmplY3QuIFRlbmRzIHRvIGxvb2sgbGlrZSBgVHlwZTppZGAuXHJcbiAqL1xyXG5leHBvcnQgdHlwZSBBcG9sbG9DYWNoZU9iamVjdEtleTxUeXBlIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXM+ID0gVGFnZ2VkPFxyXG4gIHN0cmluZyxcclxuICBUeXBlXHJcbj5cclxuXHJcbmV4cG9ydCBjb25zdCBpc1NlcnZlckVycm9yID0gKGVycjogRXJyb3IpOiBlcnIgaXMgU2VydmVyRXJyb3IgPT5cclxuICBoYXMoZXJyLCAncmVzcG9uc2UnKSAmJiBoYXMoZXJyLCAncmVzdWx0JykgJiYgaGFzKGVyciwgJ3N0YXR1c0NvZGUnKVxyXG5leHBvcnQgY29uc3QgaXNTZXJ2ZXJQYXJzZUVycm9yID0gKGVycjogRXJyb3IpOiBlcnIgaXMgU2VydmVyUGFyc2VFcnJvciA9PlxyXG4gIGhhcyhlcnIsICdyZXNwb25zZScpICYmIGhhcyhlcnIsICdib2R5VGV4dCcpICYmIGhhcyhlcnIsICdzdGF0dXNDb2RlJylcclxuXHJcbmV4cG9ydCBjb25zdCBST09UX1FVRVJZID0gJ1JPT1RfUVVFUlknIGFzIEFwb2xsb0NhY2hlT2JqZWN0S2V5PCdRdWVyeSc+XHJcbmV4cG9ydCBjb25zdCBST09UX01VVEFUSU9OID0gJ1JPT1RfTVVUQVRJT04nIGFzIEFwb2xsb0NhY2hlT2JqZWN0S2V5PCdNdXRhdGlvbic+XHJcbmV4cG9ydCBjb25zdCBST09UX1NVQlNDUklQVElPTiA9XHJcbiAgJ1JPT1RfU1VCU0NSSVBUSU9OJyBhcyBBcG9sbG9DYWNoZU9iamVjdEtleTwnU3Vic2NyaXB0aW9uJz5cclxuXHJcbnR5cGUgTW9kaWZ5Rm5DYWNoZURhdGFTaW5nbGU8RGF0YT4gPSBEYXRhIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj5cclxuICA/IERhdGEgZXh0ZW5kcyB7IGlkOiBzdHJpbmc7IF9fdHlwZW5hbWU/OiBpbmZlciBUeXBlTmFtZSB9XHJcbiAgICA/IENhY2hlT2JqZWN0UmVmZXJlbmNlPFR5cGVOYW1lIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXMgPyBUeXBlTmFtZSA6IHN0cmluZz5cclxuICAgIDogUGFydGlhbERlZXA8e1xyXG4gICAgICAgIFtrZXkgaW4ga2V5b2YgRGF0YV06IE1vZGlmeUZuQ2FjaGVEYXRhPERhdGFba2V5XT5cclxuICAgICAgfT5cclxuICA6IERhdGFcclxuXHJcbi8qKlxyXG4gKiBVdGlsaXR5IHR5cGUgZm9yIHR5cGluZyBjYWNoZWQgZGF0YSBpbiBBcG9sbG8gbW9kaWZ5IGZ1bmN0aW9ucy5cclxuICogRXNzZW50aWFsbHkgaW5zaWRlIGEgbW9kaWZ5IGZ1bmN0aW9uIGFsbCByZWZlcmVuY2VzIHRvIGNhY2hlZCBvYmplY3RzIHRoYXQgY2FuIGJlIHVuaXF1ZWx5IGlkZW50aWZpZWQgKGhhdmUgYW4gSUQgZmllbGQpIGFyZSBjb252ZXJ0ZWRcclxuICogdG8gQ2FjaGVPYmplY3RSZWZlcmVuY2Ugb2JqZWN0cyBhbmQgYWRkaXRpb25hbGx5IGFsbCBwcm9wZXJ0aWVzIGFyZSBvcHRpb25hbCBhcyB5b3UgY2FuIG5ldmVyIGtub3cgd2hhdCBleGFjdGx5IGhhcyBiZWVuIHJlcXVlc3RlZCAmIGNhY2hlZFxyXG4gKiBhbmQgd2hhdCBoYXNuJ3RcclxuICovXHJcbmV4cG9ydCB0eXBlIE1vZGlmeUZuQ2FjaGVEYXRhPERhdGE+ID0gRGF0YSBleHRlbmRzIEFycmF5PGluZmVyIEFycmF5SXRlbT5cclxuICA/IE1vZGlmeUZuQ2FjaGVEYXRhU2luZ2xlPEFycmF5SXRlbT5bXVxyXG4gIDogTW9kaWZ5Rm5DYWNoZURhdGFTaW5nbGU8RGF0YT5cclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBjYWNoZWQgb2JqZWN0J3MgaWRlbnRpZmllclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldENhY2hlSWQ8VHlwZSBleHRlbmRzIGtleW9mIEFsbE9iamVjdFR5cGVzPihcclxuICB0eXBlTmFtZTogVHlwZSxcclxuICBpZDogc3RyaW5nXHJcbik6IEFwb2xsb0NhY2hlT2JqZWN0S2V5PFR5cGU+IHtcclxuICBjb25zdCBjYWNoZWRJZCA9IGRlZmF1bHREYXRhSWRGcm9tT2JqZWN0KHtcclxuICAgIF9fdHlwZW5hbWU6IHR5cGVOYW1lLFxyXG4gICAgaWRcclxuICB9KVxyXG4gIGlmICghY2FjaGVkSWQpIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGJ1aWxkIEFwb2xsbyBjYWNoZSBJRCcpXHJcblxyXG4gIHJldHVybiBjYWNoZWRJZCBhcyBBcG9sbG9DYWNoZU9iamVjdEtleTxUeXBlPlxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0Q2FjaGVLZXkgPSBnZXRDYWNoZUlkXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNJbnZhbGlkQXV0aChlcnJvcjogQXBvbGxvRXJyb3IgfCBOZXR3b3JrRXJyb3IpIHtcclxuICBjb25zdCBuZXR3b3JrRXJyb3IgPSBlcnJvciBpbnN0YW5jZW9mIEFwb2xsb0Vycm9yID8gZXJyb3IubmV0d29ya0Vycm9yIDogZXJyb3JcclxuICBpZiAoXHJcbiAgICAhbmV0d29ya0Vycm9yIHx8XHJcbiAgICAoIWlzU2VydmVyRXJyb3IobmV0d29ya0Vycm9yKSAmJiAhaXNTZXJ2ZXJQYXJzZUVycm9yKG5ldHdvcmtFcnJvcikpXHJcbiAgKVxyXG4gICAgcmV0dXJuIGZhbHNlXHJcblxyXG4gIGNvbnN0IHN0YXR1c0NvZGUgPSBuZXR3b3JrRXJyb3Iuc3RhdHVzQ29kZVxyXG4gIGNvbnN0IGhhc0NvcnJlY3RDb2RlID0gWzQwM10uaW5jbHVkZXMoc3RhdHVzQ29kZSlcclxuICBpZiAoIWhhc0NvcnJlY3RDb2RlKSByZXR1cm4gZmFsc2VcclxuXHJcbiAgY29uc3QgbWVzc2FnZTogc3RyaW5nIHwgdW5kZWZpbmVkID0gaXNTZXJ2ZXJFcnJvcihuZXR3b3JrRXJyb3IpXHJcbiAgICA/IGlzU3RyaW5nKG5ldHdvcmtFcnJvci5yZXN1bHQpXHJcbiAgICAgID8gbmV0d29ya0Vycm9yLnJlc3VsdFxyXG4gICAgICA6IG5ldHdvcmtFcnJvci5yZXN1bHQ/LmVycm9yXHJcbiAgICA6IG5ldHdvcmtFcnJvci5ib2R5VGV4dFxyXG5cclxuICByZXR1cm4gKG1lc3NhZ2UgfHwgJycpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ3Rva2VuJylcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbnZlcnQgYW4gZXJyb3IgdGhyb3duIGR1cmluZyAkYXBvbGxvLm11dGF0ZSgpIGludG8gYSBmZXRjaCByZXN1bHRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0VGhyb3dJbnRvRmV0Y2hSZXN1bHQoXHJcbiAgZXJyOiB1bmtub3duXHJcbik6IEZldGNoUmVzdWx0PHVuZGVmaW5lZD4gJiB7IGFwb2xsb0Vycm9yPzogQXBvbGxvRXJyb3I7IGlzSW52YWxpZEF1dGg6IGJvb2xlYW4gfSB7XHJcbiAgbGV0IGdxbEVycm9yczogcmVhZG9ubHkgR3JhcGhRTEZvcm1hdHRlZEVycm9yW11cclxuICBsZXQgYXBvbGxvRXJyb3I6IE9wdGlvbmFsPEFwb2xsb0Vycm9yPiA9IHVuZGVmaW5lZFxyXG4gIGlmIChlcnIgaW5zdGFuY2VvZiBBcG9sbG9FcnJvcikge1xyXG4gICAgZ3FsRXJyb3JzID0gZXJyLmdyYXBoUUxFcnJvcnNcclxuICAgIGFwb2xsb0Vycm9yID0gZXJyXHJcblxyXG4gICAgaWYgKCFncWxFcnJvcnMubGVuZ3RoKSB7XHJcbiAgICAgIGlmIChcclxuICAgICAgICBlcnIubmV0d29ya0Vycm9yICYmXHJcbiAgICAgICAgJ3Jlc3VsdCcgaW4gZXJyLm5ldHdvcmtFcnJvciAmJlxyXG4gICAgICAgICFpc1N0cmluZyhlcnIubmV0d29ya0Vycm9yLnJlc3VsdCkgJiZcclxuICAgICAgICBpc0FycmF5KGVyci5uZXR3b3JrRXJyb3IucmVzdWx0LmVycm9ycylcclxuICAgICAgKSB7XHJcbiAgICAgICAgY29uc3QgZXJyb3JzID0gZXJyLm5ldHdvcmtFcnJvci5yZXN1bHQuZXJyb3JzIGFzIEFycmF5PHsgbWVzc2FnZTogc3RyaW5nIH0+XHJcbiAgICAgICAgZ3FsRXJyb3JzID0gZXJyb3JzLm1hcCgoZSkgPT4gbmV3IEdyYXBoUUxFcnJvcihlLm1lc3NhZ2UpKVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSBlbHNlIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xyXG4gICAgZ3FsRXJyb3JzID0gW25ldyBHcmFwaFFMRXJyb3IoZXJyLm1lc3NhZ2UpXVxyXG4gIH0gZWxzZSB7XHJcbiAgICBncWxFcnJvcnMgPSBbbmV3IEdyYXBoUUxFcnJvcihgJHtlcnJ9YCldXHJcbiAgfVxyXG5cclxuICBjb25zdCBoYXNBdXRoSXNzdWUgPSBhcG9sbG9FcnJvciAmJiBpc0ludmFsaWRBdXRoKGFwb2xsb0Vycm9yKVxyXG5cclxuICByZXR1cm4ge1xyXG4gICAgZGF0YTogdW5kZWZpbmVkLFxyXG4gICAgZXJyb3JzOiBncWxFcnJvcnMsXHJcbiAgICBhcG9sbG9FcnJvcixcclxuICAgIGlzSW52YWxpZEF1dGg6ICEhaGFzQXV0aElzc3VlXHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogR2V0IGZpcnN0IGVycm9yIG1lc3NhZ2UgZnJvbSBhIEdRTCBlcnJvcnMgYXJyYXlcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGaXJzdEVycm9yTWVzc2FnZShcclxuICBlcnJzOiByZWFkb25seSBHcmFwaFFMRXJyb3JbXSB8IHJlYWRvbmx5IEdyYXBoUUxGb3JtYXR0ZWRFcnJvcltdIHwgdW5kZWZpbmVkIHwgbnVsbCxcclxuICBmYWxsYmFja01lc3NhZ2UgPSAnQW4gdW5leHBlY3RlZCBpc3N1ZSBvY2N1cnJlZCdcclxuKTogc3RyaW5nIHtcclxuICByZXR1cm4gZXJycz8uWzBdPy5tZXNzYWdlIHx8IGZhbGxiYWNrTWVzc2FnZVxyXG59XHJcblxyXG4vKipcclxuICogRmluZCBzb21lIGNhY2hlZCBBcG9sbG8gZGF0YSB0aHJvdWdoIGEgZnJhZ21lbnQvcXVlcnkgYW5kIHVzZSB0aGUgdXBkYXRlciBmdW5jdGlvblxyXG4gKiB0byByZXR1cm4gdGhlIHJlcGxhY2VtZW50IGZvciB0aGUgZGF0YSB0aGF0IHRoZSBmcmFnbWVudCBpbml0aWFsbHkgZm91bmRcclxuICogQHJldHVybnMgV2hldGhlciBhbiB1cGRhdGUgd2FzIG1hZGVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVDYWNoZUJ5RmlsdGVyPFREYXRhLCBUVmFyaWFibGVzID0gdW5rbm93bj4oXHJcbiAgY2FjaGU6IEFwb2xsb0NhY2hlPHVua25vd24+LFxyXG4gIGZpbHRlcjoge1xyXG4gICAgZnJhZ21lbnQ/OiBEYXRhUHJveHkuRnJhZ21lbnQ8VFZhcmlhYmxlcywgVERhdGE+XHJcbiAgICBxdWVyeT86IERhdGFQcm94eS5RdWVyeTxUVmFyaWFibGVzLCBURGF0YT5cclxuICB9LFxyXG4gIC8qKlxyXG4gICAqIElmIHJldHVybnMgdW5kZWZpbmVkL3ZvaWQsIHRoZW4gdXBkYXRpbmcgaXMgZXNzZW50aWFsbHkgY2FuY2VsZWQuIEJlIGNhcmVmdWwgbm90IHRvXHJcbiAgICogbXV0YXRlIGFueXRoaW5nIGJlaW5nIHBhc3NlZCBpbnRvIHRoaXMgZnVuY3Rpb24hIEUuZy4gaWYgeW91IHdhbnQgdG8gbXV0YXRlIGFycmF5cyxcclxuICAgKiBjcmVhdGUgbmV3IGFycmF5cyB0aHJvdWdoIHNsaWNlKCkvZmlsdGVyKCkgaW5zdGVhZFxyXG4gICAqL1xyXG4gIHVwZGF0ZXI6IChkYXRhOiBVbm1hc2tlZDxURGF0YT4pID0+IFVubWFza2VkPFREYXRhPiB8IHVuZGVmaW5lZCxcclxuICBvcHRpb25zOiBQYXJ0aWFsPHtcclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB0byBzdXBwcmVzcyBlcnJvcnMgdGhhdCBvY2N1ciB3aGVuIHRoZSBmcmFnbWVudCBiZWluZyBxdWVyaWVkXHJcbiAgICAgKiBkb2Vzbid0IGZpbmQgYW55dGhpbmdcclxuICAgICAqIERlZmF1bHQ6IHRydWVcclxuICAgICAqL1xyXG4gICAgaWdub3JlQ2FjaGVFcnJvcnM6IGJvb2xlYW5cclxuXHJcbiAgICAvKipcclxuICAgICAqIFdoZXRoZXIgdG8gb3ZlcndyaXRlIHRoZSBvbGQgY2FjaGUgcmVzdWx0cywgaW5zdGVhZCBvZiB0cmlnZ2VyaW5nIGEgbWVyZ2UgZnVuY3Rpb25cclxuICAgICAqIHRvIG1lcmdlIHRoZSBvbGQgYW5kIG5ldyByZXN1bHRzLlxyXG4gICAgICogRGVmYXVsdDogdHJ1ZVxyXG4gICAgICovXHJcbiAgICBvdmVyd3JpdGU6IGJvb2xlYW5cclxuICB9PiA9IHt9XHJcbik6IGJvb2xlYW4ge1xyXG4gIGNvbnN0IHsgZnJhZ21lbnQsIHF1ZXJ5IH0gPSBmaWx0ZXJcclxuICBjb25zdCB7IGlnbm9yZUNhY2hlRXJyb3JzID0gdHJ1ZSwgb3ZlcndyaXRlID0gdHJ1ZSB9ID0gb3B0aW9uc1xyXG4gIGNvbnN0IHsgbG9nZ2VyIH0gPSB1c2VTYWZlTG9nZ2VyKClcclxuXHJcbiAgaWYgKCFmcmFnbWVudCAmJiAhcXVlcnkpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgJ0VpdGhlciBmcmFnbWVudCBvciBxdWVyeSBtdXN0IGJlIHNwZWNpZmllZCB0byBiZSBhYmxlIHRvIGZpbmQgY2FjaGVkIGRhdGEgdG8gdXBkYXRlJ1xyXG4gICAgKVxyXG4gIH1cclxuXHJcbiAgY29uc3QgcmVhZERhdGEgPSAoKTogVW5tYXNrZWQ8VERhdGE+IHwgbnVsbCA9PiB7XHJcbiAgICBpZiAoZnJhZ21lbnQpIHtcclxuICAgICAgcmV0dXJuIGNhY2hlLnJlYWRGcmFnbWVudChmcmFnbWVudClcclxuICAgIH0gZWxzZSBpZiAocXVlcnkpIHtcclxuICAgICAgcmV0dXJuIGNhY2hlLnJlYWRRdWVyeShxdWVyeSlcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBudWxsXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb25zdCB3cml0ZURhdGEgPSAoZGF0YTogVW5tYXNrZWQ8VERhdGE+KTogYm9vbGVhbiA9PiB7XHJcbiAgICBpZiAoZnJhZ21lbnQpIHtcclxuICAgICAgY2FjaGUud3JpdGVGcmFnbWVudCh7IC4uLmZyYWdtZW50LCBkYXRhLCBvdmVyd3JpdGUgfSlcclxuICAgICAgcmV0dXJuIHRydWVcclxuICAgIH0gZWxzZSBpZiAocXVlcnkpIHtcclxuICAgICAgY2FjaGUud3JpdGVRdWVyeSh7IC4uLnF1ZXJ5LCBkYXRhLCBvdmVyd3JpdGUgfSlcclxuICAgICAgcmV0dXJuIHRydWVcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdHJ5IHtcclxuICAgIGNvbnN0IGN1cnJlbnREYXRhID0gcmVhZERhdGEoKVxyXG4gICAgaWYgKCFjdXJyZW50RGF0YSkgcmV0dXJuIGZhbHNlXHJcblxyXG4gICAgY29uc3QgbmV3RGF0YSA9IHVwZGF0ZXIoY3VycmVudERhdGEpXHJcbiAgICBpZiAoaXNVbmRlZmluZWRPclZvaWQobmV3RGF0YSkpIHJldHVybiBmYWxzZVxyXG5cclxuICAgIHJldHVybiB3cml0ZURhdGEobmV3RGF0YSlcclxuICB9IGNhdGNoIChlOiB1bmtub3duKSB7XHJcbiAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7XHJcbiAgICAgIC8vIEludmFsaWQgZnJhZ21lbnQgLSB0aHJvdyBhbHdheXNcclxuICAgICAgaWYgKGUubWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdubyBmcmFnbWVudCBuYW1lZCcpKSB7XHJcbiAgICAgICAgdGhyb3cgZVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlnbm9yZUNhY2hlRXJyb3JzKSB7XHJcbiAgICAgIGxvZ2dlcigpLndhcm4oJ0ZhaWxlZCBBcG9sbG8gY2FjaGUgdXBkYXRlOicsIGUpXHJcbiAgICAgIHJldHVybiBmYWxzZVxyXG4gICAgfVxyXG4gICAgdGhyb3cgZVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEEgZ3JhcGhxbC1jb2RlZ2VuIGdlbmVyYXRlZCBmcmFnbWVudCBkb2Vzbid0IGluY2x1ZGUgdGhlIGRlZmluaXRpb24gb2Ygb3RoZXIgZnJhZ21lbnRzIGluIGl0LFxyXG4gKiBzbyBpZiB5b3UgZXZlciBuZWVkIGEgZG9jdW1lbnQgdGhhdCBjb250YWlucyBhIGZyYWdtZW50IGFzIHdlbGwgYXMgb3RoZXIgZnJhZ21lbnRzIHRoYXQgaXQgdXNlc1xyXG4gKiB5b3UgY2FuIHVzZSB0aGlzIGhlbHBlclxyXG4gKlxyXG4gKiBUT0RPOiBGaWd1cmUgb3V0IGlmIHdlIGNhbiB0dXJuIG9mZiBkZWR1cGVGcmFnbWVudHMgdG8gZ2V0IGZyYWdtZW50cyB0byBjb250YWluIGFsbCBkZXBlbmRlbmN5XHJcbiAqIGZyYWdtZW50cyBhcyB3ZWxsLiBQcmV2aW91c2x5IHRoaXMgY2F1c2VkIGFuIGVycm9yIHdoZW4gZHVwbGljYXRlIGZyYWdtZW50cyB3ZXJlIHNlbnQgdG8gdGhlIEFQSVxyXG4gKiB0aHJvdWdoIGEgcXVlcnkvbXV0YXRpb24uXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gYWRkRnJhZ21lbnREZXBlbmRlbmNpZXM8UiA9IHVua25vd24sIFYgPSB1bmtub3duPihcclxuICBmcmFnbWVudDogVHlwZWREb2N1bWVudE5vZGU8UiwgVj4sXHJcbiAgLi4uZnJhZ21lbnREZXBlbmRlbmNpZXM6IERvY3VtZW50Tm9kZVtdXHJcbikge1xyXG4gIHJldHVybiB7XHJcbiAgICBraW5kOiAnRG9jdW1lbnQnLFxyXG4gICAgZGVmaW5pdGlvbnM6IFtcclxuICAgICAgLi4uZnJhZ21lbnQuZGVmaW5pdGlvbnMuZmlsdGVyKChkKSA9PiBkLmtpbmQgPT09ICdGcmFnbWVudERlZmluaXRpb24nKSxcclxuICAgICAgLi4uZmxhdHRlbihcclxuICAgICAgICBmcmFnbWVudERlcGVuZGVuY2llcy5tYXAoKGYpID0+XHJcbiAgICAgICAgICBmLmRlZmluaXRpb25zLmZpbHRlcigoZCkgPT4gZC5raW5kID09PSAnRnJhZ21lbnREZWZpbml0aW9uJylcclxuICAgICAgICApXHJcbiAgICAgIClcclxuICAgIF1cclxuICB9IGFzIFR5cGVkRG9jdW1lbnROb2RlPFIsIFY+XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXNvbHZlIHRoZSBzdHJpbmcga2V5IG9mIGEgZmllbGQgaW4gdGhlIGFwb2xsbyBjYWNoZS4gSXMgdXNlZnVsIGluIGNhY2hlLm1vZGlmeSgpIGNhbGxzLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFN0b3JlRmllbGROYW1lKFxyXG4gIGZpZWxkTmFtZTogc3RyaW5nLFxyXG4gIHZhcmlhYmxlcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+XHJcbikge1xyXG4gIHJldHVybiAoXHJcbiAgICBmaWVsZE5hbWUgK1xyXG4gICAgKE9iamVjdC52YWx1ZXModmFyaWFibGVzIHx8IHt9KS5sZW5ndGggPyBgOiR7SlNPTi5zdHJpbmdpZnkodmFyaWFibGVzKX1gIDogJycpXHJcbiAgKVxyXG59XHJcblxyXG4vKipcclxuICogSW5zaWRlIGNhY2hlLm1vZGlmeSBjYWxscyB5b3UnbGwgZ2V0IHRoZXNlIGluc3RlYWQgb2YgZnVsbCBvYmplY3RzIHdoZW4gcmVhZGluZyBmaWVsZHMgdGhhdCBob2xkXHJcbiAqIGlkZW50aWZpYWJsZSBvYmplY3RzIG9yIG9iamVjdCBhcnJheXNcclxuICovXHJcbmV4cG9ydCB0eXBlIENhY2hlT2JqZWN0UmVmZXJlbmNlPFR5cGUgZXh0ZW5kcyBzdHJpbmcgPSBzdHJpbmc+ID0ge1xyXG4gIHJlYWRvbmx5IF9fcmVmOiBUeXBlIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXNcclxuICAgID8gQXBvbGxvQ2FjaGVPYmplY3RLZXk8VHlwZT5cclxuICAgIDogc3RyaW5nXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBPYmplY3RzICYgb2JqZWN0IGFycmF5cyBpbiBgY2FjaGUubW9kaWZ5YCBjYWxscyBhcmUgcmVwcmVzZW50ZWQgdGhyb3VnaCByZWZlcmVuY2Ugb2JqZWN0cywgc29cclxuICogaWYgeW91IHdhbnQgdG8gYWRkIG5ldyBvbmVzIHlvdSBzaG91bGRuJ3QgYWRkIHRoZSBlbnRpcmUgb2JqZWN0LCBidXQgb25seSBpdHMgcmVmZXJlbmNlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0T2JqZWN0UmVmZXJlbmNlPFR5cGUgZXh0ZW5kcyBrZXlvZiBBbGxPYmplY3RUeXBlcz4oXHJcbiAgdHlwZU5hbWU6IFR5cGUsXHJcbiAgaWQ6IHN0cmluZ1xyXG4pOiBDYWNoZU9iamVjdFJlZmVyZW5jZTxUeXBlPiB7XHJcbiAgcmV0dXJuIHtcclxuICAgIF9fcmVmOiBnZXRDYWNoZUlkKHR5cGVOYW1lLCBpZClcclxuICB9IGFzIENhY2hlT2JqZWN0UmVmZXJlbmNlPFR5cGU+XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBrZXlUb1JlZiA9IDxUeXBlIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXM+KFxyXG4gIGtleTogQXBvbGxvQ2FjaGVPYmplY3RLZXk8VHlwZT5cclxuKTogQ2FjaGVPYmplY3RSZWZlcmVuY2U8VHlwZT4gPT4ge1xyXG4gIHJldHVybiB7XHJcbiAgICBfX3JlZjoga2V5XHJcbiAgfSBhcyBDYWNoZU9iamVjdFJlZmVyZW5jZTxUeXBlPlxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNSZWZlcmVuY2Uob2JqOiB1bmtub3duKTogb2JqIGlzIENhY2hlT2JqZWN0UmVmZXJlbmNlIHtcclxuICByZXR1cm4gaGFzKG9iaiwgJ19fcmVmJylcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlc29sdmUgdGhlIGZpZWxkIG5hbWUgYW5kIHZhcmlhYmxlcyBmcm9tIGFuIEFwb2xsbyBzdG9yZSBmaWVsZCBuYW1lIHdoaWNoXHJcbiAqIGlzIHVzdWFsbHkgYSBzdHJpbmcgbGlrZSBcImZpZWxkTmFtZTp7XCJ2YXIxXCI6XCJ2YWwxXCIsXCJ2YXIyXCI6XCJ2YWwyXCJ9XCJcclxuICogQHBhcmFtIHN0b3JlRmllbGROYW1lXHJcbiAqIEBwYXJhbSBmaWVsZE5hbWVcclxuICovXHJcbmV4cG9ydCBjb25zdCByZXZvbHZlRmllbGROYW1lQW5kVmFyaWFibGVzID0gPFxyXG4gIFYgZXh0ZW5kcyBPcHRpb25hbDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4gPSB1bmRlZmluZWRcclxuPihcclxuICBzdG9yZUZpZWxkTmFtZTogc3RyaW5nLFxyXG4gIGZpZWxkTmFtZT86IHN0cmluZ1xyXG4pID0+IHtcclxuICBsZXQgdmFyaWFibGVzOiBPcHRpb25hbDxWPiA9IHVuZGVmaW5lZFxyXG5cclxuICBpZiAoIWZpZWxkTmFtZSkge1xyXG4gICAgZmllbGROYW1lID0gL15bYS16QS1aMC05Xy1dKyg/PVs6KF0pLy5leGVjKHN0b3JlRmllbGROYW1lKT8uWzBdXHJcbiAgfVxyXG4gIGlmICghZmllbGROYW1lPy5sZW5ndGgpIHJldHVybiB7IGZpZWxkTmFtZTogc3RvcmVGaWVsZE5hbWUsIHZhcmlhYmxlcyB9XHJcblxyXG4gIGNvbnN0IHZhcmlhYmxlc1N0cmluZ2Jhc2UgPSBzdG9yZUZpZWxkTmFtZS5zdWJzdHJpbmcoZmllbGROYW1lLmxlbmd0aClcclxuICBpZiAodmFyaWFibGVzU3RyaW5nYmFzZS5zdGFydHNXaXRoKCc6JykpIHtcclxuICAgIHZhcmlhYmxlcyA9IEpTT04ucGFyc2UodmFyaWFibGVzU3RyaW5nYmFzZS5zdWJzdHJpbmcoMSkpIGFzIFZcclxuICB9IGVsc2UgaWYgKHZhcmlhYmxlc1N0cmluZ2Jhc2Uuc3RhcnRzV2l0aCgnKCcpKSB7XHJcbiAgICB2YXJpYWJsZXMgPSBKU09OLnBhcnNlKFxyXG4gICAgICB2YXJpYWJsZXNTdHJpbmdiYXNlLnN1YnN0cmluZygxLCB2YXJpYWJsZXNTdHJpbmdiYXNlLmxlbmd0aCAtIDEpXHJcbiAgICApIGFzIFZcclxuICB9XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBmaWVsZE5hbWUsXHJcbiAgICB2YXJpYWJsZXNcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJdGVyYXRlIG92ZXIgYSBjYWNoZWQgb2JqZWN0J3MgZmllbGRzIGFuZCBvcHRpb25hbGx5IHVwZGF0ZSB0aGVtLiBTaW1pbGFyIHRvIGNhY2hlLm1vZGlmeSwgZXhjZXB0IGFsbG93c1xyXG4gKiBiZXR0ZXIgZmlsdGVyaW5nIGNhcGFiaWxpdGllcyB0byBmaWx0ZXIgZmlsdGVycyB0byB1cGRhdGUgKGUuZy4geW91IGNhbiBhY3R1YWxseSBnZXQgZWFjaCBmaWVsZCdzIHZhcmlhYmxlcylcclxuICogTm90ZTogVGhpcyB1c2VzIGNhY2hlLm1vZGlmeSB1bmRlcm5lYXRoIHdoaWNoIG1lYW5zIHRoYXQgYGRhdGFgIHdpbGwgb25seSBob2xkIG9iamVjdCByZWZlcmVuY2VzIChDYWNoZU9iamVjdFJlZmVyZW5jZSkgbm90XHJcbiAqIGZ1bGwgb2JqZWN0cy4gUmVhZCBtb3JlOiBodHRwczovL3d3dy5hcG9sbG9ncmFwaHFsLmNvbS9kb2NzL3JlYWN0L2NhY2hpbmcvY2FjaGUtaW50ZXJhY3Rpb24vI3ZhbHVlcy12cy1yZWZlcmVuY2VzXHJcbiAqIEBkZXByZWNhdGVkIFVzZSBtb2RpZnlPYmplY3RGaWVsZCBpbnN0ZWFkXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gbW9kaWZ5T2JqZWN0RmllbGRzPFxyXG4gIFZhcmlhYmxlcyBleHRlbmRzIE9wdGlvbmFsPFJlY29yZDxzdHJpbmcsIHVua25vd24+PiA9IHVuZGVmaW5lZCxcclxuICBGaWVsZERhdGEgPSB1bmtub3duXHJcbj4oXHJcbiAgY2FjaGU6IEFwb2xsb0NhY2hlPHVua25vd24+LFxyXG4gIGlkOiBzdHJpbmcsXHJcbiAgdXBkYXRlcjogKFxyXG4gICAgZmllbGROYW1lOiBzdHJpbmcsXHJcbiAgICB2YXJpYWJsZXM6IFZhcmlhYmxlcyxcclxuICAgIHZhbHVlOiBNb2RpZnlGbkNhY2hlRGF0YTxGaWVsZERhdGE+LFxyXG4gICAgZGV0YWlsczogUGFyYW1ldGVyczxNb2RpZmllcjxNb2RpZnlGbkNhY2hlRGF0YTxGaWVsZERhdGE+Pj5bMV0gJiB7XHJcbiAgICAgIHJlZjogdHlwZW9mIGdldE9iamVjdFJlZmVyZW5jZVxyXG4gICAgICByZXZvbHZlRmllbGROYW1lQW5kVmFyaWFibGVzOiB0eXBlb2YgcmV2b2x2ZUZpZWxkTmFtZUFuZFZhcmlhYmxlc1xyXG4gICAgfVxyXG4gICkgPT5cclxuICAgIHwgT3B0aW9uYWw8TW9kaWZ5Rm5DYWNoZURhdGE8RmllbGREYXRhPj5cclxuICAgIHwgUGFyYW1ldGVyczxNb2RpZmllcjxNb2RpZnlGbkNhY2hlRGF0YTxGaWVsZERhdGE+Pj5bMV1bJ0RFTEVURSddXHJcbiAgICB8IFBhcmFtZXRlcnM8TW9kaWZpZXI8TW9kaWZ5Rm5DYWNoZURhdGE8RmllbGREYXRhPj4+WzFdWydJTlZBTElEQVRFJ11cclxuICAgIHwgdm9pZCxcclxuICBvcHRpb25zPzogUGFydGlhbDx7XHJcbiAgICBmaWVsZE5hbWVXaGl0ZWxpc3Q6IHN0cmluZ1tdXHJcbiAgICBkZWJ1ZzogYm9vbGVhblxyXG4gIH0+XHJcbikge1xyXG4gIGNvbnN0IHsgZmllbGROYW1lV2hpdGVsaXN0LCBkZWJ1ZyA9IGZhbHNlIH0gPSBvcHRpb25zIHx8IHt9XHJcblxyXG4gIGNvbnN0IHsgbG9nZ2VyIH0gPSB1c2VTYWZlTG9nZ2VyKClcclxuICBjb25zdCBpbnZvY2F0aW9uSWQgPSBuYW5vaWQoKVxyXG4gIGNvbnN0IGxvZyA9ICguLi5hcmdzOiB1bmtub3duW10pID0+IHtcclxuICAgIGlmICghZGVidWcpIHJldHVyblxyXG4gICAgY29uc3QgW21lc3NhZ2UsIC4uLnJlc3RdID0gYXJnc1xyXG5cclxuICAgIGxvZ2dlcigpLmRlYnVnKGBbJHtpbnZvY2F0aW9uSWR9XSAke21lc3NhZ2V9YCwgLi4ucmVzdClcclxuICB9XHJcblxyXG4gIGxvZyhcclxuICAgICdtb2RpZnlPYmplY3RGaWVsZHMgaW52b2tlZCcsXHJcbiAgICB7XHJcbiAgICAgIGlkLFxyXG4gICAgICBmaWVsZE5hbWVXaGl0ZWxpc3RcclxuICAgIH0sXHJcbiAgICBuZXcgU3RhY2tUcmFjZSgpXHJcbiAgKVxyXG4gIGNhY2hlLm1vZGlmeSh7XHJcbiAgICBpZCxcclxuICAgIGZpZWxkcyhmaWVsZFZhbHVlLCBkZXRhaWxzKSB7XHJcbiAgICAgIGNvbnN0IHsgc3RvcmVGaWVsZE5hbWUsIGZpZWxkTmFtZSB9ID0gZGV0YWlsc1xyXG5cclxuICAgICAgaWYgKGZpZWxkTmFtZVdoaXRlbGlzdD8ubGVuZ3RoICYmICFmaWVsZE5hbWVXaGl0ZWxpc3QuaW5jbHVkZXMoZmllbGROYW1lKSkge1xyXG4gICAgICAgIHJldHVybiBmaWVsZFZhbHVlIGFzIHVua25vd25cclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3QgeyB2YXJpYWJsZXMgfSA9IHJldm9sdmVGaWVsZE5hbWVBbmRWYXJpYWJsZXM8VmFyaWFibGVzPihcclxuICAgICAgICBzdG9yZUZpZWxkTmFtZSxcclxuICAgICAgICBmaWVsZE5hbWVcclxuICAgICAgKVxyXG5cclxuICAgICAgbG9nKCdpbnZva2luZyB1cGRhdGVyJywgeyBmaWVsZE5hbWUsIHZhcmlhYmxlcywgZmllbGRWYWx1ZSB9KVxyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IHJlcyA9IHVwZGF0ZXIoXHJcbiAgICAgICAgICBmaWVsZE5hbWUsXHJcbiAgICAgICAgICAodmFyaWFibGVzIHx8IHt9KSBhcyBWYXJpYWJsZXMsXHJcbiAgICAgICAgICBmaWVsZFZhbHVlIGFzIE1vZGlmeUZuQ2FjaGVEYXRhPEZpZWxkRGF0YT4sXHJcbiAgICAgICAgICB7XHJcbiAgICAgICAgICAgIC4uLmRldGFpbHMsXHJcbiAgICAgICAgICAgIHJlZjogZ2V0T2JqZWN0UmVmZXJlbmNlLFxyXG4gICAgICAgICAgICByZXZvbHZlRmllbGROYW1lQW5kVmFyaWFibGVzXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgKVxyXG5cclxuICAgICAgICBpZiAoaXNVbmRlZmluZWRPclZvaWQocmVzKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGZpZWxkVmFsdWUgYXMgdW5rbm93blxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBsb2coJ3VwZGF0ZXIgcmV0dXJuZWQnLCB7IHJlcyB9KVxyXG4gICAgICAgICAgcmV0dXJuIHJlc1xyXG4gICAgICAgIH1cclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIGxvZygndXBkYXRlciB0aHJldyBhbiBlcnJvcicsIGUpXHJcbiAgICAgICAgdGhyb3cgZVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSlcclxufVxyXG5cclxuLyoqXHJcbiAqIEl0ZXJhdGUgb3ZlciBhIGNhY2hlZCBvYmplY3QncyBmaWVsZHMgYW5kIGV2aWN0L2RlbGV0ZSB0aGUgb25lcyB0aGF0IHRoZSBwcmVkaWNhdGUgcmV0dXJucyB0cnVlIGZvclxyXG4gKiBOb3RlOiBUaGlzIHVzZXMgY2FjaGUubW9kaWZ5IHVuZGVybmVhdGggd2hpY2ggbWVhbnMgdGhhdCBgZGF0YWAgd2lsbCBvbmx5IGhvbGQgb2JqZWN0IHJlZmVyZW5jZXMgKENhY2hlT2JqZWN0UmVmZXJlbmNlKSBub3RcclxuICogZnVsbCBvYmplY3RzLiBSZWFkIG1vcmU6IGh0dHBzOi8vd3d3LmFwb2xsb2dyYXBocWwuY29tL2RvY3MvcmVhY3QvY2FjaGluZy9jYWNoZS1pbnRlcmFjdGlvbi8jdmFsdWVzLXZzLXJlZmVyZW5jZXNcclxuICogQGRlcHJlY2F0ZWQgVXNlIG1vZGlmeU9iamVjdEZpZWxkIGluc3RlYWQsIGp1c3QgcmV0dXJuIHRoZSBldmljdCgpIGNhbGwgZnJvbSB0aGUgdXBkYXRlclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGV2aWN0T2JqZWN0RmllbGRzPFxyXG4gIFYgZXh0ZW5kcyBPcHRpb25hbDxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4gPSB1bmRlZmluZWQsXHJcbiAgRCA9IHVua25vd25cclxuPihcclxuICBjYWNoZTogQXBvbGxvQ2FjaGU8dW5rbm93bj4sXHJcbiAgaWQ6IHN0cmluZyxcclxuICBwcmVkaWNhdGU6XHJcbiAgICB8ICgoXHJcbiAgICAgICAgZmllbGROYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgdmFyaWFibGVzOiBWLFxyXG4gICAgICAgIHZhbHVlOiBNb2RpZnlGbkNhY2hlRGF0YTxEPixcclxuICAgICAgICBkZXRhaWxzOiBQYXJhbWV0ZXJzPE1vZGlmaWVyPE1vZGlmeUZuQ2FjaGVEYXRhPEQ+Pj5bMV0gJiB7XHJcbiAgICAgICAgICByZXZvbHZlRmllbGROYW1lQW5kVmFyaWFibGVzOiB0eXBlb2YgcmV2b2x2ZUZpZWxkTmFtZUFuZFZhcmlhYmxlc1xyXG4gICAgICAgIH1cclxuICAgICAgKSA9PiBib29sZWFuKVxyXG4gICAgfCBzdHJpbmdbXVxyXG4pIHtcclxuICBtb2RpZnlPYmplY3RGaWVsZHM8ViwgRD4oXHJcbiAgICBjYWNoZSxcclxuICAgIGlkLFxyXG4gICAgKGZpZWxkTmFtZSwgdmFyaWFibGVzLCB2YWx1ZSwgZGV0YWlscykgPT4ge1xyXG4gICAgICBpZiAoaXNGdW5jdGlvbihwcmVkaWNhdGUpKSB7XHJcbiAgICAgICAgaWYgKFxyXG4gICAgICAgICAgIXByZWRpY2F0ZShmaWVsZE5hbWUsIHZhcmlhYmxlcywgdmFsdWUsIHtcclxuICAgICAgICAgICAgLi4uZGV0YWlscyxcclxuICAgICAgICAgICAgcmV2b2x2ZUZpZWxkTmFtZUFuZFZhcmlhYmxlc1xyXG4gICAgICAgICAgfSlcclxuICAgICAgICApXHJcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3QgcHJlZGljYXRlRmllbGRzID0gcHJlZGljYXRlXHJcbiAgICAgICAgaWYgKCFwcmVkaWNhdGVGaWVsZHMuaW5jbHVkZXMoZmllbGROYW1lKSkgcmV0dXJuIHVuZGVmaW5lZFxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBkZXRhaWxzLkRFTEVURSBhcyBNb2RpZnlGbkNhY2hlRGF0YTxEPlxyXG4gICAgfSxcclxuICAgIHsgZGVidWc6IGZhbHNlIH1cclxuICApXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCByZXNvbHZlR2VuZXJpY1N0YXR1c0NvZGUgPSAoXHJcbiAgZXJyb3JzOiByZWFkb25seSBHcmFwaFFMRXJyb3JbXSB8IHJlYWRvbmx5IEdyYXBoUUxGb3JtYXR0ZWRFcnJvcltdXHJcbikgPT4ge1xyXG4gIGlmIChlcnJvcnMuc29tZSgoZSkgPT4gZS5leHRlbnNpb25zPy5jb2RlID09PSAnRk9SQklEREVOJykpIHJldHVybiA0MDNcclxuICBpZiAoXHJcbiAgICBlcnJvcnMuc29tZSgoZSkgPT5cclxuICAgICAgWydVTkFVVEhFTlRJQ0FURUQnLCAnVU5BVVRIT1JJWkVEJywgJ1VOQVVUSE9SSVpFRF9BQ0NFU1NfRVJST1InXS5pbmNsdWRlcyhcclxuICAgICAgICAoZS5leHRlbnNpb25zPy5jb2RlIHx8ICcnKSBhcyBzdHJpbmdcclxuICAgICAgKVxyXG4gICAgKVxyXG4gIClcclxuICAgIHJldHVybiA0MDFcclxuICBpZiAoXHJcbiAgICBlcnJvcnMuc29tZSgoZSkgPT5cclxuICAgICAgWydOT1RfRk9VTkRfRVJST1InLCAnU1RSRUFNX05PVF9GT1VORCcsICdBVVRPTUFUSU9OX05PVF9GT1VORCddLmluY2x1ZGVzKFxyXG4gICAgICAgIChlLmV4dGVuc2lvbnM/LmNvZGUgfHwgJycpIGFzIHN0cmluZ1xyXG4gICAgICApXHJcbiAgICApXHJcbiAgKVxyXG4gICAgcmV0dXJuIDQwNFxyXG5cclxuICByZXR1cm4gNTAwXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBlcnJvckZhaWxlZEF0UGF0aFNlZ21lbnQgPSAoXHJcbiAgZXJyb3I6IEdyYXBoUUxFcnJvciB8IEdyYXBoUUxGb3JtYXR0ZWRFcnJvcixcclxuICBzZWdtZW50OiBzdHJpbmdcclxuKSA9PiB7XHJcbiAgY29uc3QgcGF0aCA9IGVycm9yLnBhdGggfHwgW11cclxuICByZXR1cm4gcGF0aFtwYXRoLmxlbmd0aCAtIDFdID09PSBzZWdtZW50XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBnZXREYXRlQ3Vyc29yRnJvbVJlZmVyZW5jZSA9IChwYXJhbXM6IHtcclxuICByZWY6IFJlZmVyZW5jZVxyXG4gIGRhdGVQcm9wOiBzdHJpbmdcclxuICByZWFkRmllbGQ6IChmaWVsZE5hbWU6IHN0cmluZywgcmVmOiBSZWZlcmVuY2UpID0+IHVua25vd25cclxufSk6IHN0cmluZyB8IG51bGwgPT4ge1xyXG4gIGNvbnN0IGRhdGVTdHIgPSBwYXJhbXMucmVhZEZpZWxkKHBhcmFtcy5kYXRlUHJvcCwgcGFyYW1zLnJlZikgYXMgc3RyaW5nXHJcbiAgaWYgKCFkYXRlU3RyIHx8ICFpc1N0cmluZyhkYXRlU3RyKSkgcmV0dXJuIG51bGxcclxuXHJcbiAgY29uc3QgZGF0ZSA9IGRheWpzKGRhdGVTdHIpXHJcbiAgaWYgKCFkYXRlLmlzVmFsaWQoKSkgcmV0dXJuIG51bGxcclxuXHJcbiAgY29uc3QgaXNvID0gZGF0ZS50b0lTT1N0cmluZygpXHJcbiAgcmV0dXJuIGJhc2U2NEVuY29kZShpc28pXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBCdWlsZCBza2lwTG9nZ2luZ0Vycm9ycyBmdW5jdGlvbiB0aGF0IHNraXBzIGxvZ2dpbmcgZXJyb3JzIGlmIHRoZXJlJ3Mgb25seSBvbmUgZXJyb3IgYW5kIGl0J3MgcmVsYXRlZCB0byBhIHNwZWNpZmljIGZpZWxkXHJcbiAqL1xyXG5leHBvcnQgY29uc3Qgc2tpcExvZ2dpbmdFcnJvcnNJZk9uZUZpZWxkRXJyb3IgPVxyXG4gIChmaWVsZE5hbWU6IHN0cmluZyB8IHN0cmluZ1tdKSA9PlxyXG4gIChlcnI6IEVycm9yUmVzcG9uc2UpOiBib29sZWFuID0+IHtcclxuICAgIGNvbnN0IGZpZWxkTmFtZXMgPSBpc0FycmF5KGZpZWxkTmFtZSkgPyBmaWVsZE5hbWUgOiBbZmllbGROYW1lXVxyXG4gICAgcmV0dXJuIChcclxuICAgICAgZXJyLmdyYXBoUUxFcnJvcnM/Lmxlbmd0aCA9PT0gMSAmJlxyXG4gICAgICBlcnIuZ3JhcGhRTEVycm9ycy5zb21lKChlKSA9PiBpbnRlcnNlY3Rpb24oZS5wYXRoIHx8IFtdLCBmaWVsZE5hbWVzKS5sZW5ndGggPiAwKVxyXG4gICAgKVxyXG4gIH1cclxuXHJcbnR5cGUgTm9uVW5kZWZpbmVkPFQ+ID0gVCBleHRlbmRzIHVuZGVmaW5lZCA/IG5ldmVyIDogVFxyXG5cclxuLyoqXHJcbiAqIFVwZGF0ZSBmaWVsZCBhdCBzcGVjaWZpYyBwYXRoIGluIG9iamVjdCwgb25seSBpZiBpdCBleGlzdHMuIFVzZWZ1bCBmb3IgY2FjaGUgbW9kaWZpY2F0aW9uXHJcbiAqIHdoZW4gZmllbGRzIHNob3VsZCBvbmx5IGJlIHVwZGF0ZWQgaWYgdGhleSBleGlzdC5cclxuICovXHJcbmV4cG9ydCBjb25zdCB1cGRhdGVQYXRoSWZFeGlzdHMgPSA8VmFsdWUsIFBhdGggZXh0ZW5kcyBQYXRoczxWYWx1ZT4gJiBzdHJpbmc+KFxyXG4gIHZhbDogVmFsdWUsXHJcbiAgcGF0aDogUGF0aCxcclxuICB1cGRhdGVyOiAodmFsOiBOb25VbmRlZmluZWQ8R2V0PFZhbHVlLCBQYXRoPj4pID0+IE5vblVuZGVmaW5lZDxHZXQ8VmFsdWUsIFBhdGg+PlxyXG4pID0+IHtcclxuICBpZiAoIXZhbCkgcmV0dXJuIHZhbFxyXG5cclxuICBpZiAoaGFzKHZhbCwgcGF0aCkpIHtcclxuICAgIGNvbnN0IHBhdGhWYWwgPSBnZXQodmFsLCBwYXRoKSBhcyBOb25VbmRlZmluZWQ8R2V0PFZhbHVlLCBQYXRoPj5cclxuICAgIGNvbnN0IG5ld1ZhbCA9IHVwZGF0ZXIocGF0aFZhbClcclxuICAgIHNldCh2YWwsIHBhdGgsIG5ld1ZhbClcclxuICB9XHJcblxyXG4gIHJldHVybiB2YWxcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB2YWx1ZSBmcm9tIHNwZWNpZmljIHBhdGggaW4gb2JqZWN0LCBvbmx5IGlmIGl0IGV4aXN0cy5cclxuICovXHJcbmV4cG9ydCBjb25zdCBnZXRGcm9tUGF0aElmRXhpc3RzID0gPFZhbHVlLCBQYXRoIGV4dGVuZHMgUGF0aHM8VmFsdWU+ICYgc3RyaW5nPihcclxuICB2YWw6IE1heWJlTnVsbE9yVW5kZWZpbmVkPFZhbHVlPixcclxuICBwYXRoOiBQYXRoXHJcbik6IE9wdGlvbmFsPEdldDxWYWx1ZSwgUGF0aD4+ID0+IHtcclxuICBpZiAoIXZhbCkgcmV0dXJuIHVuZGVmaW5lZFxyXG4gIGlmICghaGFzKHZhbCwgcGF0aCkpIHJldHVybiB1bmRlZmluZWRcclxuICByZXR1cm4gZ2V0KHZhbCwgcGF0aCkgYXMgR2V0PFZhbHVlLCBQYXRoPlxyXG59XHJcblxyXG50eXBlIE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8XHJcbiAgVHlwZSBleHRlbmRzIGtleW9mIEFsbE9iamVjdFR5cGVzLFxyXG4gIEZpZWxkIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXNbVHlwZV1cclxuPiA9IE1vZGlmeUZuQ2FjaGVEYXRhPEFsbE9iamVjdFR5cGVzW1R5cGVdW0ZpZWxkXT5cclxuXHJcbi8qKlxyXG4gKiBHZXQga2V5cyBvZiBhbGwgY2FjaGVkIG9iamVjdHMgYnkgdHlwZVxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGdldENhY2hlZE9iamVjdEtleXMgPSA8VHlwZSBleHRlbmRzIGtleW9mIEFsbE9iamVjdFR5cGVzPihcclxuICBjYWNoZTogQXBvbGxvQ2FjaGU8dW5rbm93bj4sXHJcbiAgdHlwZTogVHlwZVxyXG4pOiBBcG9sbG9DYWNoZU9iamVjdEtleTxUeXBlPltdID0+IHtcclxuICBjb25zdCBkYXRhID0gY2FjaGUuZXh0cmFjdCgpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+XHJcbiAgY29uc3Qgb2JqZWN0SWRzID0gT2JqZWN0LmtleXMoZGF0YSkuZmlsdGVyKChrKSA9PiBrLnN0YXJ0c1dpdGgoYCR7dHlwZX06YCkpXHJcbiAgcmV0dXJuIG9iamVjdElkcyBhcyBBcG9sbG9DYWNoZU9iamVjdEtleTxUeXBlPltdXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTaW1wbGlmaWVkICYgaW1wcm92ZWQgdmVyc2lvbiBvZiBtb2RpZnlPYmplY3RGaWVsZHMsIGp1c3QgdGFyZ2V0dGluZyBhIHNpbmdsZSBmaWVsZCBmb3IgYSBjYWNoZSBtb2RpZmljYXRpb25cclxuICogQHNlZSBtb2RpZnlPYmplY3RGaWVsZHNcclxuICovXHJcbmV4cG9ydCBjb25zdCBtb2RpZnlPYmplY3RGaWVsZCA9IDxcclxuICBUeXBlIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXMsXHJcbiAgRmllbGQgZXh0ZW5kcyBrZXlvZiBBbGxPYmplY3RUeXBlc1tUeXBlXVxyXG4+KFxyXG4gIGNhY2hlOiBBcG9sbG9DYWNoZTx1bmtub3duPixcclxuICBrZXk6IEFwb2xsb0NhY2hlT2JqZWN0S2V5PFR5cGU+LFxyXG4gIGZpZWxkTmFtZTogRmllbGQsXHJcbiAgdXBkYXRlcjogKHBhcmFtczoge1xyXG4gICAgZmllbGROYW1lOiBzdHJpbmdcclxuICAgIHZhcmlhYmxlczogRmllbGQgZXh0ZW5kcyBrZXlvZiBBbGxPYmplY3RGaWVsZEFyZ1R5cGVzW1R5cGVdXHJcbiAgICAgID8gQWxsT2JqZWN0RmllbGRBcmdUeXBlc1tUeXBlXVtGaWVsZF1cclxuICAgICAgOiBuZXZlclxyXG4gICAgLyoqXHJcbiAgICAgKiBWYWx1ZSBmb3VuZCBpbiB0aGUgY2FjaGUuIFJlYWQtb25seSBhbmQgc2hvdWxkIG5vdCBiZSBtdXRhdGVkIGRpcmVjdGx5LiBVc2UgdGhlXHJcbiAgICAgKiBjcmVhdGVVcGRhdGVkVmFsdWUoKSBoZWxwZXIgdG8gYnVpbGQgYSBuZXcgdmFsdWUgd2l0aCB1cGRhdGVkIGZpZWxkcy5cclxuICAgICAqL1xyXG4gICAgdmFsdWU6IFJlYWRvbmx5RGVlcDxNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPj5cclxuICAgIGhlbHBlcnM6IHtcclxuICAgICAgLyoqXHJcbiAgICAgICAqIEJ1aWxkIG5ldyB2YWx1ZSB3aXRoIHRoZSB2YWx1ZXMgYXQgc3BlY2lmaWMgcGF0aHMgdXBkYXRlZCB3aXRoIHRoZSBwcm92aWRlZCB1cGRhdGVyIGZ1bmN0aW9ucyxcclxuICAgICAgICogT05MWSBpZiB0aGUgcGF0aHMgZXhpc3QgaW4gdGhlIGNhY2hlLlxyXG4gICAgICAgKlxyXG4gICAgICAgKiBUaGlzIGZ1bmN0aW9uIG9wZXJhdGVzIG9uIGEgZGVlcGx5IGNsb25lZCB2YWx1ZSB0aGF0IGlzIHNhZmUgdG8gbXV0YXRlXHJcbiAgICAgICAqL1xyXG4gICAgICBjcmVhdGVVcGRhdGVkVmFsdWU6IChcclxuICAgICAgICB1cGRhdGVIYW5kbGVyOiAocGFyYW1zOiB7XHJcbiAgICAgICAgICAvKipcclxuICAgICAgICAgICAqIEludm9rZSB0aGlzIGZ1bmN0aW9uIHRvIHVwZGF0ZSBvbmUgc3BlY2lmaWMgcGF0aCBpbiB0aGUgb2JqZWN0XHJcbiAgICAgICAgICAgKi9cclxuICAgICAgICAgIHVwZGF0ZTogPFBhdGggZXh0ZW5kcyBQYXRoczxNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPj4gJiBzdHJpbmc+KFxyXG4gICAgICAgICAgICBwYXRoOiBQYXRoLFxyXG4gICAgICAgICAgICBwYXRoVXBkYXRlOiAoXHJcbiAgICAgICAgICAgICAgdmFsOiBOb25VbmRlZmluZWQ8R2V0PE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8VHlwZSwgRmllbGQ+LCBQYXRoPj5cclxuICAgICAgICAgICAgKSA9PiBOb25VbmRlZmluZWQ8R2V0PE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8VHlwZSwgRmllbGQ+LCBQYXRoPj5cclxuICAgICAgICAgICkgPT4gTWF5YmVOdWxsT3JVbmRlZmluZWQ8TW9kaWZ5T2JqZWN0RmllbGRWYWx1ZTxUeXBlLCBGaWVsZD4+XHJcbiAgICAgICAgfSkgPT4gdm9pZFxyXG4gICAgICApID0+IE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8VHlwZSwgRmllbGQ+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBHZXQgdmFsdWUgZnJvbSBzcGVjaWZpYyBwYXRoLCBvbmx5IGlmIGl0IGV4aXN0cyBpbiB0aGUgY2FjaGUgdmFsdWVcclxuICAgICAgICovXHJcbiAgICAgIGdldDogPFBhdGggZXh0ZW5kcyBQYXRoczxNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPj4gJiBzdHJpbmc+KFxyXG4gICAgICAgIHBhdGg6IFBhdGhcclxuICAgICAgKSA9PiBPcHRpb25hbDxHZXQ8TW9kaWZ5T2JqZWN0RmllbGRWYWx1ZTxUeXBlLCBGaWVsZD4sIFBhdGg+PlxyXG4gICAgICAvKipcclxuICAgICAgICogSW52b2tlIGFuZCByZXR1cm4gdGhpcyBvdXQgZnJvbSB0aGUgbW9kaWZ5IGNhbGwgdG8gZXZpY3QgdGhlIGZpZWxkIGZyb20gdGhlIGNhY2hlXHJcbiAgICAgICAqL1xyXG4gICAgICBldmljdDogKCkgPT4gTW9kaWZpZXJEZXRhaWxzWydERUxFVEUnXVxyXG4gICAgICAvKipcclxuICAgICAgICogUmVhZCBmaWVsZCBkYXRhIGZyb20gYSBSZWZlcmVuY2Ugb2JqZWN0XHJcbiAgICAgICAqL1xyXG4gICAgICByZWFkRmllbGQ6IDxcclxuICAgICAgICBSZWFkRmllbGRUeXBlIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXMsXHJcbiAgICAgICAgUmVhZEZpZWxkTmFtZSBleHRlbmRzIGtleW9mIEFsbE9iamVjdFR5cGVzW1JlYWRGaWVsZFR5cGVdICYgc3RyaW5nXHJcbiAgICAgID4oXHJcbiAgICAgICAgcmVmOiBDYWNoZU9iamVjdFJlZmVyZW5jZTxSZWFkRmllbGRUeXBlPixcclxuICAgICAgICBmaWVsZE5hbWU6IFJlYWRGaWVsZE5hbWVcclxuICAgICAgKSA9PiBPcHRpb25hbDxNb2RpZnlGbkNhY2hlRGF0YTxBbGxPYmplY3RUeXBlc1tSZWFkRmllbGRUeXBlXVtSZWFkRmllbGROYW1lXT4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBHZXQgdGhlIG9iamVjdCB3ZSdyZSBtb2RpZnlpbmcgYXMgYSByZWFkYWJsZSBvYmplY3RcclxuICAgICAgICovXHJcbiAgICAgIHJlYWRPYmplY3Q6ICgpID0+IFBhcnRpYWw8e1xyXG4gICAgICAgIFtwcm9wIGluIGtleW9mIEFsbE9iamVjdFR5cGVzW1R5cGVdXTogTW9kaWZ5Rm5DYWNoZURhdGE8XHJcbiAgICAgICAgICBBbGxPYmplY3RUeXBlc1tUeXBlXVtwcm9wXVxyXG4gICAgICAgID5cclxuICAgICAgfT5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIEJ1aWxkIGEgcmVmZXJlbmNlIG9iamVjdCBmb3IgYSBzcGVjaWZpYyBvYmplY3QgaW4gdGhlIGNhY2hlXHJcbiAgICAgICAqL1xyXG4gICAgICByZWY6IHR5cGVvZiBnZXRPYmplY3RSZWZlcmVuY2VcclxuICAgICAgLyoqXHJcbiAgICAgICAqIEJ1aWxkIGEgcmVmZXJlbmNlIG9iamVjdCBmcm9tIGEga2V5XHJcbiAgICAgICAqL1xyXG4gICAgICBrZXlUb1JlZjogdHlwZW9mIGtleVRvUmVmXHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBQYXJzZSBhIHJlZmVyZW5jZSBvYmplY3QgdG8gZ2V0IGl0cyB0eXBlIGFuZCBpZCBzZXBhcmF0ZWx5XHJcbiAgICAgICAqL1xyXG4gICAgICBmcm9tUmVmOiB0eXBlb2YgcGFyc2VPYmplY3RSZWZlcmVuY2VcclxuICAgIH1cclxuICB9KSA9PlxyXG4gICAgfCBPcHRpb25hbDxNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPj5cclxuICAgIHwgUmVhZG9ubHlEZWVwPE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8VHlwZSwgRmllbGQ+PlxyXG4gICAgfCBNb2RpZmllckRldGFpbHNbJ0RFTEVURSddXHJcbiAgICB8IE1vZGlmaWVyRGV0YWlsc1snSU5WQUxJREFURSddXHJcbiAgICB8IHZvaWQsXHJcbiAgb3B0aW9ucz86IFBhcnRpYWw8e1xyXG4gICAgZGVidWc6IGJvb2xlYW5cclxuICAgIC8qKlxyXG4gICAgICogV2hldGhlciB0byBhdXRvIGV2aWN0IHZhbHVlcyB0aGF0IGhhdmUgdmFyaWFibGVzIHdpdGggY29tbW9uIGZpbHRlcnMgaW4gdGhlbSAoZS5nLiBhICdmaWx0ZXInIG9yXHJcbiAgICAgKiAnc2VhcmNoJyBwcm9wKS4gT2Z0ZW4gaXRzIGJldHRlciB0byBldmljdCBmaWx0ZXJlZCB2YWx1ZXMsIGJlY2F1c2Ugd2UgY2FuJ3QgdGVsbCBpZiB0aGUgbmV3bHlcclxuICAgICAqIGFkZGVkIGl0ZW0gc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZSBmaWx0ZXJlZCBsaXN0IG9yIG5vdC5cclxuICAgICAqXHJcbiAgICAgKiBJZiBzdHJpbmcgYXJyYXkgcGFzc2VkIGluLCB0aGVzZSBleHRyYSBmaWx0ZXIga2V5cyB3aWxsIGJlIGNoZWNrZWQgdG8gc2VlIGlmIHdlIG5lZWQgdG8gZXZpY3RcclxuICAgICAqL1xyXG4gICAgYXV0b0V2aWN0RmlsdGVyZWQ6IGJvb2xlYW4gfCBzdHJpbmdbXVxyXG4gIH0+XHJcbikgPT4ge1xyXG4gIGNvbnN0IHsgYXV0b0V2aWN0RmlsdGVyZWQgfSA9IG9wdGlvbnMgfHwge31cclxuXHJcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcclxuICBtb2RpZnlPYmplY3RGaWVsZHM8YW55LCBhbnk+KFxyXG4gICAgY2FjaGUsXHJcbiAgICBrZXksXHJcbiAgICAoZmllbGQsIHZhcmlhYmxlcywgdmFsdWUsIGRldGFpbHMpID0+IHtcclxuICAgICAgaWYgKGZpZWxkICE9PSBmaWVsZE5hbWUpIHJldHVyblxyXG5cclxuICAgICAgLy8gQXV0byBldmljdCBmaWx0ZXJlZCB2YWx1ZXM/XHJcbiAgICAgIGlmIChhdXRvRXZpY3RGaWx0ZXJlZCAmJiBpc09iamVjdExpa2UodmFyaWFibGVzKSkge1xyXG4gICAgICAgIGNvbnN0IGNoZWNrRmlsdGVyID0gKGZpbHRlcjogc3RyaW5nKSA9PiB7XHJcbiAgICAgICAgICBpZiAoIWhhcyh2YXJpYWJsZXMsIGZpbHRlcikpIHJldHVybiBmYWxzZVxyXG4gICAgICAgICAgY29uc3QgdmFsID0gZ2V0KHZhcmlhYmxlcywgZmlsdGVyKVxyXG5cclxuICAgICAgICAgIC8vIFRydWUsIGlmIGFueSBwcmltaXRpdmUgdmFsdWUgKGUuZy4gc3RyaW5nLCBudW1iZXIpICYmIGFycmF5c1xyXG4gICAgICAgICAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbCkpIHJldHVybiBmYWxzZVxyXG4gICAgICAgICAgaWYgKGlzQXJyYXkodmFsKSkgcmV0dXJuIHRydWVcclxuICAgICAgICAgIGlmICghaXNPYmplY3RMaWtlKHZhbCkpIHJldHVybiB0cnVlXHJcbiAgICAgICAgICByZXR1cm4gZmFsc2VcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGNvbW1vbkZpbHRlcnMgPSBbXHJcbiAgICAgICAgICAncXVlcnknLFxyXG4gICAgICAgICAgJ2ZpbHRlcicsXHJcbiAgICAgICAgICAnc2VhcmNoJyxcclxuICAgICAgICAgICdmaWx0ZXIuc2VhcmNoJyxcclxuICAgICAgICAgICdpbnB1dC5zZWFyY2gnLFxyXG4gICAgICAgICAgLi4uKGlzQXJyYXkoYXV0b0V2aWN0RmlsdGVyZWQpID8gYXV0b0V2aWN0RmlsdGVyZWQgOiBbXSlcclxuICAgICAgICBdXHJcbiAgICAgICAgY29uc3QgaGFzRmlsdGVyID0gY29tbW9uRmlsdGVycy5zb21lKGNoZWNrRmlsdGVyKVxyXG5cclxuICAgICAgICBpZiAoaGFzRmlsdGVyKSB7XHJcbiAgICAgICAgICByZXR1cm4gZGV0YWlscy5ERUxFVEVcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIEJ1aWxkIGhlbHBlcnMgJiBjbG9uZSB2YWx1ZSB0byBhbGxvdyBmb3IgZGlyZWN0IG11dGF0aW9uXHJcbiAgICAgIGNvbnN0IGNyZWF0ZVVwZGF0ZWRWYWx1ZSA9IChcclxuICAgICAgICB1cGRhdGVIYW5kbGVyOiAocGFyYW1zOiB7XHJcbiAgICAgICAgICB1cGRhdGU6IDxQYXRoIGV4dGVuZHMgUGF0aHM8TW9kaWZ5T2JqZWN0RmllbGRWYWx1ZTxUeXBlLCBGaWVsZD4+ICYgc3RyaW5nPihcclxuICAgICAgICAgICAgcGF0aDogUGF0aCxcclxuICAgICAgICAgICAgcGF0aFVwZGF0ZTogKFxyXG4gICAgICAgICAgICAgIHZhbDogTm9uVW5kZWZpbmVkPEdldDxNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPiwgUGF0aD4+XHJcbiAgICAgICAgICAgICkgPT4gTm9uVW5kZWZpbmVkPEdldDxNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPiwgUGF0aD4+XHJcbiAgICAgICAgICApID0+IE1heWJlTnVsbE9yVW5kZWZpbmVkPE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8VHlwZSwgRmllbGQ+PlxyXG4gICAgICAgIH0pID0+IHZvaWRcclxuICAgICAgKSA9PiB7XHJcbiAgICAgICAgbGV0IGNsb25lZFZhbHVlID0gY2xvbmVEZWVwKHZhbHVlKSBhcyBNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPlxyXG4gICAgICAgIHVwZGF0ZUhhbmRsZXIoe1xyXG4gICAgICAgICAgdXBkYXRlOiAocGF0aCwgcGF0aFVwZGF0ZSkgPT4ge1xyXG4gICAgICAgICAgICBjbG9uZWRWYWx1ZSA9IHVwZGF0ZVBhdGhJZkV4aXN0cyhjbG9uZWRWYWx1ZSwgcGF0aCwgcGF0aFVwZGF0ZSlcclxuICAgICAgICAgICAgcmV0dXJuIGNsb25lZFZhbHVlXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgICByZXR1cm4gY2xvbmVkVmFsdWVcclxuICAgICAgfVxyXG5cclxuICAgICAgY29uc3QgZ2V0SWZFeGlzdHMgPSA8XHJcbiAgICAgICAgUGF0aCBleHRlbmRzIFBhdGhzPE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8VHlwZSwgRmllbGQ+PiAmIHN0cmluZ1xyXG4gICAgICA+KFxyXG4gICAgICAgIHBhdGg6IFBhdGhcclxuICAgICAgKSA9PiBnZXRGcm9tUGF0aElmRXhpc3RzPE1vZGlmeU9iamVjdEZpZWxkVmFsdWU8VHlwZSwgRmllbGQ+LCBQYXRoPih2YWx1ZSwgcGF0aClcclxuICAgICAgY29uc3QgZXZpY3QgPSAoKSA9PiBkZXRhaWxzLkRFTEVURVxyXG5cclxuICAgICAgY29uc3QgcmVhZEZpZWxkID0gPFxyXG4gICAgICAgIFJlYWRGaWVsZFR5cGUgZXh0ZW5kcyBrZXlvZiBBbGxPYmplY3RUeXBlcyxcclxuICAgICAgICBSZWFkRmllbGROYW1lIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXNbUmVhZEZpZWxkVHlwZV0gJiBzdHJpbmdcclxuICAgICAgPihcclxuICAgICAgICByZWY6IENhY2hlT2JqZWN0UmVmZXJlbmNlPFJlYWRGaWVsZFR5cGU+LFxyXG4gICAgICAgIGZpZWxkTmFtZTogUmVhZEZpZWxkTmFtZVxyXG4gICAgICApID0+XHJcbiAgICAgICAgZGV0YWlscy5yZWFkRmllbGQoZmllbGROYW1lLCByZWYpIGFzIE9wdGlvbmFsPFxyXG4gICAgICAgICAgTW9kaWZ5Rm5DYWNoZURhdGE8QWxsT2JqZWN0VHlwZXNbUmVhZEZpZWxkVHlwZV1bUmVhZEZpZWxkTmFtZV0+XHJcbiAgICAgICAgPlxyXG5cclxuICAgICAgY29uc3QgcmVhZE9iamVjdCA9ICgpID0+XHJcbiAgICAgICAgbmV3IFByb3h5KFxyXG4gICAgICAgICAge30gYXMgUGFydGlhbDx7XHJcbiAgICAgICAgICAgIFtwcm9wIGluIGtleW9mIEFsbE9iamVjdFR5cGVzW1R5cGVdXTogTW9kaWZ5Rm5DYWNoZURhdGE8XHJcbiAgICAgICAgICAgICAgQWxsT2JqZWN0VHlwZXNbVHlwZV1bcHJvcF1cclxuICAgICAgICAgICAgPlxyXG4gICAgICAgICAgfT4sXHJcbiAgICAgICAgICB7XHJcbiAgICAgICAgICAgIGdldChfdGFyZ2V0LCBwcm9wKSB7XHJcbiAgICAgICAgICAgICAgaWYgKCFpc1N0cmluZyhwcm9wKSkgcmV0dXJuIHVuZGVmaW5lZFxyXG5cclxuICAgICAgICAgICAgICBjb25zdCByZWYgPSBrZXlUb1JlZihrZXkpXHJcbiAgICAgICAgICAgICAgcmV0dXJuIGRldGFpbHMucmVhZEZpZWxkKHByb3AsIHJlZilcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIClcclxuXHJcbiAgICAgIHJldHVybiB1cGRhdGVyKHtcclxuICAgICAgICBmaWVsZE5hbWU6IGZpZWxkLFxyXG4gICAgICAgIHZhcmlhYmxlcyxcclxuICAgICAgICB2YWx1ZSxcclxuICAgICAgICBoZWxwZXJzOiB7XHJcbiAgICAgICAgICBjcmVhdGVVcGRhdGVkVmFsdWUsXHJcbiAgICAgICAgICBnZXQ6IGdldElmRXhpc3RzLFxyXG4gICAgICAgICAgZXZpY3QsXHJcbiAgICAgICAgICByZWFkRmllbGQsXHJcbiAgICAgICAgICByZWY6IGdldE9iamVjdFJlZmVyZW5jZSxcclxuICAgICAgICAgIGZyb21SZWY6IHBhcnNlT2JqZWN0UmVmZXJlbmNlLFxyXG4gICAgICAgICAga2V5VG9SZWYsXHJcbiAgICAgICAgICByZWFkT2JqZWN0XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG4gICAgfSxcclxuICAgIG9wdGlvbnNcclxuICApXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJdGVyYXRlIG92ZXIgb2JqZWN0IGZpZWxkIHZlcnNpb25zIChzYW1lIGZpZWxkIGNhbiBoYXZlIGRpZmZlcmVudCBhcmcgdmVyc2lvbnMpLiBJZiB5b3UgYWxzb1xyXG4gKiB3YW50IHRvIG1ha2UgdXBkYXRlcywgdXNlIG1vZGlmeU9iamVjdEZpZWxkIGluc3RlYWQuXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgaXRlcmF0ZU9iamVjdEZpZWxkID0gPFxyXG4gIFR5cGUgZXh0ZW5kcyBrZXlvZiBBbGxPYmplY3RUeXBlcyxcclxuICBGaWVsZCBleHRlbmRzIGtleW9mIEFsbE9iamVjdFR5cGVzW1R5cGVdXHJcbj4oXHJcbiAgY2FjaGU6IEFwb2xsb0NhY2hlPHVua25vd24+LFxyXG4gIGtleTogQXBvbGxvQ2FjaGVPYmplY3RLZXk8VHlwZT4sXHJcbiAgZmllbGROYW1lOiBGaWVsZCxcclxuICBwcmVkaWNhdGU6IChwYXJhbXM6IHtcclxuICAgIGZpZWxkTmFtZTogc3RyaW5nXHJcbiAgICB2YXJpYWJsZXM6IEZpZWxkIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0RmllbGRBcmdUeXBlc1tUeXBlXVxyXG4gICAgICA/IEFsbE9iamVjdEZpZWxkQXJnVHlwZXNbVHlwZV1bRmllbGRdXHJcbiAgICAgIDogbmV2ZXJcclxuICAgIC8qKlxyXG4gICAgICogVmFsdWUgZm91bmQgaW4gdGhlIGNhY2hlLiBSZWFkLW9ubHkgYW5kIHNob3VsZCBub3QgYmUgbXV0YXRlZCBkaXJlY3RseS4gVXNlIHRoZVxyXG4gICAgICogY3JlYXRlVXBkYXRlZFZhbHVlKCkgaGVscGVyIHRvIGJ1aWxkIGEgbmV3IHZhbHVlIHdpdGggdXBkYXRlZCBmaWVsZHMuXHJcbiAgICAgKi9cclxuICAgIHZhbHVlOiBSZWFkb25seURlZXA8TW9kaWZ5T2JqZWN0RmllbGRWYWx1ZTxUeXBlLCBGaWVsZD4+XHJcbiAgICBoZWxwZXJzOiB7XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBHZXQgdmFsdWUgZnJvbSBzcGVjaWZpYyBwYXRoLCBvbmx5IGlmIGl0IGV4aXN0cyBpbiB0aGUgY2FjaGUgdmFsdWVcclxuICAgICAgICovXHJcbiAgICAgIGdldDogPFBhdGggZXh0ZW5kcyBQYXRoczxNb2RpZnlPYmplY3RGaWVsZFZhbHVlPFR5cGUsIEZpZWxkPj4gJiBzdHJpbmc+KFxyXG4gICAgICAgIHBhdGg6IFBhdGhcclxuICAgICAgKSA9PiBPcHRpb25hbDxHZXQ8TW9kaWZ5T2JqZWN0RmllbGRWYWx1ZTxUeXBlLCBGaWVsZD4sIFBhdGg+PlxyXG4gICAgICAvKipcclxuICAgICAgICogUmVhZCBmaWVsZCBkYXRhIGZyb20gYSBSZWZlcmVuY2Ugb2JqZWN0XHJcbiAgICAgICAqL1xyXG4gICAgICByZWFkRmllbGQ6IDxcclxuICAgICAgICBSZWFkRmllbGRUeXBlIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXMsXHJcbiAgICAgICAgUmVhZEZpZWxkTmFtZSBleHRlbmRzIGtleW9mIEFsbE9iamVjdFR5cGVzW1JlYWRGaWVsZFR5cGVdICYgc3RyaW5nXHJcbiAgICAgID4oXHJcbiAgICAgICAgcmVmOiBDYWNoZU9iamVjdFJlZmVyZW5jZTxSZWFkRmllbGRUeXBlPixcclxuICAgICAgICBmaWVsZE5hbWU6IFJlYWRGaWVsZE5hbWVcclxuICAgICAgKSA9PiBPcHRpb25hbDxNb2RpZnlGbkNhY2hlRGF0YTxBbGxPYmplY3RUeXBlc1tSZWFkRmllbGRUeXBlXVtSZWFkRmllbGROYW1lXT4+XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBHZXQgdGhlIG9iamVjdCB3ZSdyZSBtb2RpZnlpbmcgYXMgYSByZWFkYWJsZSBvYmplY3RcclxuICAgICAgICovXHJcbiAgICAgIHJlYWRPYmplY3Q6ICgpID0+IFBhcnRpYWw8e1xyXG4gICAgICAgIFtwcm9wIGluIGtleW9mIEFsbE9iamVjdFR5cGVzW1R5cGVdXTogTW9kaWZ5Rm5DYWNoZURhdGE8XHJcbiAgICAgICAgICBBbGxPYmplY3RUeXBlc1tUeXBlXVtwcm9wXVxyXG4gICAgICAgID5cclxuICAgICAgfT5cclxuICAgICAgLyoqXHJcbiAgICAgICAqIEJ1aWxkIGEgcmVmZXJlbmNlIG9iamVjdCBmb3IgYSBzcGVjaWZpYyBvYmplY3QgaW4gdGhlIGNhY2hlXHJcbiAgICAgICAqL1xyXG4gICAgICByZWY6IHR5cGVvZiBnZXRPYmplY3RSZWZlcmVuY2VcclxuICAgICAgLyoqXHJcbiAgICAgICAqIFBhcnNlIGEgcmVmZXJlbmNlIG9iamVjdCB0byBnZXQgaXRzIHR5cGUgYW5kIGlkIHNlcGFyYXRlbHlcclxuICAgICAgICovXHJcbiAgICAgIGZyb21SZWY6IHR5cGVvZiBwYXJzZU9iamVjdFJlZmVyZW5jZVxyXG4gICAgfVxyXG4gIH0pID0+IHZvaWQsXHJcbiAgb3B0aW9ucz86IFBhcnRpYWw8e1xyXG4gICAgZGVidWc6IGJvb2xlYW5cclxuICB9PlxyXG4pID0+IHtcclxuICBtb2RpZnlPYmplY3RGaWVsZDxUeXBlLCBGaWVsZD4oXHJcbiAgICBjYWNoZSxcclxuICAgIGtleSxcclxuICAgIGZpZWxkTmFtZSxcclxuICAgIChwYXJhbXMpID0+IHtcclxuICAgICAgcHJlZGljYXRlKHBhcmFtcylcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIC4uLihvcHRpb25zIHx8IHt9KSxcclxuICAgICAgYXV0b0V2aWN0RmlsdGVyZWQ6IGZhbHNlIC8vIG5vIG11dGF0aW9ucyBoZXJlXHJcbiAgICB9XHJcbiAgKVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgaGFzRXJyb3JXaXRoID0gKHBhcmFtczoge1xyXG4gIGVycm9yczogcmVhZG9ubHkgR3JhcGhRTEZvcm1hdHRlZEVycm9yW10gfCB1bmRlZmluZWRcclxuICBjb2Rlcz86IEFycmF5PHN0cmluZyB8IFJlZ0V4cD5cclxuICBtZXNzYWdlPzogc3RyaW5nXHJcbn0pID0+IHtcclxuICBjb25zdCB7IGVycm9ycywgbWVzc2FnZSwgY29kZXMgfSA9IHBhcmFtc1xyXG4gIGlmICghZXJyb3JzPy5sZW5ndGgpIHJldHVybiB1bmRlZmluZWRcclxuICBpZiAoIW1lc3NhZ2U/Lmxlbmd0aCAmJiAhY29kZXM/Lmxlbmd0aCkgcmV0dXJuIHVuZGVmaW5lZFxyXG5cclxuICByZXR1cm4gZXJyb3JzLmZpbmQoKGUpID0+IHtcclxuICAgIGNvbnN0IGhhc01lc3NhZ2UgPSBtZXNzYWdlICYmIGUubWVzc2FnZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKG1lc3NhZ2UpXHJcbiAgICBjb25zdCBoYXNDb2RlcyA9XHJcbiAgICAgIGNvZGVzICYmXHJcbiAgICAgIGNvZGVzLnNvbWUoKHRlc3RDb2RlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgY29kZSA9IGUuZXh0ZW5zaW9ucz8uY29kZVxyXG4gICAgICAgIGlmICghY29kZSB8fCAhaXNTdHJpbmcoY29kZSkpIHJldHVybiBmYWxzZVxyXG4gICAgICAgIHJldHVybiBpc1N0cmluZyh0ZXN0Q29kZSkgPyBjb2RlID09PSB0ZXN0Q29kZSA6IGNvZGUubWF0Y2godGVzdENvZGUpXHJcbiAgICAgIH0pXHJcbiAgICByZXR1cm4gaGFzTWVzc2FnZSB8fCBoYXNDb2Rlc1xyXG4gIH0pXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBlcnJvcnNUb0F1dGhSZXN1bHQgPSAocGFyYW1zOiB7XHJcbiAgZXJyb3JzOiByZWFkb25seSBHcmFwaFFMRm9ybWF0dGVkRXJyb3JbXSB8IHVuZGVmaW5lZFxyXG59KTogUGVybWlzc2lvbkNoZWNrUmVzdWx0ID0+IHtcclxuICBjb25zdCB7IGVycm9ycyB9ID0gcGFyYW1zXHJcbiAgaWYgKCFlcnJvcnM/Lmxlbmd0aCkgcmV0dXJuIHsgYXV0aG9yaXplZDogdHJ1ZSwgbWVzc2FnZTogJ09LJywgY29kZTogJ09LJyB9XHJcblxyXG4gIC8vIFByaW9yaXRpemUgY29tbW9uIGVycm9yIGNvZGVzXHJcbiAgY29uc3QgY29tbW9uQXV0aEVycm9yID0gaGFzRXJyb3JXaXRoKHtcclxuICAgIGVycm9ycyxcclxuICAgIGNvZGVzOiBbXHJcbiAgICAgIC9mb3JiaWRkZW4vaSxcclxuICAgICAgL3VuYXV0aG9yaXplZC9pLFxyXG4gICAgICAvbm90W19cXHNdZm91bmQvaSxcclxuICAgICAgL25vdFtfXFxzXWF1dGhvcml6ZWQvaSxcclxuICAgICAgJ1NTT19TRVNTSU9OX01JU1NJTkdfT1JfRVhQSVJFRF9FUlJPUidcclxuICAgIF1cclxuICB9KVxyXG4gIGlmIChjb21tb25BdXRoRXJyb3IpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIGF1dGhvcml6ZWQ6IGZhbHNlLFxyXG4gICAgICBjb2RlOiBjb21tb25BdXRoRXJyb3IuZXh0ZW5zaW9ucyEuY29kZSBhcyBzdHJpbmcsXHJcbiAgICAgIG1lc3NhZ2U6IGNvbW1vbkF1dGhFcnJvci5tZXNzYWdlLFxyXG4gICAgICBwYXlsb2FkOiBjb21tb25BdXRoRXJyb3IuZXh0ZW5zaW9ucyB8fCBudWxsXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb25zdCBmaXJzdEVycm9yID0gZXJyb3JzWzBdXHJcbiAgcmV0dXJuIHtcclxuICAgIGF1dGhvcml6ZWQ6IGZhbHNlLFxyXG4gICAgY29kZTpcclxuICAgICAgZmlyc3RFcnJvci5leHRlbnNpb25zPy5jb2RlICYmIGlzU3RyaW5nKGZpcnN0RXJyb3IuZXh0ZW5zaW9ucz8uY29kZSlcclxuICAgICAgICA/IGZpcnN0RXJyb3IuZXh0ZW5zaW9ucz8uY29kZVxyXG4gICAgICAgIDogJ1VOS05PV05fRVJST1InLFxyXG4gICAgbWVzc2FnZTogZmlyc3RFcnJvci5tZXNzYWdlLFxyXG4gICAgcGF5bG9hZDogZmlyc3RFcnJvci5leHRlbnNpb25zIHx8IG51bGxcclxuICB9XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBwYXJzZU9iamVjdEtleSA9IDxUeXBlIGV4dGVuZHMga2V5b2YgQWxsT2JqZWN0VHlwZXM+KFxyXG4gIGtleTogQXBvbGxvQ2FjaGVPYmplY3RLZXk8VHlwZT5cclxuKTogeyB0eXBlOiBUeXBlOyBpZDogc3RyaW5nIH0gPT4ge1xyXG4gIGNvbnN0IFt0eXBlLCBpZF0gPSBrZXkuc3BsaXQoJzonKVxyXG4gIHJldHVybiB7IHR5cGU6IHR5cGUgYXMgVHlwZSwgaWQgfVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgcGFyc2VPYmplY3RSZWZlcmVuY2UgPSA8VHlwZSBleHRlbmRzIGtleW9mIEFsbE9iamVjdFR5cGVzPihcclxuICByZWY6IENhY2hlT2JqZWN0UmVmZXJlbmNlPFR5cGU+XHJcbik6IHsgdHlwZTogVHlwZTsgaWQ6IHN0cmluZyB9ID0+IHtcclxuICByZXR1cm4gcGFyc2VPYmplY3RLZXkocmVmLl9fcmVmIGFzIEFwb2xsb0NhY2hlT2JqZWN0S2V5PFR5cGU+KVxyXG59XHJcbiJdLCJmaWxlIjoiRDovc3BlY2tsZS1zZXJ2ZXIvcGFja2FnZXMvZnJvbnRlbmQtMi9saWIvY29tbW9uL2hlbHBlcnMvZ3JhcGhxbC50cyJ9